【问题标题】:Safari iPad 1: how to disable zoom/centering on double-tap, but keep pinch zoomSafari iPad 1:如何在双击时禁用缩放/居中,但保持捏缩放
【发布时间】:2011-12-25 16:13:03
【问题描述】:

我想知道是否可以防止在 Safari iOS (iPad 1) 中的特定 HTML 元素上双击缩放和双击居中?

因为我的小型 HTML5 游戏会强制用户进行快速点击(或轻击),这会被解释为双击,当这种情况发生时 - 页面会自动改变缩放并居中。

检测双击(就像在这个答案中 - Safari iPad : prevent zoom on double-tap)闻起来很糟糕......

错误答案#1: <meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"> - 不适合我的目的,因为它会阻止任何缩放。

错误答案 #2: 可能仅在点击事件中 .preventDefault() 就足够了? - 没有任何效果。

【问题讨论】:

标签: javascript ipad touch mobile-safari zooming


【解决方案1】:

我正在防止这样的双击:

var doubleTouchStartTimestamp = 0;
$(document).bind("touchstart", function (event) {
    var now = +(new Date());
    if (doubleTouchStartTimestamp + 500 > now) {
        event.preventDefault();
    }
    doubleTouchStartTimestamp = now;
});

优雅在于不需要超时。我只更新一个时间戳。它只会在下一次 touchstart 时进行比较。在 iOS 6 上为我工作。

dom 后面的双击不受影响。

没有 jQuery 也一样:

var doubleTouchStartTimestamp = 0;
document.addEventListener("touchstart", function (event) {
    var now = +(new Date());
    if (doubleTouchStartTimestamp + 500 > now) {
        event.preventDefault();
    }
    doubleTouchStartTimestamp = now;
});

【讨论】:

    【解决方案2】:

    在 MVC4 中禁用双击缩放的 JQuery 方法 要在 iOS 1+ 上禁用双击(双击鼠标)功能,您需要捕获 touchStart 事件并创建覆盖以防止缩放。

    // 使用单个 script.js 和 JQuery.Mobile-1.2.0 UI MVC 中的每个页面都通过委托分配 JQuery,因此您不必完全刷新页面,从而可以利用数据-prefetch 在应用第一次加载时在 DOM 中加载页面

    $(document).delegate("#CashRegister", "pageinit", function () {

    // To Disable 'Pinch to Zoom' Note: don't implement gester event handlers if you want to 
    //keep pinch to zoom functionality NOTE: i use this as my pageinit is a delegate of a page
    this.addEventListener("gesturestart", gestureStart, false);
    this.addEventListener("gesturechange", gestureChange, false);
    this.addEventListener("gestureend", gestureEnd, false);
    //handle each event by disabling the defaults
    function gestureStart(event) {
        event.preventDefault();
    }
    
    function gestureChange(event) {
        event.preventDefault();
    }
    
    function gestureEnd(event) {
        event.preventDefault();
    }
    //Recreate Double Tap and preventDefault on it
    $(this).bind('touchstart', function preventZoom(e) {
    // recreate the double tab functionality
            var t2 = e.timeStamp
          , t1 = $(this).data('lastTouch') || t2
          , dt = t2 - t1
          , fingers = e.originalEvent.touches.length; 
            $(this).data('lastTouch', t2);
            if (!dt || dt > 500 || fingers > 1) return; // not double-tap 
            e.preventDefault(); // double tap - prevent the zoom
            // also synthesize click events we just swallowed up
            $(this).trigger('click').trigger('click');
        });
    

    【讨论】:

      【解决方案3】:

      我出于同样的目的写了一个jQuery plugin - 有选择地禁用给定页面元素的双击缩放(在我的例子中,导航按钮翻页)我想响应每次点击(包括双击)作为正常的点击事件,没有 iOS“触摸魔法”,无论用户点击多快。

      要使用它,只需在您关心的元素上运行$('.prev,.next').nodoubletapzoom(); 之类的东西。它使用的原理是在 500ms 内监听一个节点上连续的touchstart 事件,并在第二个运行event.preventDefault(),除非同时有其他触摸处于活动状态。由于 preventDefault 会同时消耗两个触摸,因此我们还为节点合成了两个“未命中”的点击事件,因此您预期的触摸操作发生的次数与用户预期的一样多。

      【讨论】:

      • 看起来很有趣。将尝试对其进行测试,并以我的结论作出回应。
      • 这是一个很酷的解决方案。尽管发生双击时,我无法让 onclick="..." 事件在目标项目上触发。你有什么想法吗?
      • 为我工作:jsfiddle.net/ecmanaut/xptak/show - jsfiddle.net/ecmanaut/xptak 的源代码 - 也许您的页面有处理程序窃取那些 click(或 touchstart)事件并运行 e.preventDefault()e.stopPropagation()在他们到达您的onclick 处理程序之前。
      • 它有效。你知道是否也可以禁用捏合缩放?
      【解决方案4】:

      实际上,.preventDefault() 确实有效...使用 jQuery:

      var InputHandler = {    
          startEventType : isTouch ? "touchstart" : "mousedown"
      }
      
      $(selector).bind(InputHandler.startEventType, function(evnt) {
          evnt.preventDefault();
      });
      

      您试图阻止 .click() 的问题是浏览器没有抛出“click”元素。 Safari 只会触发一次点击以帮助模拟点击......但是当有一个双标签时,Safair 不会通过“点击”元素。 .click() 的事件处理程序永远不会触发,因此 .preventDefault() 也不会触发。

      【讨论】:

      • 这种方法似乎可以检测到触摸客户端。实际上,有一些设备既是触控又是鼠标,所以这种非此即彼的区别并不适用,或者会破坏某些用户的网站。
      【解决方案5】:

      您需要在第二次点击时实现双击功能和preventDefault。下面是一些使用全局变量的测试代码,可以帮助您入门:

      <button id="test1">Double Tap Me!</button>
      <div id="test2">EMPTY</div>
      
      var elm1 = document.getElementById('test1');
      var elm2 = document.getElementById('test2');
      var timeout;
      var lastTap = 0;
      elm1.addEventListener('touchend', function(event) {
          var currentTime = new Date().getTime();
          var tapLength = currentTime - lastTap;
          clearTimeout(timeout);
          if (tapLength < 500 && tapLength > 0) {
              elm2.innerHTML = 'Double Tap';
              event.preventDefault();
          } else {
              elm2.innerHTML = 'Single Tap';
              timeout = setTimeout(function() {
                  elm2.innerHTML = 'Single Tap (timeout)';
                  clearTimeout(timeout);
              }, 500);
          }
          lastTap = currentTime;
      });
      

      还有一个小提琴:http://jsfiddle.net/brettwp/J4djY/

      【讨论】:

      • 谢谢,但它并没有在我的 Android 上禁用缩放。有什么想法吗?
      • @Gaurav,您可能想针对 Android 单独提出一个问题,并包括您要完成的任务以及您的目标设备(手机、平板电脑、版本等)的详细信息。
      【解决方案6】:

      除了捕获您想要阻止的事件并调用preventDefault() 之外别无他法,因为您已经或多或少地想通了。

      确实,某些特定的 CSS 属性/值可能会改变全局站点行为(例如,固定宽度或 fixed),但您不能安全地避免更改操作系统(请参阅 iOS5 中的 fixedhandling 更改) ,这些更改也不一定会阻止所有行为(捏合可能会关闭,但不会双击)。

      因此,禁用默认行为的最佳方法仅用于双击是利用count of touches iOS 提供的优势:如果我们只有一个联系人,那么我们正在点击。二,这意味着我们在捏。

      以下设置代码提供了该功能:

      var elm = document.body; // or some selection of the element you want to disable
      
      var catcher = function(evt) {
          if (evt.touches.length < 2)
              evt.preventDefault();
      };
      
      elm.addEventListener('touchstart', catcher, true);
      

      Demo 在 jsFiddle 上。

      注意:addEventListener 的第三个参数 (true) 表示我们要 capture events,即捕获它们,即使是我们的后代。

      【讨论】:

      • 如果preventDefault() 有效,那会很糟糕,但可以接受。但它没有。至少对于click ...我会尝试同样的方法,对于触摸事件也会尝试stopPropagation()。 (最大的障碍是“我的”iPad 和我的工作场所相距甚远)。
      • click 怎么了?你说你想防止双击缩放。根据我在 iOS 设备(iPhone 3GS)上的测试,小提琴显示上述代码可防止双击放大。我不明白你为什么提到click 事件:-S
      • 从编写代码到在 iPad 上测试,我平均需要 2-3 天,抱歉。我希望明天测试一下。
      • ...呃。您的示例禁用单指双击缩放(酷!),但它也完全禁用单指点击(不太酷),因此它甚至停止产生点击。两指双击工作,两指平移工作。两指捏合缩放有一些问题.. 获得 +1,不过。
      • @c69 哦,感谢您的赏金!你奖励它是因为它结束了还是它正好解决了你的问题?我们需要记录实际的工作答案for the future :)
      【解决方案7】:

      您使用的是什么 iOS 版本/Safari 浏览器?该网站绝对不允许您双击。我找到了一些 CSS,但由于我即将走出去,所以没有时间尝试:

      body {
        -webkit-text-size-adjust:none;
        margin:0px;
      }
      
      div{
        clear:both!important;
        display:block!important;
        width:100%!important;
        float:none!important;
        margin:0!important;
        padding:0!important;
      }
      

      【讨论】:

        【解决方案8】:

        Apple 提供了很多关于 webkit (Safari) 专用标签的提示。 View Official Docs

        【讨论】:

        • 我想我只需要尝试一下我最初的想法 - prevent default behaviour
        • 有可能...不幸的是,我找不到我曾经这样做的代码!访问像 foxnews.mobi 这样的网站;你不能捏缩放或双击缩放。它是通过一个特殊的 CSS webkit 元素完成的。如果我找到了代码,我会分享它 lol
        • 对不起,伙计们,这并不能阻止任何事情。在 foxnews.mobi - 有宽度:95%,这就是为什么没有缩放,但是当你双击时它会居中内容,所以这不是一个很好的例子。
        猜你喜欢
        • 2012-05-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-03
        • 2020-02-19
        • 2020-05-01
        相关资源
        最近更新 更多