【问题标题】:JQuery click event not working for iframe, in mobile browserjQuery点击事件不适用于iframe,在移动浏览器中
【发布时间】:2013-08-09 16:53:52
【问题描述】:

这是我遇到的一个非常具体的问题,但我不知道如何调试它,甚至不知道它是否可以在移动浏览器上运行。

我有 2 个页面(都在同一个域上,所以我对跨域安全策略没有问题),一个位于另一个内部的 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>

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

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

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

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

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

任何提示或指示?

谢谢!

【问题讨论】:

  • touchpunch.furf.com 并阅读第一段,了解他们制作该脚本的原因。对你来说可能是同样的问题。

标签: jquery mobile mobile-browser


【解决方案1】:

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

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

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

【讨论】:

  • 我猜测 find 中使用的 'link2' 类(在父文件中)是一个错字。
【解决方案2】:

我的答案基于 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

【讨论】:

  • touchstart 事件未在移动设备中从父框架触发。
  • 您的意思是当您以编程方式触发它时,还是父框架中的元素没有捕获事件?可以提供样品吗?
  • 基本上就是使用上面的代码。在父框架中,我有一个 div,单击它时会尝试调用 $('#slider').contents().find("#link1").trigger('touchstart');子框架,但没有任何反应。选择器似乎没问题,因为我可以做 $('#slider').contents().find("#link1").css('border', '2px solid red');
  • 我在 Android 手机上运行了您的示例,我遇到的问题与我最初想象的完全不同。刚刚添加了一个新答案...希望对您有所帮助。
【解决方案3】:

有两个 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 对象会丢失一些参考。如果有人可以深入解释,请做...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-20
    • 1970-01-01
    • 2015-03-14
    • 2015-10-31
    • 2020-02-22
    • 1970-01-01
    • 2023-03-13
    相关资源
    最近更新 更多