jQuery的.on()和.delegate()在iPad上无法正常工作

31

如果您在桌面上尝试此代码片段,一切正常。
但是,如果您在上尝试,则不会有任何反应。

$('body').on('click', '#click', function() {
    alert("This alert won't work on iPad");
});
div { 
  font-size: 24px; 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="click">Click here</div>

简单的.click()事件处理程序可行,但这不是我想要的。同样适用于.delegate();.live()

这是一个错误还是什么?


你正在使用jQuery Mobile吗?on是在2011年11月添加到jQuery 1.7.2中的,但尚未应用到jQuery Mobile中。 - Joe Frambach
@joeframbach,你的意思是它被添加到了jQuery 1.7中? - Sparky
@joeframbach,我也不明白你的观点。jQuery Mobile不是独立的...它需要jQuery;因此,如果您正在使用jQuery 1.7,则具有on() - Sparky
Martin,使用“click”作为您的“id”名称是否是根本问题?(我无法测试)也许它不是保留字,但个人而言,我会避免以这种方式命名事物。 - Sparky
7个回答

34

啊,这也是一个不错的答案!是的,这可能是一个全局性的解决方案! - Martin.
此外,事件冒泡的层数越少,越好。将 .on() 绑定到 body 上通常(并非总是)是适得其反的。在这里,您的元素是唯一的 #id,所以直接绑定就足够了,只要它没有被 Ajax 注入即可。 - mddw
如果你从ajax请求中获取了#id,你需要使用委托或.on()。@mdi 我不明白你的意思。 - Martin.
这正是我所想的...直接绑定#id,除非使用Ajax。 - mddw
良好的研究,您的测试示例证明了该行为。 但最简单的解决方法是添加cursor:pointer - 它将使点击事件冒泡。在这里查看Simon Arnold的答案。 - 1234ru
如果任何人在非body元素上遇到此问题,问题可能是其他附加到您的元素的悬停事件,例如bootstrap工具提示。我注意到我必须触摸两次才能触发我的事件委托,但当我禁用工具提示时,事件在第一次触摸时就会触发,如预期所示。 - Philip Holly

30

将iOS设备上body元素的鼠标指针样式更改为"pointer",所有东西都会完美地工作。您无需在想要可点击的每个元素上添加onclick = "" ...

<script type="text/javascript">
    $(function() {
        // The trick
        if (/ip(hone|od)|ipad/i.test(navigator.userAgent)) {
           $("body").css ("cursor", "pointer");
        }
        // The test
        $("body").on("click", "#click", function() {
            alert("This also works on iOS !");
        });
    });
</script>
<div id="click">Click here</div>

我知道你现在在想什么:"WTF!"。


6
这个行为看起来很奇怪,但我找到的最好解释在这里:(http://swsharinginfo.blogspot.in/2013/03/solution-for-click-event-issue-on-ipad.html)。简而言之,iPad/pod/phone上的首次触摸被视为悬停。为了告诉浏览器该元素是可点击的,您需要将 cursor:pointer 添加到元素中。注意1:要将 cursor:pointer 添加到底层元素 $('#myElement') 中,而不仅仅是 $('myElement:hover')。注意2. 您可以直接添加 cursor:pointer 到您的 CSS 文件中。这对我有用! - dunxz
这正是我所思考的。 - troelskn
我找到的最好的解释是:苹果编码烂透了。这个问题在iOS 9上的Safari仍然存在。 - Ian Kemp

12
在 iOS 上,如果没有光标样式,就不会有事件冒泡。因此,在 CSS 中您需要为该元素添加“cursor: pointer;”。

$('body').on('click', '#click', function() {
    alert("This alert won't work on iPad");
});
#click { 
  font-size: 24px; 
  cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="click">Click here</div>

我知道这个问题很久以前就被问过了,但我认为一个简单的 CSS 解决方案可能会有所帮助。


2
西蒙,你太棒了! 这是对这种行为的简单解释和快速解决方法。 你救了我的一天。 - 1234ru

12

我不确定为什么它不能正常工作,可能是个bug,但有一个不错的解决方法。只需在你委托的div中加入onclick=""即可完美解决。

<div id="click" onclick="">Click here</div>
<script>
$("body").on("click", "#click", function() {
    alert("This works on iPad");
});
</script>

fiddle


4
完全可以提出一个问题并立即回答它。我之前也这样做过。如果您有任何异议,请在 Meta 上提出;不要劫持其他回答的评论区。谢谢。 - BoltClock

3

我在http://www.danwellman.co.uk/fixing-jquery-click-events-for-the-ipad/上找到了解决方案。

按照以下方法进行:

var isIPad = function() {
    return (/ipad/i).test(navigator.userAgent);
};
var isIPhone = function() {
    return (/iphone/i).test(navigator.userAgent);
};
var isIPod = function() {
    return (/ipod/i).test(navigator.userAgent);
};

并且在绑定点击事件处理程序时这样做:
var eventName = (isIPod() || isIPad() || isIPhone()) ? "touchstart" : "click";
// if you are using jquery-mobile
eventName = (isIPod() || isIPad() || isIPhone()) ? "touchstart" : "vclick";

$(".selector").bind(eventName, function(e) {
    //do something here
});
// or
$(document).on(eventName, ".selector", function(e) {
    //do something here
});

就是这样。


这个没有任何黑客技巧,很合理! - TruMan1
你不能在同一个on()中声明两个事件吗?那为什么不直接这样做:$(document).on("click touchstart",".class",function) - john k

0

我在 iPhone 5C 及以下设备上遇到了这个问题。
这个方法对我有效:

body {
  cursor:pointer;
}

0

我遇到了一个问题,就是我在HTML body前面添加消息时出现了问题。我在[jQuery 'click' event doesn't work on iOS Safari?]上找到了这个问题。

我使用了这个。

$('body').on('click touchstart', 'someselect', function(){})

它在iPhone 4S和iPhone 5S上运行良好。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接