javascript 中的变量范围 - 未被事件侦听器拾取
Variable scope in javascript - not being picked up by 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;
}
好的,这样就可以了。当我单击 link "clickable" 时,javascript 将 class "open" 添加到 iframe,使高度从 0 变为 200px,因此视频幻灯片打开。然后,当我再次单击时,视频关闭。
所以我想做的是添加一个功能,当视频完成此功能时,该功能也会关闭视频:
$('#myVid').on('ended',function(){
rect.removeClass("open");
alert('finished');
});
这是问题开始的时候。问题是把这个功能放在哪里。如果我将它放在 "clickable" 函数之外,它会在视频结束时触发(出现警告框),但视频不会崩溃,所以我断定它无法到达视频。然后我像这样修改了事件监听器:
$('#rickieVid').on('ended',function(){
if ($(rect).hasClass("open")){alert('has class')}
else {alert('has not');}
});
并且警告框显示:"has not"。所以这真的让我感到困惑,因为 class "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 源页面位于同一域内时有效。
我有一个问题,一开始是一个实用的问题,因为我想要一个包含视频的元素在视频结束时折叠,为此我需要添加一个事件侦听器,但由于它不起作用,我开始做一些正在测试,我不明白 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;
}
好的,这样就可以了。当我单击 link "clickable" 时,javascript 将 class "open" 添加到 iframe,使高度从 0 变为 200px,因此视频幻灯片打开。然后,当我再次单击时,视频关闭。 所以我想做的是添加一个功能,当视频完成此功能时,该功能也会关闭视频:
$('#myVid').on('ended',function(){
rect.removeClass("open");
alert('finished');
});
这是问题开始的时候。问题是把这个功能放在哪里。如果我将它放在 "clickable" 函数之外,它会在视频结束时触发(出现警告框),但视频不会崩溃,所以我断定它无法到达视频。然后我像这样修改了事件监听器:
$('#rickieVid').on('ended',function(){
if ($(rect).hasClass("open")){alert('has class')}
else {alert('has not');}
});
并且警告框显示:"has not"。所以这真的让我感到困惑,因为 class "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 源页面位于同一域内时有效。