非法调用jQuery HTML5音频播放

时间:2021-03-02 17:11:25

Background

Basically, this code takes all of the audio tags on the page, and when one finishes it starts the next one in the DOM.

基本上,此代码获取页面上的所有音频标记,当一个完成时,它将启动DOM中的下一个。

The Issue

When fnPlay is called I receive an Illegal Invocation error.

当调用fnPlay时,我收到一个非法调用错误。

//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);
});

Now I am sure that the rest of the code is fine, because the following worked.

现在我确信其余的代码都没问题,因为以下工作正常。

//WORKS GREAT!
var lastAudio = null;
$('audio').each(function(index) {
    var lastAudioObj = $(this)[0];
    if (lastAudio != null) {
        lastAudio.bind("ended", function() {
            lastAudioObj.play(); 
        });
    }
    lastAudio = $(this);
});

Question

Can anybody explain why I couldn't store the play() function inside my variable fnPlay and call fnPlay(), but I could store the object and call the play() function on the object?

任何人都可以解释为什么我不能在我的变量fnPlay中存储play()函数并调用fnPlay(),但是我可以存储该对象并在对象上调用play()函数?

1 个解决方案

#1


2  

This is because of how the context of JavaScript functions work. The context (or this) inside a function is set when it's ran, not when it's set.

这是因为JavaScript函数的上下文如何工作。函数内部的上下文(或者这个)在运行时设置,而不是在设置时设置。

When you call lastAudioObj.play();, the play() function is called in the context of lastAudioObj. Inside play(), this is lastAudioObj, so everything works.

当您调用lastAudioObj.play();时,将在lastAudioObj的上下文中调用play()函数。在play()中,这是lastAudioObj,所以一切正常。

When you do fnPlay() however, it has no context. this inside the function will be null (or window). play() doesn't like that, so it throws an exception.

但是当你执行fnPlay()时,它没有上下文。函数内部将为null(或窗口)。 play()不喜欢这样,所以它会引发异常。

There are a few ways to fix this.

有几种方法可以解决这个问题。

One is to call the function with .call() to manually set the context.

一种是使用.call()调用该函数来手动设置上下文。

Set the variables like:

设置变量如:

var lastAudioObj = $(this)[0];
var fnPlay = lastAudioObj.play;

Then call:

然后打电话:

fnPlay.call(lastAudioObj);

You can also use .bind() to set the context when setting the variable.

您还可以使用.bind()在设置变量时设置上下文。

var lastAudioObj = $(this)[0];
var fnPlay = lastAudioObj.play.bind(lastAudioObj);

Then you can just call it like:

然后你就可以这样称呼它:

fnPlay();

#1


2  

This is because of how the context of JavaScript functions work. The context (or this) inside a function is set when it's ran, not when it's set.

这是因为JavaScript函数的上下文如何工作。函数内部的上下文(或者这个)在运行时设置,而不是在设置时设置。

When you call lastAudioObj.play();, the play() function is called in the context of lastAudioObj. Inside play(), this is lastAudioObj, so everything works.

当您调用lastAudioObj.play();时,将在lastAudioObj的上下文中调用play()函数。在play()中,这是lastAudioObj,所以一切正常。

When you do fnPlay() however, it has no context. this inside the function will be null (or window). play() doesn't like that, so it throws an exception.

但是当你执行fnPlay()时,它没有上下文。函数内部将为null(或窗口)。 play()不喜欢这样,所以它会引发异常。

There are a few ways to fix this.

有几种方法可以解决这个问题。

One is to call the function with .call() to manually set the context.

一种是使用.call()调用该函数来手动设置上下文。

Set the variables like:

设置变量如:

var lastAudioObj = $(this)[0];
var fnPlay = lastAudioObj.play;

Then call:

然后打电话:

fnPlay.call(lastAudioObj);

You can also use .bind() to set the context when setting the variable.

您还可以使用.bind()在设置变量时设置上下文。

var lastAudioObj = $(this)[0];
var fnPlay = lastAudioObj.play.bind(lastAudioObj);

Then you can just call it like:

然后你就可以这样称呼它:

fnPlay();