jQuery的on()方法在移动版Safari中无效。

3
我希望您能够翻译使用jQuery $.ajax({...})和XML文件动态生成的列表的toggleClass功能。在Safari和Chrome桌面端上可以正常工作,但在移动端Safari上却不行。Delegate和Live在移动端也无效。
我正在使用jQuery 1.7.2,在iPad(iOS 5.1)和iPhone(iOS 5.0.1)上使用,没有使用jQuery mobile。
jQuery文档建议使用.on()代替.live(),因为.live()自1.7版本开始已弃用。
原始HTML。
<ul id="movies">
   /* empty */
</ul>

动态生成后
<ul id="movies">
    <li>Movie-1</li>
    <li>Movie-2</li>
    <li>Movie-3</li>
</ul>

以下内容在桌面版Safari和Chrome上可以运行,但在移动版Safari上无法运行。
$(document).on('click', '#movies li', function() {
    $(this).toggleClass('selected');
});

cyrusv似乎问了一个类似的问题,并自己回答了解决方案,但他没有详细说明。 https://stackoverflow.com/a/9538134/372567 说:

向div元素添加onclick =''。不确定为什么这样做有效,但确实有效。


cyrusv 似乎提出了一个类似的问题,并自己回答了解决方案,但他没有详细说明。链接 - Joel Z.
我在我的应用程序中使用jQuery on()来完成许多事情,它们都可以在iPhone和iPad的iOS Safari上正常工作。 - Dylan Cross
8个回答

4

将事件绑定到document元素并不是最佳实践,您应该改为这样做:

$('#movies').on('click', 'li', function() {
    $(this).toggleClass('selected');
});

2
同时,使用ID指定标签类型也是不好的做法。一个ID应该只有一个。添加ul会导致jQuery遍历整个DOM以查找具有该ID的DOMS。将其保留为#movies可以让它在找到第一个实例时停止。 - Kyle Macey
对于类:非常好。CSS:很棒。但是jQuery和Ids就不太行了。 - Kyle Macey
2
没问题 :) 我打字太快了。 - Darius
谢谢你,Kyle。这是我第一次使用.on(),并不理解问题,但现在看到你的解决方案,似乎很基本。非常感谢,做得好! - Joel Z.
谢谢Darius的回答。 - Joel Z.

4

所以,为了总结这一切,我在调试和搜索了数小时后才到达这里:

为了使事件绑定在Ajax调用之后仍然有效,您需要将它们绑定到文档而不是元素,例如:

而不是:

$('.foo').on('click', function() { ... }

使用:

$( document ).on('click', '.foo', function () { ... }

然而,对于iOS移动版的Safari浏览器,此文档绑定将无法工作,除非您在元素的HTML中还包含onclick = ""。奇怪但却是真的。


谢谢。你刚刚为我节省了很多时间。 - jerome
对于其他人来说:我遇到了Safari iOS移动版的问题,测试BrowserStack似乎表明onclick="void(0)"可能更有帮助。 onclick =""本身不起作用。 我不确定这是否是BrowserStack的问题。 - petrosmm

1

我曾使用on()时遇到类似问题。在桌面版的Chrome和Safari上可以运行,但在任何移动浏览器上都无法运行。像cyrusv建议的那样,解决方案是这样的:

JQuery:

$('#questions').on('click', 'li', function() {
    ....
});

将HTML代码从以下内容更改为:

<div id="questions"> 
  <li>...</li>
  <li>...</li>
</div> 

至:

<div id="questions"> 
  <li onclick=''>...</li>
  <li onclick=''>...</li>
</div> 

0
你是否使用了 jQ DocReady 包装?$(function() { ... })
$(function() {
  $('#movies li').on('click', function() {
    $(this).toggleClass('selected');
  });
});

0

$(document).on在新版本的桌面Safari上也存在问题(至少在8.0.8上)。 Safari还存在一个问题,即仅使用变量而不指定名称和值的Ajax POST调用。 仅指定变量在Chrome和Firefox中都可以正常工作。

在Safari中将无法正常工作:

var id = 1;
$.ajax({
            type: "POST",
            url: "@Url.Action("AjaxAction")",
            data: {
                id
            }
        });

适用于所有浏览器:

var id = 1;
$.ajax({
            type: "POST",
            url: "@Url.Action("AjaxAction")",
            data: {
                id:id
            }
        })

0

我在使用on('change')时遇到了同样的问题。当我在HTML中添加onchange=''时,它就可以正常工作了。


0

实际上,将委派任务交给更高级别的元素,如文档或其他容器,是一个好的实践方法。但是当针对iOS时,必须考虑以下内容: 在jQuery中进行事件委托,如 $(document).on('click', '.target-element', function(event) {...}); 将不起作用。您必须将 onclick = "" 添加到目标元素或将其样式设置为 cursor:pointer

解释取自http://gravitydept.com/blog/js-click-event-bubbling-on-ios并进行了修改:

事实证明,在iPhone上的Safari不支持除链接或输入之外的点击事件的事件委派。幸运的是,有可用的解决方法。


0

再加两个选择器,为了选项的缘故 :)

$("#movies li").on("click", function(){
    $(this).toggleClass('selected');
})

$("ul[id='movies'] li").on("click", function(){
    $(this).toggleClass('selected');
})

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