我正在为Safari创建一个用于iPad的网站。我需要防止双击事件的缩放,但我有两个问题:Safari iPad:防止双击变焦
- 双击不会生成任何事件,所以我不能使用“event.preventDefault();”
- 我只有在满足一些条件时才需要这样做,所以我不能使用标签“
<meta name = "viewport" content = "user-scalable = no">
”...如果我这样做了,用户永远无法放大我的页面。
我该如何解决这些问题?
我正在为Safari创建一个用于iPad的网站。我需要防止双击事件的缩放,但我有两个问题:Safari iPad:防止双击变焦
<meta name = "viewport" content = "user-scalable = no">
”...如果我这样做了,用户永远无法放大我的页面。我该如何解决这些问题?
Mobile Safari不支持javascript ondblclick事件。它被Safari解释为“缩放”。
劳尔·桑切斯发布了一个潜在的解决方案: http://appcropolis.com/implementing-doubletap-on-iphones-and-ipads/
这里有一个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);
这可行,但有一个错误:多于两次点击。在触发吞噬点击之后添加:$(this).data('lastTouch',0);'。没有它,当你三次点击时,你会得到四次点击(可能更多的是四次点击)。有了它,您可以在三次点击上点击三次,四次点击就可以点击四次。这个想法是,你可能有一个元素,应该响应很多连续的水龙头(而不是被持有,无论出于何种原因)。 – 2014-10-20 16:12:08
此解决方案似乎可以防止所有重复点击,如果它们之间的延迟小于500毫秒。它会以某种方式允许点击例如。在500ms的时间范围内5次并仍然防止缩放?我需要一种在鼠标设备中重复点击的方式。 – 2015-06-09 19:02:47
我发现了一个简单的解决方案,我的射手问题:http://stackoverflow.com/a/30744654/1691517。它不会“等待”500毫秒,直到允许新的点击,但立即执行,但仍可防止不必要的点击缩放。 – 2015-06-09 23:38:21
只是塞汀视可能并不总是不够的 - 在某些情况下,你可能不得不也呼吁 event.preventDefault();在touchstart处理程序上。
我修改@ 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!
//
// [email protected]: 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处理程序,然后将所有事件处理程序附加到“.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").nodoubletapzoom();
感谢您的支持!我举了一个例子:http://jsbin.com/dihoxedika/1/。 ecmanauts代码中的问题是$(this).trigger('click')。trigger('click')'。当我用'e.target'替换'this'并删除了第二个触发器时,它开始在Android Chrome中运行。问题在于快速重复点击是不可能的。 – 2015-06-10 21:23:28
如果是相关的,请接受答案 – Inventillect 2015-06-13 06:30:58
我所看到的所有解决方案(此页面上及其他地方)有一个侧它们可以防止快速重复点击。允许每500ms或类似点击一次。在某些情况下,这可以是好的,但不是例如。如果您有射手或箭头按钮可以快速移动物品。
最简单的方法是这样的:
$('#nozoom').on('touchstart', function(e)
{
fn_start(e);
e.preventDefault();
});
这就要求fn_start()
(实际回调函数),每次当触摸时开始,但阻止则默认值zoomings等时间
工作比较例子是在这里:http://jsbin.com/meluyevisi/1/。 绿框可以防止,红框允许。
我确实使用了这个解决方案......这个主题真的很详细,谢谢!对于游客来说,主要想法如下:首先,抓住一个“轻拍”事件。然后,如果在500ms之前抛出另一个“tap”事件:这是一个“双击”,所以如果您可以在这里停止事件 - >不“双击”:)请参阅链接以获取更多解释。 – Nicolas 2011-06-17 07:47:43