Javascript Safari iPad 1:如何在双击时禁用缩放/居中,但保持捏合缩放
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8071603/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Safari iPad 1: how to disable zoom/centering on double-tap, but keep pinch zoom
提问by c69
I wonder if its possible to prevent double-tap-to-zoom and double-tap-to-center on a specific HTML element in Safari iOS (iPad 1) ?
我想知道是否有可能防止在 Safari iOS (iPad 1) 中的特定 HTML 元素上双击缩放和双击居中?
Because my small HTML5 game forces users to make fast clicks (or taps), which are interpreted as double clicks, and when it happens - the page changes zoom and centers itself.
因为我的小型 HTML5 游戏迫使用户快速点击(或点击),这被解释为双击,当它发生时 - 页面会改变缩放并居中。
Detecting double clicks (like in this answer - Safari iPad : prevent zoom on double-tap) smells bad..
检测双击(就像在这个答案中 - Safari iPad:防止双击放大)闻起来很糟糕..
Wrong answer #1:<meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
- does not suit my purposes, because it will block any zoom.
错误答案 #1:<meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
- 不适合我的目的,因为它会阻止任何缩放。
Wrong answer #2:maybe would .preventDefault()
on click event alone be enough for that ? - Does not have any effect.
错误答案#2:也许.preventDefault()
仅点击事件就足够了?- 没有任何影响。
回答by MattiSG
There's no other way than catching the events you want to prevent, and call preventDefault()
on them, as you had already more or less figured out.
除了捕捉您想要阻止的事件并调用preventDefault()
它们之外别无他法,正如您或多或少已经想到的那样。
Indeed, some particular CSS properties / values may change the global site behavior (fixed width or fixed
, for example), but you're not safe from changes to the OS (see fixed
handling change in iOS5), nor do these changes necessarily prevent all behavior (pinch might be off, but not double-tapping).
事实上,一些特定的CSS属性/值可能会改变全球网站上的行为(固定宽度或者fixed
,例如),但你从更改OS不是安全的(见fixed
处理在iOS5中的变化),也没有这些变化不一定会阻止所有行为(捏合可能关闭,但不能双击)。
So, the best way to disable default behavior only for double-tappingis to take advantage of the count of touchesiOS provides: if we have only one contact, then we're tapping. Two, this means we're pinching.
因此,仅针对双击禁用默认行为的最佳方法是利用iOS 提供的触摸计数:如果我们只有一个联系人,那么我们正在点击。二,这意味着我们正在捏。
The following setup code provides that functionality:
以下设置代码提供了该功能:
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);
Demoon jsFiddle.
jsFiddle 上的演示。
Note: the third parameter (true
) to addEventListener
means that we want to capture events, that is catch them all, even for our descendant children.
注意:第三个参数 ( true
) toaddEventListener
表示我们要捕获事件,即捕获所有事件,即使是我们的后代。
回答by amenthes
I am preventing doubletaps like this:
我正在防止这样的双击:
var doubleTouchStartTimestamp = 0;
$(document).bind("touchstart", function (event) {
var now = +(new Date());
if (doubleTouchStartTimestamp + 500 > now) {
event.preventDefault();
}
doubleTouchStartTimestamp = now;
});
The elegance lies within the fact, that no timeouts are needed. I only update a timestamp. It only gets compared on the next touchstart. Works for me on iOS 6.
优雅在于不需要超时的事实。我只更新一个时间戳。它只会在下一次 touchstart 时进行比较。在 iOS 6 上对我有用。
Doubletaps further down the dom are not affected.
dom 下的双击不受影响。
The same works without jQuery, as well:
不使用 jQuery 也一样:
var doubleTouchStartTimestamp = 0;
document.addEventListener("touchstart", function (event) {
var now = +(new Date());
if (doubleTouchStartTimestamp + 500 > now) {
event.preventDefault();
}
doubleTouchStartTimestamp = now;
});
回答by ecmanaut
I wrote a jQuery pluginfor the same purpose - selectively disabling double-tap zoom on given page elements (in my case, navigation buttons to flip pages) I want to respond to every tap (including double-tap) as a normal click event, with no iOS "touch magic", no matter how fast the user clicks it.
我为同样的目的编写了一个jQuery 插件- 有选择地禁用给定页面元素上的双击缩放(在我的情况下,导航按钮来翻转页面)我想响应每一次点击(包括双击)作为一个普通的点击事件,没有 iOS 的“触摸魔法”,无论用户点击它的速度有多快。
To use it, just run something like $('.prev,.next').nodoubletapzoom();
on the elements you care for. The principle it uses is to listen for consecutive touchstart
events on a node within 500ms, and running event.preventDefault()
on the second, unless other touches are active at the same time. As that preventDefault consumes both touches, we also synthesize the two "missed" click events for the node, so your intended touch action happens as many times as the user intended.
要使用它,只需$('.prev,.next').nodoubletapzoom();
在您关心的元素上运行类似的东西。它使用的原理是touchstart
在 500ms 内监听一个节点上的连续事件,并event.preventDefault()
在第二个运行,除非其他触摸同时处于活动状态。由于 preventDefault 消耗了两次触摸,我们还为节点合成了两个“错过的”点击事件,因此您预期的触摸操作发生的次数与用户预期的一样多。
回答by Paul Styles
JQuery approach to disable Double Tap Zoom in MVC4 To Disable the double tap (double mouse down) functionality on iOS 1+ you need to catch the touchStart Event and create an override to prevent the zoom.
在 MVC4 中禁用双击缩放的 JQuery 方法要在 iOS 1+ 上禁用双击(双击鼠标)功能,您需要捕获 touchStart 事件并创建覆盖以防止缩放。
// Using Single script.js and JQuery.Mobile-1.2.0 UI each page in MVC gets assigned JQuery through delegates so you don't have to do a full refresh of the page allowing you to take advantage of the data-prefetch which loads the page in the DOM when the app loads for the first time
// 使用 Single script.js 和 JQuery.Mobile-1.2.0 UI,MVC 中的每个页面都通过委托分配了 JQuery,因此您不必完全刷新页面,从而允许您利用数据预取当应用程序第一次加载时在 DOM 中加载页面
$(document).delegate("#CashRegister", "pageinit", function () {
$(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');
});
回答by Brett Pontarelli
You will need to implement a double tap function and preventDefault
on the second tap. Here is some tested code that uses global variables that should get you started:
您将需要实现双击功能和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;
});
And a fiddle: http://jsfiddle.net/brettwp/J4djY/
还有一个小提琴:http: //jsfiddle.net/brettwp/J4djY/
回答by master_gracey
Apple has a lot of tips with specialized tags for webkit (Safari). View Official Docs
Apple 有很多关于 webkit (Safari) 专用标签的提示。查看官方文档
回答by master_gracey
What iOS version/Safari browser are you using? That site most definitely does not let you double-tap. I found some CSS but haven't had time to try it as I'm about to step out:
您使用的是什么 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;
}
回答by weisjohn
Actually, .preventDefault() definitely does work... using jQuery:
实际上, .preventDefault() 确实有效……使用 jQuery:
var InputHandler = {
startEventType : isTouch ? "touchstart" : "mousedown"
}
$(selector).bind(InputHandler.startEventType, function(evnt) {
evnt.preventDefault();
});
Your problem with trying to prevent on .click() is that the browser isn't throwing a "click" element. Safari only fires a click to help simulate a click... But when there's a double tab, Safair doesn't through a "click" element. Your event handler for .click()
doesn't ever fire, and therefore the .preventDefault()
doesn't fire either.
您试图阻止 .click() 的问题是浏览器没有抛出“click”元素。Safari 只触发点击以帮助模拟点击...但是当有双标签时,Safair 不会通过“点击”元素。您的事件处理程序 for.click()
永远不会触发,因此.preventDefault()
也不会触发。