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

javascript中的变量范围-事件侦听器未拾取,javascript,html,css,scope,event-listener,Javascript,Html,Css,Scope,Event Listener,我有一个问题是从一个实际的问题开始的,因为我想要一个包含视频的元素在视频结束时崩溃,为此我需要添加一个事件侦听器,但由于它不起作用,我开始做一些测试,我不明白JavaScript是如何访问变量的 好的,在我的项目中,我在iframe中有一个视频,如下所示: $(document).ready(function(){ var rect; $("#rickie").click(function(){ rect = $(this).next().find('.re

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

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

$(document).ready(function(){

    var rect;

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

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

etc...
html

还有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”变量置于“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')

当主文档准备就绪时,可以通过将加载事件处理程序附加到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源页面位于同一域内时有效。

您的变量
rect
仅在click handler函数中可用。如果您在
外部声明
rect
。单击
函数,rect将是全局的,因此您可以在其他函数(如上一个函数)中使用它。好的,我如何使rect成为全局的。我尝试将rect移到页面顶部的函数外部,然后将其移到内部,如so$(document).ready(function(){var rect;$(“#rickie”)。单击(function(){rect=$(this).next().find('.rect'));您需要在事件处理程序中再次获得rect选择器。但所有这些都非常复杂,没有任何原因。为什么要使用iFrame,只需使用隐藏的div,在一个函数中定义所有处理程序,让它们可以访问相同的变量范围,您就完成了。下面是一个示例:感谢您的回复。这是r iframe。如果我不使用它们,随着div越来越高,视频不断按比例改变纵横比,这不是我想要的外观。iframe意味着随着高度的增加,视频已经是全宽了。但我同意你的观点,我知道这可以做得更简单。我只是在自学,所以我正在努力让事情正常进行首先,我会教自己优雅地做。谢谢纳西尔,这太棒了。如果你想看一看,我问了一个相关的问题。非常欢迎。我已经在你的其他问题的答案中添加了。请检查它是否有帮助。
TypeError: undefined is not an object (evaluating 'rect.hasClass')
$(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();
            }
        });
    });