我正在Safari for iPad上创建一个网站。我需要阻止双击事件的缩放,但我有两个问题:
<meta name = "viewport" content = "user-scalable = no">
”...如果我这样做,用户就永远无法放大我的页面。如何解决这些问题?
答案 0 :(得分:7)
Mobile Safari不支持javascript ondblclick事件。它被Safari解释为“缩放”。
Raul Sanchez发布了一个潜在的解决方案: http://appcropolis.com/implementing-doubletap-on-iphones-and-ipads/
答案 1 :(得分:7)
这是我为同一目的编写的jQuery插件 - 选择性地禁用双击缩放给定页面元素(在我的情况下,导航按钮翻转页面)我想响应每个点击(包括双击)作为正常点击事件,没有iOS“触摸魔法”。
要使用它,只需在您关注的元素上运行类似$('.prev,.next').nodoubletapzoom();
的内容即可。 (编辑:现在也会忽略捏合)
// jQuery no-double-tap-zoom plugin
// Triple-licensed: Public Domain, MIT and WTFPL license - share and enjoy!
(function($) {
var IS_IOS = /iphone|ipad/i.test(navigator.userAgent);
$.fn.nodoubletapzoom = function() {
if (IS_IOS)
$(this).bind('touchstart', function preventZoom(e) {
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');
});
};
})(jQuery);
答案 2 :(得分:6)
尝试这个修改过的代码。它应该适用于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();
答案 3 :(得分:5)
我修改了@ ecmanaut的javascript解决方案,做了两件事。
我相信这些修改使它更好,因为你可以增加一个计数器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();
你的html结构应该是这样的
<body>
<div class="content">...your content and everything in your page</div>
</body>
然后在你的javascript中绑定你的点击处理程序
$(".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处理程序附加到正文,然后将所有事件处理程序附加到&#34; .content&#34;节点,但委托给有问题的特定节点,因此jquery在事件冒泡到body标签之前的最后阶段捕获所有处理程序。
这个解决方案的主要好处是你只需要将nodoubletapzoom()处理程序分配给正文,你只需要执行一次,而不是每个元素执行一次,这样就不需要工作,努力和思考了为了完成任务。
这有另外一个好处,如果你使用AJAX添加内容,他们会自动让处理程序准备就绪并等待,我想如果你不想这样,那么这种方法对你和你来说都不会有用。我必须更多地调整它。
我已验证此代码适用于ipad,它实际上非常漂亮,对于@ecmanaut主要解决方案做得很好!!
** 5月26日星期六修改,因为我发现似乎是一个完美的解决方案,只需极少的努力
答案 4 :(得分:3)
我看到的所有解决方案(在此页面以及其他地方)都会产生副作用,导致它们无法快速重复点击。允许每500毫秒或类似的一次点击。在某些情况下这可能没问题,但不是例如。如果你有一个射击或箭头按钮,允许快速移动项目。
最简单的解决方案是:
$('#nozoom').on('touchstart', function(e)
{
fn_start(e);
e.preventDefault();
});
每次启动触摸时都会调用fn_start()
(实际的回调函数),但会阻止默认的缩放等。
工作比较示例如下:http://jsbin.com/meluyevisi/1/。 绿框禁止,红框允许。
答案 5 :(得分:1)
只是设置视口可能并不总是足够 - 在某些情况下,您可能还需要打电话 event.preventDefault(); 在touchstart处理程序上。
答案 6 :(得分:0)
接受的“双击”回答对我来说有点“臃肿”并使用时间戳.....为什么?看看这个简单的实现,没有过多的“臃肿”。
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; }
干杯!
答案 7 :(得分:0)
万一有人需要一个没有jQuery的解决方案,我发现这个(https://exceptionshub.com/disable-double-tap-zoom-option-in-browser-on-touch-devices.html)可以很好地工作。该函数将期望和事件对象作为参数:
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();
}
Angular 10示例:
<!— Template —>
<span (click)="clicked($event)">Click me</span>
Component
clicked(event) {
this.preventZoom(event);
// your code
}
preventZoom(e) {
var t2 = e.timeStamp;
var t1 = e.currentTarget.dataset.lastTouch || t2;
var dt = t2 - t1;
var fingers = e.touches?.length;
e.currentTarget.dataset.lastTouch = t2;
if (!dt || dt > 500 || fingers > 1) return; // not double-tap
e.preventDefault();
e.target.click();
}