javascript中的变量范围 - 不被事件侦听器拾取

时间:2016-11-07 12:17:19

标签: javascript html css scope event-listener

我有一个问题,最初是一个实用的问题因为我想要一个包含视频的元素在视频播放时崩溃,我需要添加一个事件监听器,但由于它不起作用,我开始做一些测试和我不明白JavaScript如何访问变量。

好的,所以在我的项目中,我在iframe中有一个视频,如下所示:

HTML

    <p> ...some tex... 
<span id="clickable" class="link">click me to watch video</span>.<span><iframe  id="frame" class="rect" src="iframe.html" scrolling="no" marginwidth=0 marginheight=0></iframe></span>
 ...some more tex...</p>

iframe只有一个视频

IFRAME:

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <script type="text/javascript" src="jquery.js"></script>
    <script type="text/javascript" src="script2.js"></script>
    <link rel="stylesheet" type="text/css" href="styles.css">   
</head>
<body>
    <video id="myVid" width="350" height="200" >
       <source src="someVideo.mp4" type="video/mp4">
    </video>
</body>
</html> 

JavaScript就像这样:

$(document).ready(function(){


    $("#clickable").click(function(){

        var rect = $(this).next().find('.rect');

        if (rect.hasClass( "open" )){

            rect.removeClass("open");

            rect.contents().find("#myVid").get(0).pause();

        } else {

        rect.addClass("open");

        rect.contents().find("#myVid").get(0).play();
        }
     });

和css

.rect{
    float: left;
    height: 0px;
    width: 350px;
    display: block;
    margin: 0px;
    padding: 0px;
    opacity: 0;

    transition-property: all;
    transition-duration: 2s;
    transition-timing-function: ease-in-out;
}

.open {
    height: 200px;
    width: 350px;
    opacity: 1;
    padding-bottom: 10px;
    padding-top: 10px;
}

好的,这样可行。当我点击链接“clickable”时,javascript将“open”类添加到iframe,使得高度从0到200px,因此视频幻灯片打开。然后,当我再次点击视频关闭。 所以我试图做的是添加一个功能,当视频完成此功能时,该功能也会关闭视频:

    $('#myVid').on('ended',function(){
         rect.removeClass("open");
         alert('finished');
    });

这是问题开始的时候。问题是在哪里放置这个功能。如果我把它放在“可点击”的功能之外,它会在视频结束时触发(警报框显示),但视频没有崩溃,所以我认为它无法到达视频。然后我像这样修改了事件监听器:

  $('#rickieVid').on('ended',function(){

      if ($(rect).hasClass("open")){alert('has class')}
      else {alert('has not');}   
    });

警告框显示:“没有”。所以这真让我感到困惑,因为“open”这个类显然加入了“clickable”事件。有人能帮助我理解为什么这不起作用?非常感谢 P

===================================编辑=========== =======================

我或许应该提一下,我确实尝试将“rect”变量置于“可点击”功能之外,使其成为全局变量,如下所示:

$(document).ready(function(){

    var rect;

    $("#rickie").click(function(){

        rect = $(this).next().find('.rect');

etc...

然后修改我的函数以访问全局变量,如下所示:

$('#rickieVid').on('ended',function(){

if (rect.hasClass("open")){alert('has class')}

else {alert('has not');}   

});

这仍然不起作用,因为它出现了这个错误:

TypeError: undefined is not an object (evaluating 'rect.hasClass')

1 个答案:

答案 0 :(得分:1)

您可以通过将load事件处理程序附加到iframe jquery对象来实现此目的,因为主文档已准备好,即使iframe源正在加载,有时视频控件也需要时间加载。

无论如何,在这种情况下,您需要设置全局播放器对象,并将结束的事件处理程序附加到播放器。

要使用的jQuery代码:

$(document).ready(function(){

        var frame = $("#frame");
        var player;

        frame.bind("load", function () {
            player = $(this).contents().find("#myVid");
            player.on('ended', function () {
                frame.removeClass("open");
                alert('finished');
            });
        });

        $("#clickable").click(function(){
            if (frame.hasClass("open")) 
            {
                frame.removeClass("open");
                player[0].pause();
            } 
            else {
                frame.addClass("open");
                player[0].play();
            }
        });
    });

有一点需要注意。如果iframe源是跨域url,则.contents()将引发安全性错误。这仅适用于iframe源页面位于同一域中的情况。