【问题标题】:Click event not triggering over youtube iframe in mobile safari点击事件未在移动 Safari 中通过 youtube iframe 触发
【发布时间】:2013-10-27 21:35:55
【问题描述】:

我想在 youtube iframe 视频上方放置交互控件,我只需添加 wmode=opaque 作为参数,然后将元素绝对定位在 iframe 上方,就可以正常工作。

我的问题是在移动 Safari 上 - 控件首先可以正常工作,但是当我从全屏视频返回时,它们都被禁用了。但它在桌面上运行良好。

HTML 基本上是:

<iframe src="http://www.youtube.com/embed/[ID]?wmode=opaque"></iframe>
<button id="btn">Click me</button>

然后按钮绝对位于 iframe 上方。

如需演示,请使用您的移动浏览器访问此小提琴:http://jsfiddle.net/SwGH5/embedded/result/

您会看到该按钮在单击时会发出警报。现在,播放视频并单击“完成”。然后尝试再次点击按钮...

如果电影是使用&lt;video&gt; 标签嵌入的,我可以监听全屏结束事件并做一些事情,但现在我被卡住了......

这是小提琴:http://jsfiddle.net/SwGH5

【问题讨论】:

  • 我离开了我的开发计算机 - 但我有一个想法。我之前也遇到过类似的问题(iOS 上的绝对位置、iFrame 等)。我们发现的最奇怪的解决方案是向可点击元素(给你的按钮)添加 CSS 过渡。我们添加了一个什么都不做的过渡(比如旋转 0)。但是,我们并没有通过 youtube iFrame 执行此操作。如果我回到我的开发机器并且它仍然打开,我会看看它。
  • 我不会说他们被禁用。他们只是不再开火了。如果您检查按钮,您可以看到事件已附加并且按钮未禁用。看起来像一个 iOS 错误。
  • 我过去也遇到过类似的问题。看起来,因为移动 safari 中的所有视频都是本地处理的,所以本地叠加层具有“吃掉”触摸事件而不是将它们传递给下面的 DOM 的不幸后果。我还没有找到解决方法。
  • 刚刚在我的 iPhone 上试了一下,同样的问题。我很好奇是否有人知道解决方案。
  • 我确定您已经尝试更改 iframe 上的 z-index。当您使用旧的 youtube 嵌入代码 - &lt;object width="420" height="315"&gt;&lt;param name="movie" value="//www.youtube.com/v/9u_hp7zPir0?version=3&amp;amp;hl=en_US&amp;amp;rel=0"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="//www.youtube.com/v/9u_hp7zPir0?version=3&amp;amp;hl=en_US&amp;amp;rel=0" type="application/x-shockwave-flash" width="420" height="315" allowscriptaccess="always" allowfullscreen="true"&gt;&lt;/embed&gt;&lt;/object&gt; 时会怎样?运气好吗?

标签: javascript jquery mobile iframe youtube


【解决方案1】:

所以我玩了一下iframe API 并找到了解决方案。这有点骇人听闻......但不是真的。当用户点击视频进行播放时,document.activeElement 成为 iframe。当用户单击“完成”按钮时,document.activeElement === document.body.因此,当视频开始播放时,我们会定期检查活动元素是否返回正文。那时,我找到的唯一解决方案是重绘 iframe。在示例中,我销毁()视频并使用 iframe API 重新创建它。我还尝试克隆 iframe 并将其替换为成功(我将代码留在那里以便您可以看到):

http://jsfiddle.net/ryanwheale/SwGH5/105/

这不是最好的解决方案,但它确实有效。此外,为了解释 [我认为] 正在发生的事情 - iOS 劫持任何视频内容(Safari 或 Chrome)并使用本机视频播放器播放。如果您愿意,任何类型的操作系统功能都会在浏览器“上方”发生 - 高于任何 z-index ......完全在浏览器之外。当用户单击“完成”时,本地播放器会缩小,就好像它正在将自己重新植入页面上一样。我最好的猜测是,本地播放器仍然在浏览器“上方”闲逛......因此无法访问它下面的任何东西。按钮似乎在顶部的事实只是一个反常现象......因为缺乏更好的描述。

【讨论】:

  • 谢谢!这对我帮助很大。
  • 在 iPhone 4 (iOS 7.1.2) 上测试.. document.activeElement.tagName 显然一直返回“BODY”,这让我的脚本认为用户点击了“完成”。
  • 更新:啊,这里的区别可能是我的视频设置为自动播放,适用于 iOS 7,但我想这不会将焦点放在 iframe 上。所以也许我可以在视频开始播放时以编程方式设置焦点,然后理论上它应该仍然切换到 BODY,当用户点击“完成”时?我试试看..
【解决方案2】:

编辑:Ryan Wheale 的解决方案是解决此问题的更好方法,并且在大多数情况下都有效。

来自 Apple 的文档:

在基于 iOS 的小屏幕设备(例如 iPhone 和 iPod touch)上,视频始终以全屏模式播放,因此无法将画布叠加在正在播放的视频上。在 iPad 等具有较大屏幕的 iOS 设备上,您可以将画布图形叠加在播放视频上,就像在桌面上一样。

播放的视频”也是如此。 This article 明确表示这是不可能的。

解决方法:

您可以在webkitfullscreenchange 上分离并重新附加 iframe 元素。但它不适用于外国iframe。浏览器不允许您操作 iframe DOM bec。跨域策略。即使是这样,您也只能隐藏视频叠加层才能到达您的按钮。

因此,唯一的解决方案是通过 YouTube iFrame API 观察 YT.PlayerState.ENDED 状态,然后销毁并重新创建播放器。不过不用担心它会流畅播放。

window.onYouTubeIframeAPIReady = function () {
    var video = {
        player: null,
        create: function () {
            // first destroy if we already have the player
            if (video.player) { video.player.destroy(); }
            // create the player
            video.player = new YT.Player('ytp', {
                videoId: '9u_hp7zPir0',
                width: '620',
                height: '290',
                events: {
                    'onStateChange': video.onStateChange
                }
            });
        },
        onStateChange: function (event) {
            // YT.PlayerState.ENDED » exiting full screen
            if (event.data === 0) { video.create(); }
        }
    };
    video.create();
};

这里是working fiddle

【讨论】:

  • 这是一个非常好的解决方案,您还可以保存视频的第二个,并在重新创建播放器时使用它,以提供暂停的感觉。
  • “end”事件仅在视频结束时触发。很多时候,用户会在视频结束之前点击“完成”......即使他们观看了整个视频并在视频实际结束前 1 秒点击“完成”。每当用户单击“完成”按钮(退出全屏)时,我的解决方案都会处理。
  • 你是对的。另外,我重新检查了文档,实际上状态 2 是 PAUSE,0 是 END。覆盖按钮以这种方式工作,但它会在暂停时破坏视频。我认为您的解决方案更好。
【解决方案3】:

如果您无法让它与常规 iframe 一起使用,您可能需要考虑使用 mediaelement.js - 它可以将 Youtube API 包装在 HTML5 媒体 API 包装器中。这在 ios 上的 safari 上运行良好 - 试试 mediaelementjs.com 上的Youtube example

您需要做的就是添加 mejs js/css 并将您的 youtube 视频作为源代码放入您的视频标签中,以下是取自 mediaelementjs.com 的一些示例标记:

<script src="jquery.js"></script>
<script src="mediaelement-and-player.min.js"></script>
<link rel="stylesheet" href="mediaelementplayer.css" />
<video width="640" height="360" id="player1" preload="none">
    <source type="video/youtube" src="http://www.youtube.com/watch?v=nOEw9iiopwI" />
</video>

然后像这样启动播放器:

jQuery(document).ready(function($) {
    $('#player1').mediaelementplayer();
});

如果你想在 mejs 播放器上添加你的按钮,它可以正常工作,只需将 z-index 设置得足够高。如果您想要一个常规的播放按钮,您还可以考虑为 mejs 附带的现有按钮设置样式。

【讨论】:

    【解决方案4】:

    comments from @CullenJ's answer,可能是由于iOS device browsers not triggering the click event on iframe elements中的一些问题。在这种情况下,您必须更改:

    document.getElementById('btn').onclick = function() {
        alert('clicked');
    }
    

    对于这样的事情(as answered by @smnh):

    $('#btn').on('click tap touchstart', function() {
        alert('clicked');
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-31
      • 2013-12-28
      • 2012-02-14
      • 2015-01-28
      相关资源
      最近更新 更多