变量范围未被事件侦听器拾取

Variable scope in not being picked up by event listener

本文关键字:侦听器 事件 范围 变量      更新时间:2023-09-26

我有一个问题,开始作为一个实际的,因为我想要一个元素包含视频崩溃时,视频结束,为此我需要添加一个事件监听器,但由于它不工作,我开始做一些测试,我不明白是如何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');}   
    });

警告框显示:"has not"。所以这真的让我很困惑,因为类"open"显然是与"clickable"事件一起添加的。有人能帮我理解为什么这不起作用吗?非常感谢P

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

我也许应该提到,我确实试图把"rect"变量外的"clickable"函数使其全局,像这样:

$(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')

您可以通过将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源页面在同一域中