为什么/什么时候我必须点击两次才能触发 iOS 上的点击

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17710893/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 00:22:21  来源:igfitidea点击:

Why/when do I have to tap twice to trigger click on iOS

iosmobileclicktouchtap

提问by user2383672

Ok I feel like I'm crazy...

好吧,我觉得我疯了……

I'm looking at Mobile Safari on iOs 6.0. I can't seem to establish any rhyme or reason as to when tapping on an element will trigger click. In many cases, it seems I need to tap once to trigger a hover and then again to trigger a click.

我正在查看 iOs 6.0 上的 Mobile Safari。我似乎无法确定何时点击元素会触发点击的任何押韵或原因。在许多情况下,似乎我需要点击一次以触发悬停,然后再次触发点击。

The Mobile Safari specsays : "... The flow of events generated by one-finger and two-finger gestures are conditional depending on whether or not the selected element is clickable or scrollable... A clickable element is a link, form element, image map area, or any other element with mousemove, mousedown, mouseup, or onclick handlers... Because of these differences, you might need to change some of your elements to clickable elements..."

移动Safari规范说:” ...由一个手指和两手指手势生成的事件的流动是有条件的根据所选的元素是否是可点击或滚动...一个可点击的元件是一个链接,表格元件、图像地图区域或任何其他具有 mousemove、mousedown、mouseup 或 onclick 处理程序的元素……由于这些差异,您可能需要将某些元素更改为可点击元素……”

It goes on to suggest that the developer "...Add a dummy onclick handler, onclick = "void(0)", so that Safari on iOS recognizes the span element as a clickable element."

它继续建议开发人员“...添加一个虚拟的 onclick 处理程序,onclick = "void(0)",以便 iOS 上的 Safari 将 span 元素识别为可点击元素。”

However, my testing has shown these statements to be false.

但是,我的测试表明这些陈述是错误的。

JsFiddle : http://jsfiddle.net/6Ymcy/1/

JsFiddle:http: //jsfiddle.net/6Ymcy/1/

html

html

<div id="plain-div" onclick="void(0)">Plain Div</div>

js

js

document.getElementById('plain-div').addEventListener('click', function() {
   alert('click'); 
});

Try tapping the element on an iPad. Nothing Happens

尝试在 iPad 上点击该元素。 没发生什么事

But I digress. What is important to me is to find out the following question:

但我离题了。对我来说重要的是找出以下问题:

Exactly what are the criteria that determine when clicking on an element will fire a 'click' event on the first tap?As opposed to firing a 'hover' event on the first tap and a 'click' event on the second tap.

确定单击元素时将在第一次点击时触发“单击”事件的确切标准是什么?与在第一次点击时触发“悬停”事件和在第二次点击时触发“点击”事件相反。

In my testing, anchor elements are the only elements that I can get to fire a click on the first tap, and then, only occasionally and inconsistently.

在我的测试中,锚元素是我可以在第一次点击时触发点击的唯一元素,然后只是偶尔和不一致。

Here's where I start to feel crazy. I searched the internet far and wide and found next to nothing about this issue. Is it just me?! Does anybody know where there's been any discussion about the criteria for two-taps and or an approach to dealing with these limitations?

这就是我开始感到疯狂的地方。我在互联网上广泛搜索,几乎没有发现关于这个问题的任何信息。只有我吗?!有没有人知道哪里有关于两次点击的标准和/或处理这些限制的方法的讨论?

I'm happy to respond to questions/requests.

我很高兴回答问题/请求。

Thanks!

谢谢!

回答by Gareth Farrington

I had this same issue. The simplest solution is not to bind the 'mouseenter' event on iOS (or any touch enabled target platform). If that is not bound the hover event won't get triggered and click is triggered on the first tap.

我有同样的问题。最简单的解决方案是不要在 iOS(或任何支持触摸的目标平台)上绑定 ' mouseenter' 事件。如果未绑定,则不会触发悬停事件,并在第一次点击时触发单击。

回答by noahott

iOS will trigger the hover event if an element is "display: none;" in the normal state and "display: block;" or inline-block on :hover.

如果元素为“display: none;”,iOS 将触发悬停事件。在正常状态和“显示:块;” 或内联块:悬停。

回答by sandre89

I was having this issue using Bootstrap, and I found out that the culprit was the tooltip. Remove the tooltip from the button and you don't need to tap it twice anymore.

我在使用 Bootstrap 时遇到了这个问题,我发现罪魁祸首是工具提示。从按钮中删除工具提示,您不再需要点击它两次。

回答by everyonesdesign

It is also worthwhile to mention that ':hover' pseudo-class may prevent 'click' event from firing.

还值得一提的是,':hover' 伪类可能会阻止触发 'click' 事件。

As in mobile browsers click is sometimes used to replace hovering action (e.g. to show dropdown menu), they may trigger artificial 'hover' state on first click and then handle click on the second one.

由于在移动浏览器中单击有时用于替换悬停操作(例如显示下拉菜单),它们可能会在第一次单击时触发人为的“悬停”状态,然后在第二次单击时处理单击。

See https://css-tricks.com/annoying-mobile-double-tap-link-issue/for detailed explanation and examples of that.

有关详细说明和示例,请参阅https://css-tricks.com/annoying-mobile-double-tap-link-issue/

回答by Frank

I solved this issue by first detecting if it was an iphone, then binding the mouseup event to the function I was trying to call.

我通过首先检测它是否是 iphone,然后将 mouseup 事件绑定到我试图调用的函数来解决这个问题。

if ((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i))){ 
    $('foo').on('mouseup', function(){
        ...
    }
}

I tried other events but mouseup seemed to work best. Other events like touchend were firing even if the user was trying to scroll. Mouseup doesn't seem to get fired if you drag your finger after touching.

我尝试了其他事件,但 mouseup 似乎效果最好。即使用户试图滚动,其他事件如 touchend 也会触发。如果您在触摸后拖动手指,Mouseup 似乎不会被触发。

Credit David Walsh (and ESPN) for the iPhone detection. http://davidwalsh.name/detect-iphone

归功于 David Walsh(和 ESPN)的 iPhone 检测。 http://davidwalsh.name/detect-iphone

回答by NodeDad

I was googling around to see if i could help you out some and found this piece of code. Try modifying it to your likings and see if you can do what your trying. If you have troubles understanding it let me know and i'll elaborate more. Theres also more to it here where i found it

我在谷歌上搜索,看看我是否可以帮助你一些并找到这段代码。尝试根据您的喜好修改它,看看您是否可以做您想做的事情。如果您在理解它时遇到问题,请告诉我,我会详细说明。还有更多内容在这里我找到了

Jquery hover function and click through on tablet

Jquery悬停功能并在平板电脑上点击

$('clickable_element').live("touchstart",function(e){
    if ($(this).data('clicked_once')) {
        // element has been tapped (hovered), reset 'clicked_once' data flag and return true
        $(this).data('clicked_once', false);
        return true;
    } else {
        // element has not been tapped (hovered) yet, set 'clicked_once' data flag to true
        e.preventDefault();
        $(this).trigger("mouseenter"); //optional: trigger the hover state, as preventDefault(); breaks this.
        $(this).data('clicked_once', true);
    }
});

回答by peterh

The display:none; solution mentioned above works on iOS (not tested on later than 9.3.5), but not on Android.

显示:无;上面提到的解决方案适用于 iOS(未在 9.3.5 之后测试),但不适用于 Android。

A hacky css-only solution is to hide the link below the element using a minus z-index and to bring the link up to a positive z-index on :hover or first-touch (with a small transition delay). I guess one could achieve the same result with css translate instead of z-index. Works on iOS and Android.

一个 hacky css-only 解决方案是使用负 z-index 隐藏元素下方的链接,并在 :hover 或第一次触摸时将链接提升到正 z-index(具有小的过渡延迟)。我想用 css translate 而不是 z-index 可以达到相同的结果。适用于 iOS 和 Android。

In this way you can display a hover effect on a link on a touch-screen device with the first tap without activating the url until a second tap.

通过这种方式,您可以通过第一次点击在触摸屏设备上的链接上显示悬停效果,而无需激活网址,直到第二次点击。

回答by Or Bachar

my solution was to remove the :hover state from the css, and when you think about it, mobile browsers should not have :hover state, since there is no hover..

我的解决方案是从 css 中删除 :hover 状态,当你考虑它时,移动浏览器不应该有 :hover 状态,因为没有悬停..

if you want to keep the hover state on desktop, you can use media query, like so:

如果要在桌面上保持悬停状态,可以使用媒体查询,如下所示:

.button {
    background: '#000'
}

@media (min-width: 992px) {
    .button:hover {
        background: '#fff'
    }
}

回答by Scott Phillips

You need @media (hover) { /* Your styles */ }

你需要 @media (hover) { /* Your styles */ }

As far as I can tell, this problem in various forms is still present.

据我所知,这个问题仍然存在各种形式。

In 2019, most, if not all of the above cases can be now ameliorated using a CSS only solution... it will however, require some stylesheet refactoring.

在 2019 年,大多数(如果不是全部)上述情况现在都可以使用仅 CSS 的解决方案来改善……但是,它需要一些样式表重构。

label {
  opacity:0.6  
}

label input[type=radio]:checked+span {
  opacity:1
}

.myClass::before { } /* Leave me empty to catch all browsers */

a:link { color: blue }
a:visited { color: purple }
a:hover { } /* Leave me empty to catch all browsers */
a:active { font-weight: bold }



/* Your styles */
@media (hover) {
  a:hover { color: red }

  .myClass::before { background: black }

  label:hover {
    opacity:0.8
  }
}

You can read in more detail here why Fastclick, :pseudo, <span>, just targeting "desktop" resolutions and first tap is hover and second tap is clickare all fixed using @media (hover): https://css-tricks.com/annoying-mobile-double-tap-link-issue/

您可以在此处更详细地阅读为什么Fastclick, :pseudo, <span>, 仅针对“桌面”分辨率并first tap is hover and second tap is click使用@media (hover)以下方法进行修复:https: //css-tricks.com/annoying-mobile-double-tap-link-issue/

:hoverdoesn't offer the clarity it once did as stylus input, touch desktops and mobile have a disparate interpretation of the notion.

:hover不像触控笔输入那样清晰,触摸台式机和移动设备对这个概念有不同的解释。

回答by Youssef Elsaygh

you can use ontouchstartinstead of onclickevent on element and call the function focus() on this element if it is input :

您可以在元素上使用ontouchstart代替onclick事件,并在此元素上调用函数 focus() 如果它是输入:

document.getElementById('plain-div').addEventListener('touchstart', function() {
   //write body of your function here
    alert(“hi”);
  // if input needs double tap 
  this.focus();

});