隐藏iframe时如何暂停YouTube播放器?


86

我有一个隐藏的div,其中包含一个YouTube视频<iframe>。当用户单击链接时,此div变为可见,然后用户应该可以播放视频。

当用户关闭面板时,视频应停止播放。我该如何实现?

码:

<!-- link to open popupVid -->
<p><a href="javascript:;" onClick="document.getElementById('popupVid').style.display='';">Click here</a> to see my presenting showreel, to give you an idea of my style - usually described as authoritative, affable and and engaging.</p>

<!-- popup and contents -->
<div id="popupVid" style="position:absolute;left:0px;top:87px;width:500px;background-color:#D05F27;height:auto;display:none;z-index:200;">

  <iframe width="500" height="315" src="http://www.youtube.com/embed/T39hYJAwR40" frameborder="0" allowfullscreen></iframe>

  <br /><br /> 
  <a href="javascript:;" onClick="document.getElementById('popupVid').style.display='none';">
  close
  </a>
</div><!--end of popupVid -->

我不知道,但你可能必须找到一个方法来阻止视频或从DIV删除该视频,而不是仅仅把它隐藏..
aniri

您应该接受答案。
snymkpr

Answers:


188

实现此行为的最简单方法是在需要时调用pauseVideoplayVideo方法。受到先前答案的启发,我编写了一个无插件功能来实现所需的行为。

唯一的调整:

  • 我增加了一个功能 toggleVideo
  • 我已添加?enablejsapi=1到YouTube的URL,以启用该功能

演示:http : //jsfiddle.net/ZcMkt/
代码:

<script>
function toggleVideo(state) {
    // if state == 'hide', hide. Else: show video
    var div = document.getElementById("popupVid");
    var iframe = div.getElementsByTagName("iframe")[0].contentWindow;
    div.style.display = state == 'hide' ? 'none' : '';
    func = state == 'hide' ? 'pauseVideo' : 'playVideo';
    iframe.postMessage('{"event":"command","func":"' + func + '","args":""}', '*');
}
</script>

<p><a href="javascript:;" onClick="toggleVideo();">Click here</a> to see my presenting showreel, to give you an idea of my style - usually described as authoritative, affable and and engaging.</p>

<!-- popup and contents -->
<div id="popupVid" style="position:absolute;left:0px;top:87px;width:500px;background-color:#D05F27;height:auto;display:none;z-index:200;">
   <iframe width="500" height="315" src="http://www.youtube.com/embed/T39hYJAwR40?enablejsapi=1" frameborder="0" allowfullscreen></iframe>
   <br /><br />
   <a href="javascript:;" onClick="toggleVideo('hide');">close</a>

1
是的,如果这可行,则肯定需要绿色复选框。我也采用了这种解决方案-很棒的东西,我将这些视频帧放在jQueryUI手风琴中,因此我需要将其附加到每个触发事件上。
jeffkee 2012年

只是想指出,可悲的是,YouTube的API确实使您对通过postMessage发送的消息使用双引号。例如,您不能切换为使用外部双引号和内部单引号。
乔丹

1
@Jordan完全有道理,因为该消息应为JSON。根据定义,JSON使用双引号引起来的键和值。
Rob W

2
如果有人感兴趣,我会更新代码,以在单击bootstrap 3模态上的“关闭”按钮时停止播放视频。$(“#MyModal-close”).click(function(){var div = document.getElementById(“ MyModal-videoWrapper”); var iframe = div.getElementsByTagName(“ iframe”)[0] .contentWindow; iframe.postMessage ('{“ event”:“ command”,“ func”:“'+'pauseVideo'+'”,“ args”:“”}','*');});
赖安·沃尔顿

10
请注意,您必须?enablejsapi=1像这样将其添加到iframe嵌入网址中:<iframe class="embed-responsive-item" src="//www.youtube.com/embed/WIZUeIDFALw?html5=1&enablejsapi=1" allowfullscreen></iframe>否则将无法正常工作:)
dineth 2014年

23

这是jQuery对RobW的回答,用于在模式窗口中隐藏/暂停iframe:

    function toggleVideo(state) {
        if(state == 'hide'){
            $('#video-div').modal('hide');
            document.getElementById('video-iframe'+id).contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}', '*');
        }
        else {
            $('#video-div').modal('show');
            document.getElementById('video-iframe'+id).contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}', '*');
        }
    }

所引用的html元素是模态div本身(#video-div)调用show / hide方法,以及iframe(#video-iframe),其视频网址为src =“”,后缀enablejsapi = 1 ?这样就可以通过编程方式控制播放器(例如

有关html的更多信息,请参见RobW的答案。


5
哪些增强的可读性正在改变?以if / else为条件,但感谢您开始参与此工作。我只是觉得我有一些有效的补充就是全部。
DrewT

15

这是一个简单的jQuery代码段,可根据RobW和DrewT的答案暂停页面上的所有视频:

jQuery("iframe").each(function() {
  jQuery(this)[0].contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}', '*')
});

如果您不想使用jQuery,则取消引用jQuery对象后,“每个”函数中的代码相同。即node.contentWindow。...
mattdlockyer

再次显示视频时,如何将其反转以再次播放?
卡尔·帕普沃思

只需将“ pauseVideo”替换为“ playVideo”即可。范例:jsfiddle.net/ora2kqzq/1
Quartarian

这不再起作用...即使我尝试{"event":"command","func":"playVideo","args":[],"id":1,"channel":"widget"}之后{"event":"listening","id":1,"channel":"widget"},YT.Player iframe api也将其发布到youtube嵌入中。
NoBugs

9

嘿,一种简单的方法是将视频的src设置为空,以便在隐藏视频时将其消失,然后在单击打开视频的链接时将src设置回所需的视频..只需将一个ID设置为youtube iframe并使用该ID调用src函数,如下所示:

<script type="text/javascript">
function deleteVideo()
{
document.getElementById('VideoPlayer').src='';
}

function LoadVideo()
{
document.getElementById('VideoPlayer').src='http://www.youtube.com/embed/WHAT,EVER,YOUTUBE,VIDEO,YOU,WHANT';
}
</script>

<body>

<p onclick="LoadVideo()">LOAD VIDEO</P>
<p onclick="deleteVideo()">CLOSE</P>

<iframe id="VideoPlayer" width="853" height="480" src="http://www.youtube.com/WHAT,EVER,YOUTUBE,VIDEO,YOU,HAVE" frameborder="0" allowfullscreen></iframe>

</boby>

4
警告:修改到iframesrc与JavaScript会不经意推入window.history,造成后退按钮的问题。
约旦·阿塞诺

谢谢乔丹!我自己才开始使用此答案,却不知道这种行为。最好现在知道,以后再说:)
MMachinegun 2014年

向尝试使用此方法的任何人发出警告:如果您使用此方法在包含YouTube iframe嵌入的div之间进行切换,则可能会导致非常明显的延迟。小心。
穆罕默德·阿卜杜勒·拉希姆

6

由于您需要先设置?enablejsapi=trueiframe的src才能使用其他答案中提到的playVideo/pauseVideo命令,因此通过Javascript以编程方式添加此命令可能会很有用(尤其是例如,如果您希望此行为适用于其他人嵌入的视频,刚刚剪切并粘贴YouTube嵌入代码的用户)。在这种情况下,如下所示可能会有用:

function initVideos() {

  // Find all video iframes on the page:
  var iframes = $(".video").find("iframe");

  // For each of them:
  for (var i = 0; i < iframes.length; i++) {
    // If "enablejsapi" is not set on the iframe's src, set it:
    if (iframes[i].src.indexOf("enablejsapi") === -1) {
      // ...check whether there is already a query string or not:
      // (ie. whether to prefix "enablejsapi" with a "?" or an "&")
      var prefix = (iframes[i].src.indexOf("?") === -1) ? "?" : "&amp;";
      iframes[i].src += prefix + "enablejsapi=true";
    }
  }
}

...如果您对此进行调用,document.ready则div中所有具有“视频”类的iframe都将enablejsapi=true添加到其源代码中,从而可以在它们上使用playVideo / pauseVideo命令。

(注:此示例在设置的那一行中使用jQuery var iframes,但是如果您不使用jQuery,则一般方法也应适用于纯Javascript)。



4

RobW的方式对我来说很棒。对于使用jQuery的人,这是我最终使用的简化版本:

var iframe = $(video_player_div).find('iframe');

var src = $(iframe).attr('src');      

$(iframe).attr('src', '').attr('src', src);

在此示例中,“ video_player”是包含iframe的父div。


4

我想分享一个使用jQuery提出的解决方案,如果您在一个页面上嵌入了多个YouTube视频,该解决方案就可以使用。就我而言,我为每个视频定义了一个模式弹出窗口,如下所示:

<div id="videoModalXX">
...
    <button onclick="stopVideo(videoID);" type="button" class="close"></button>
    ...
    <iframe width="90%" height="400" src="//www.youtube-nocookie.com/embed/video_id?rel=0&enablejsapi=1&version=3" frameborder="0" allowfullscreen></iframe>
...
</div>

在这种情况下,videoModalXX表示视频的唯一ID。然后,以下功能停止视频:

function stopVideo(id)
{
    $("#videoModal" + id + " iframe")[0].contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}', '*');
}

我喜欢这种方法,因为这样可以使视频暂停播放,以防您想返回并稍后继续观看。它对我来说效果很好,因为它正在寻找具有特定ID的视频模式内的iframe。不需要特殊的YouTube元素ID。希望有人也会发现它也有用。


无需大量代码,效果很好。我在页面上有多个YT视频,只是显示了YT拇指,需要停止/暂停解决方案。通过将pauseVideo更改为playVideo,我可以在视频扩展到全列宽度时开始播放视频
WebDude0482

2

只需删除iframe的src

$('button.close').click(function(){
    $('iframe').attr('src','');;
});

但是当用户单击打开时,他可能想继续玩。
科达·张

兄弟,再次onclick通过jquery添加src,它将起作用
rakesh kejriwal

1

Rob W的回答帮助我弄清楚了隐藏滑块时如何在iframe上暂停视频。但是,我需要进行一些修改才能使它起作用。这是我的html的代码段:

<div class="flexslider" style="height: 330px;">
  <ul class="slides">
    <li class="post-64"><img src="http://localhost/.../Banner_image.jpg"></li>
    <li class="post-65><img  src="http://localhost/..../banner_image_2.jpg "></li>
    <li class="post-67 ">
        <div class="fluid-width-video-wrapper ">
            <iframe frameborder="0 " allowfullscreen=" " src="//www.youtube.com/embed/video-ID?enablejsapi=1 " id="fitvid831673 "></iframe>
        </div>
    </li>
  </ul>
</div>

观察到这在localhost上有效,并且正如Rob W提到的“ enablejsapi = 1,在视频URL的末尾添加了 ”。

以下是我的JS文件:

jQuery(document).ready(function($){
    jQuery(".flexslider").click(function (e) {
        setTimeout(checkiframe, 1000); //Checking the DOM if iframe is hidden. Timer is used to wait for 1 second before checking the DOM if its updated

    });
});

function checkiframe(){
    var iframe_flag =jQuery("iframe").is(":visible"); //Flagging if iFrame is Visible
    console.log(iframe_flag);
    var tooglePlay=0;
    if (iframe_flag) {                                //If Visible then AutoPlaying the Video
        tooglePlay=1;
        setTimeout(toogleVideo, 1000);                //Also using timeout here
    }
    if (!iframe_flag) {     
        tooglePlay =0;
        setTimeout(toogleVideo('hide'), 1000);  
    }   
}

function toogleVideo(state) {
    var div = document.getElementsByTagName("iframe")[0].contentWindow;
    func = state == 'hide' ? 'pauseVideo' : 'playVideo';
    div.postMessage('{"event":"command","func":"' + func + '","args":""}', '*');
}; 

另外,作为一个更简单的示例,请在 JSFiddle检查


1

这种方法需要jQuery。首先,选择您的iframe:

var yourIframe = $('iframe#yourId');
//yourId or something to select your iframe.

现在,您选择此iframe的播放/暂停按钮,然后单击它

$('button.ytp-play-button.ytp-button', yourIframe).click();

希望对您有帮助。


0

RobW在这里和其他地方的答案很有帮助,但是我发现我的需求要简单得多。我已经在其他地方回答了,但也许在这里也很有用。

我有一种方法,可以形成要在UIWebView中加载的HTML字符串:

NSString *urlString = [NSString stringWithFormat:@"https://www.youtube.com/embed/%@",videoID];

preparedHTML = [NSString stringWithFormat:@"<html><body style='background:none; text-align:center;'><script type='text/javascript' src='http://www.youtube.com/iframe_api'></script><script type='text/javascript'>var player; function onYouTubeIframeAPIReady(){player=new YT.Player('player')}</script><iframe id='player' class='youtube-player' type='text/html' width='%f' height='%f' src='%@?rel=0&showinfo=0&enablejsapi=1' style='text-align:center; border: 6px solid; border-radius:5px; background-color:transparent;' rel=nofollow allowfullscreen></iframe></body></html>", 628.0f, 352.0f, urlString];

您可以忽略prepareHTML字符串中的样式设置。重要方面是:

  • 使用API​​创建“ YT.player”对象。有一次,我只将视频包含在iFrame标记中,这使我以后无法使用JS引用“玩家”对象。
  • 我在网上看到了一些示例,其中第一个脚本标签(带有iframe_api src标签的脚本标签)被省略了,但是我确实需要这样做才能使它工作。
  • 在API脚本的开头创建“ player”变量。我还看到了一些省略了该行的示例。
  • 将ID标记添加到要在API脚本中引用的iFrame。我差点忘了那部分。
  • 在iFrame src标记的末尾添加“ enablejsapi = 1”。这让我挂了一段时间,因为我最初将它作为iFrame标记的属性使用,该标记对我不起作用/不起作用。

当我需要暂停视频时,只需运行以下命令:

[webView stringByEvaluatingJavaScriptFromString:@"player.pauseVideo();"];

希望有帮助!


如果您想知道为什么不投票,那是因为那不是JavaScript,因此对于OP的用例来说是没有用的,OP的用例是iframe引用的是YouTube嵌入网址,而不是iOS应用。
Vroo 2015年

@Vroo是的,我明白了。只是想在这里留下这个答案,以防其他iOS人士像我一样来到这里找到这个问题。
布赖恩

0

YT播放器对我来说效果很好

 createPlayer(): void {
  return new window['YT'].Player(this.youtube.playerId, {
  height: this.youtube.playerHeight,
  width: this.youtube.playerWidth,
  playerVars: {
    rel: 0,
    showinfo: 0
  }
});
}

this.youtube.player.pauseVideo();


0

更为简洁,优雅和安全的答案:在视频URL的末尾添加“?enablejsapi = 1”,然后构造并字符串化表示暂停命令的普通对象:

const YouTube_pause_video_command_JSON = JSON.stringify(Object.create(null, {
    "event": {
        "value": "command",
        "enumerable": true
    },
    "func": {
        "value": "pauseVideo",
        "enumerable": true
    }
}));

使用该Window.postMessage方法将结果JSON字符串发送到嵌入式视频文档:

// |iframe_element| is defined elsewhere.
const video_URL = iframe_element.getAttributeNS(null, "src");
iframe_element.contentWindow.postMessage(YouTube_pause_video_command_JSON, video_URL);

确保为Window.postMessage方法的targetOrigin参数指定视频URL,以确保您的消息不会发送给任何意外的收件人。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.