Safari iPad:防止双击放大

Safari iPad:防止双击放大,ipad,safari,zooming,Ipad,Safari,Zooming,我正在Safari上为iPad创建一个网站。我需要防止双击放大事件,但我有两个问题: 双击不会生成任何事件,因此我不能使用“event.preventDefault();” 我只需要在满足某些条件时执行此操作,因此我不能使用标记“”。。。如果我这样做,用户就永远无法缩放我的页面 如何解决这些问题?Mobile Safari不支持javascript ondblclick事件。Safari将其解释为“缩放” Raul Sanchez发布了一个潜在的解决方案: 我为同样的目的编写了一个jQuer

我正在Safari上为iPad创建一个网站。我需要防止双击放大事件,但我有两个问题:

  • 双击不会生成任何事件,因此我不能使用“event.preventDefault();”
  • 我只需要在满足某些条件时执行此操作,因此我不能使用标记“
    ”。。。如果我这样做,用户就永远无法缩放我的页面

如何解决这些问题?

Mobile Safari不支持javascript ondblclick事件。Safari将其解释为“缩放”

Raul Sanchez发布了一个潜在的解决方案:

我为同样的目的编写了一个jQuery插件——有选择地禁用对给定页面元素的双击缩放(在我的例子中,是翻页的导航按钮),我希望将每次点击(包括双击)作为正常的点击事件来响应,而不使用iOS“触摸魔术”

要使用它,只需运行类似于
$('.prev,.next').nodoubletapzoom()的命令在您关心的元素上。(编辑:现在也忽略夹点)

//jQuery无双击缩放插件
//三重许可:公共领域,麻省理工学院和WTFPL许可-共享和享受!
(函数($){
var是IOS=/iphone | ipad/i.test(navigator.userAgent);
$.fn.nodoubletapzoom=函数(){
if(IS_IOS)
$(this).bind('touchstart',函数preventZoom(e){
var t2=e.时间戳
,t1=$(this).data('lastTouch')| | t2
,dt=t2-t1
,fingers=e.originalEvent.touchs.length;
$(此).data('lastTouch',t2);
如果(!dt | | dt>500 | | fingers>1)返回;//不双击
e、 preventDefault();//双击-防止缩放
//还有我们刚刚吞下的点击事件
$(this.trigger('click')。trigger('click');
});
};
})(jQuery);

仅仅设置viewport可能并不总是足够-在某些情况下,您可能还需要调用 event.preventDefault();
在touchstart处理程序上。

我修改了@ecmanaut的javascript解决方案来完成两件事

  • 我使用Modernizer,所以它会在html节点上放置一个.touch css类,这样我就可以检测触摸屏而不是使用用户代理检测。也许有一种“少现代化”的方法,但我不知道
  • 我将每个“点击”分开,这样它们就会分开发生,如果你点击一次,它就会点击一次,如果你快速点击按钮/触发器,它会计数多次
  • 一些小的代码格式更改,我更喜欢每个单独定义的变量,等等,这是一个“我”的东西,而不是其他任何东西,我想你可以恢复,没有什么不好的事情会发生
  • 我相信这些修改会使它变得更好,因为你可以增加计数器1,2,3,4,而不是2,4,6,8

    以下是修改后的代码:

    //  jQuery no-double-tap-zoom plugin
    //  Triple-licensed: Public Domain, MIT and WTFPL license - share and enjoy!
    //
    //  chris.thomas@antimatter-studios.com: I modified this to 
    //  use modernizr and the html.touch detection and also to stop counting two 
    //  clicks at once, but count each click separately.
    
    (function($) {
        $.fn.nodoubletapzoom = function() {
            if($("html.touch").length == 0) return;
    
            $(this).bind('touchstart', function preventZoom(e){
                var t2 = e.timeStamp;
                var t1 = $(this).data('lastTouch') || t2;
                var dt = t2 - t1;
                var 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');
            });
        };
    })(jQuery);
    
    将nodoubletapzoom()应用于body标记,如下所示

    $("body").nodoubletapzoom();
    
    <body>
        <div class="content">...your content and everything in your page</div>
    </body>
    
    $(".content")
        .on(".mydomelement","click",function(){...})
        .on("button","click",function(){...})
        .on("input","keyup blur",function(){...}); 
        // etc etc etc, add ALL your handlers in this way
    
    你的html结构应该是这样的

    $("body").nodoubletapzoom();
    
    <body>
        <div class="content">...your content and everything in your page</div>
    </body>
    
    $(".content")
        .on(".mydomelement","click",function(){...})
        .on("button","click",function(){...})
        .on("input","keyup blur",function(){...}); 
        // etc etc etc, add ALL your handlers in this way
    
    您可以使用任何jquery事件处理程序和任何dom节点。现在你不需要做更多的事情,你必须用这种方式连接所有事件处理程序,我没有尝试过其他方式,但这种方式绝对可靠,你可以每秒敲击屏幕10次,它不会缩放并记录点击(显然不是每秒10次,ipad没有那么快,我的意思是,你不能触发变焦)

    我认为这是可行的,因为您将nozoom处理程序附加到body,然后将所有事件处理程序附加到“.content”节点,但将委托给所讨论的特定节点,因此jquery在事件冒泡到body标记之前的最后阶段捕获所有处理程序

    此解决方案的主要好处是,只需将nodoubletapzoom()处理程序分配给主体,只需执行一次,而不是对每个元素执行一次,因此完成任务所需的工作量、精力和思考都要少得多

    这还有一个额外的好处,如果您使用AJAX添加内容,它们会自动让处理程序准备就绪并等待,我想如果您不想这样做,那么这种方法将不适用于您,您必须对其进行更多的调整

    我已经在ipad上验证了这段代码的有效性,它实际上很漂亮,在@ecmanaut上做得很好,作为主要解决方案


    **5月26日星期六进行了修改,因为我发现似乎是一个完美的解决方案,只需付出极小的努力

    对我来说,接受的“双击”答案有点“臃肿”,并使用了时间戳……为什么?请看这个简单的实现,不要过度“臃肿”

    function simulateDblClickTouchEvent(oo)
    {
     var $oo = !oo?{}:$(oo);
     if( !$oo[0] )
      { return false; }
    
     $oo.bind('touchend', function(e)
     {
        var ot = this,
        ev = e.originalEvent;
    
        if( ev && typeof ev.touches == 'object' && ev.touches.length > 1 )
         { return; }
    
        ot.__taps = (!ot.__taps)?1:++ot.__taps;
    
        if( !ot.__tabstm ) // don't start it twice
        {
         ot.__tabstm = setTimeout( function()
         {
           if( ot.__taps >= 2 )
           {  ot.__taps = 0;
              $(ot).trigger('dblclick'); 
           }
           ot.__tabstm = 0;
           ot.__taps = 0;
         },800);
        }
     });
     return true;
    };
    
    用法:

    simulateDblClickTouchEvent($('#example'));
    
    or 
    
    simulateDblClickTouchEvent($('.example'));
    
    当事件是否绑定时,函数返回true或false

    要防止缩放和滚动,请执行以下操作:

    function disableTouchScroll()
    {
    
     try {
      document.addEventListener('touchmove', function(e) { e.preventDefault(); }, true );
      $j('body')[0].addEventListener('touchmove', function(e) { e.preventDefault(); }, true );
      }
      catch(ee) { return false; }
      return true;
    }
    
    此外,使用CSS可以轻松避免缩放:

    body * { -webkit-user-select:none; }
    
    • =效率不高,但试试看,效果很好

    干杯!

    试试这个修改过的代码。它应该适用于android和IOS设备

    (function($) {
    $.fn.nodoubletapzoom = function() {
        $(this).bind('touchstart', function preventZoom(e){
            var t2 = e.timeStamp;
            var t1 = $(this).data('lastTouch') || t2;
            var dt = t2 - t1;
            var 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
            $(e.target).trigger('click');
        });
    };
    })(jQuery);
    
    然后将nodoubletapzoom()应用于body标记

    $("body").nodoubletapzoom();
    

    我看到的所有解决方案(在本页和其他地方)都有一个副作用,它们可以防止快速重复点击。允许每500毫秒点击一次或类似。在某些情况下,这是可以的,但如果您有一个射手或箭头按钮,允许从一个项目快速移动到另一个项目

    最简单的解决方案是:

    $('#nozoom').on('touchstart', function(e)
    {
      fn_start(e);
      e.preventDefault();
    });
    
    每次触摸启动时都会调用
    fn_start()
    (实际的回调函数),但会阻止默认的缩放等操作

    下面是一个有效的比较示例:。
    绿色框阻止,红色框允许。

    如果有人需要一个没有jQuery的解决方案,我发现这个()工作得很好。函数需要和事件对象作为参数:

    function preventZoom(e) {
      var t2 = e.timeStamp;
      var t1 = e.currentTarget.dataset.lastTouch || t2;
      var dt = t2 - t1;
      var fingers = e.touches ? e.touches.length : 0;
      e.currentTarget.dataset.lastTouch = t2;
    
      if (!dt || dt > 500 || fingers > 1) return; // not double-tap
    
      e.preventDefault();
      e.target.click();
    }
    
    角度10的示例:

    
    点击我
    

    我确实使用过这个解决方案…这个主题非常详细,谢谢!对于访问者来说,主要思想如下:首先,捕获一个“点击”事件。然后,如果在500毫秒之前抛出另一个“点击”事件:这是一个“双击”,因此如果您可以在此处停止该事件-