基本上,这段代码会获取页面上的所有音频标签,当一个完成后,它会启动DOM中的下一个。
调用fnPlay
时,我收到Illegal Invocation
错误。
//THIS CODE FAILS
var lastAudio = null;
$('audio').each(function(index) {
var fnPlay = $(this)[0].play;
if (lastAudio != null) {
lastAudio.bind("ended", function() {
fnPlay();
});
}
lastAudio = $(this);
});
现在我肯定其余代码没问题,因为以下方法有效。
//WORKS GREAT!
var lastAudio = null;
$('audio').each(function(index) {
var lastAudioObj = $(this)[0];
if (lastAudio != null) {
lastAudio.bind("ended", function() {
lastAudioObj.play();
});
}
lastAudio = $(this);
});
任何人都可以解释为什么我无法将play()
函数存储在我的变量fnPlay
中并调用fnPlay()
,但我可以存储该对象并调用play()
函数对象?
答案 0 :(得分:2)
这是因为JavaScript函数的上下文如何工作。函数内部的上下文(或this
)在运行时设置,而不是在设置时设置。
当您致电lastAudioObj.play();
时,play()
功能会在lastAudioObj
的上下文中调用。在play()
内,this
是lastAudioObj
,所以一切正常。
但是,当你执行fnPlay()
时,它没有上下文。函数内的this
将为null
(或window
)。 play()
不喜欢这样,所以它会引发异常。
有几种方法可以解决这个问题。
一种是用.call()
调用函数来手动设置上下文。
设置变量如:
var lastAudioObj = $(this)[0];
var fnPlay = lastAudioObj.play;
然后致电:
fnPlay.call(lastAudioObj);
您还可以使用.bind()
在设置变量时设置上下文。
var lastAudioObj = $(this)[0];
var fnPlay = lastAudioObj.play.bind(lastAudioObj);
然后你可以这样称呼它:
fnPlay();