在移动浏览器中,JQuery点击事件不适用于iframe

时间:2013-08-09 16:53:52

标签: jquery mobile mobile-browser

这是我遇到的一个非常具体的问题,但我对如何调试这个问题缺乏想法,或者甚至不知道它是否适用于移动浏览器。

我有2个页面(都在SAME域上,因此我没有跨域安全策略的问题),一个在另一个内部的iframe中。由于我需要捕获父项和子项的点击,我创建了一个覆盖iframe的div,然后调用子元素上的click方法:

这是我制作的演示代码:

父文件:

<script>
$(document).ready(function()
{
    $("#floating_play_button").click(function()
    {
        alert("just clicked floating_play_button... will try to click iframe's on click for link2");
        $('#slider').contents().find("#link1").click();
    });
});
</script>

<div id="floating_play_button" style="cursor:pointer; left: 0px; top:0px; width:100%; height:395px; position:absolute; border:2px solid red;"></div>
<iframe id="slider" src="slider_test.php" width="957" height="337" frameBorder="1" style="border:2px solid green;" ></iframe>

子页面:

<script>
$(document).ready(function()
{
    $("#link1").click(function()
    {
        alert("#link1 clicked...");
    });
});
</script>

<div id="link1">
    <a href="#">Link 1</a><br />
</div>

这适用于所有桌面浏览器,但不适用于Chrome for Android(2013年7月22日版)默认Android浏览器,iPad或iPhone。

在子页面中,我尝试了这两种形式,但都不起作用:

    $(document).on('click', '#link1', function()
    {
        alert("on click activated for link1");
    });

    $("#link1").click(function()
    {
        alert("#link1 clicked...");
    });

作为补充说明,选择器很好。我可以做一些事情,比如通过jQuery更改文本属性和类似的东西,它工作正常。我无法调用点击事件。

任何提示或指示?

谢谢!

3 个答案:

答案 0 :(得分:1)

Chrome不允许访问iframe的内容。即使内容具有相同的来源。

您应该使用postMessage在帧之间进行通信。

也许这会有所帮助: cross-window-messaging-with-postmessage

答案 1 :(得分:0)

我的答案是基于ios,因为这是我所有的,但对于android可能是相同的。

点击事件在启用触摸的设备上的工作方式略有不同。没有鼠标,所以从技术上讲没有点击。 根据这篇文章 - http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html - 由于内存限制,单击事件仅从锚点和输入元素模拟和分派。任何其他元素都可以使用触摸事件,或者通过向原始html元素添加处理程序来手动初始化单击事件,例如,强制在div上单击事件:

$('div').each(function(){
    this.onclick = function() {}
});

现在点击将由div触发,因此可以被jQuery监听。


在你的情况下,你可以只将监听器改为锚元素:

$("#link1 a").click(function()
{
    alert("#link1 clicked...");
});

或者在div上使用触摸事件:

$(document).on('touchstart', '#link1', function()
{
    alert("on click activated for link1");
});

然后按这样触发:

$('#slider').contents().find("#link1").trigger('touchstart');

这是一个小小的实验,可能会有所帮助 - http://jsbin.com/ukalah/9/edit

答案 2 :(得分:0)

有两个jQuery实例被加载。一个在父级,一个在iframe内。事情在父母的实例上生成事件和处理孩子的事件之间的某个地方搞砸了。

如果你在不使用jQuery的事件引擎的情况下发送事件,它就可以工作:

$("#floating_play_button").click(function(){
    //$('#slider').contents().find("#link1").click(); // instead:
    var newEvent = document.createEvent('Event');
    newEvent.initEvent('click',true,true);
    $('#slider').contents().find("#link1").first()[0].dispatchEvent(newEvent);
});

但jQuery处理了很多东西,比如跨浏览器兼容性,我们不想错过。因此,只需确保您的事件由同一个jQuery实例创建和处理,它应该可以工作:

$("#floating_play_button").click(function(){
    //$('#slider').contents().find("#link1").click(); // instead:
    window.frames['slider'].$('#link1').click();
});

编辑1

我无法弄清楚究竟是什么中断,但我注意到它失败的浏览器没有实现Event构造函数。事件是使用document.createEvent创建的。所以我的猜测是,使用错误的document对象会导致某些引用丢失。如果有人可以深入解释,请做...