简体   繁体   English

HTML 事件给出“未捕获的类型错误:X 不是函数”

[英]HTML event gives 'Uncaught TypeError: X is not a function'

I had a problem.我有问题。 Here's the very simplified code:这是非常简化的代码:

<!DOCTYPE html>
<html>
<head>
    <script>
        function ended(e) {
            alert("Ended");
        }
        
        function paused(e) {
            alert("Paused");
        }

        function played(e) {
            alert("Played");
        }       
    </script>
</head>
<body>
    <div>
        <video src="videoFile.mp4" controls onended="ended(event)" onpause="paused()" onplay="played(event)" >
        </video>
    </div>
</body>
</html>

Any time I paused, played, or ended the video, I would get the error:每当我暂停、播放或结束视频时,都会收到错误消息:

Uncaught TypeError: played is not a function
    at HTMLVideoElement.onplay

or the same but with paused or ended instead of played , and onpause and onended instead of onplay .或相同但pausedended而不是played ,以及onpauseonended而不是onplay

I've already solved it, so I put the answer below, for those who encounter a similar problem.我已经解决了,所以我把答案放在下面,给遇到类似问题的人。

It turns out that the HTMLMediaElement , which the <video> element is, contains some boolean properties: ended , paused and played .事实证明, <video>元素所在的HTMLMediaElement包含一些布尔属性: endedpausedplayed

And it turns out that when the browser (Chrome, maybe others) calls the event, it gets the value of those properties (which is true or false ), instead of using my already defined functions.事实证明,当浏览器(Chrome,也可能是其他人)调用该事件时,它会获取这些属性的值( truefalse ),而不是使用我已经定义的函数。 So then it tries to call true(event) or false(event) , and since true and false are not functions, it gives the error that played is not a function .然后它尝试调用true(event)false(event) ,并且由于truefalse不是函数,因此它给出了played is not a function的错误played is not a function

So the answer is, make sure that the function names you use for events do not match properties within the relevant HTMLElement that is firing the event, and then you shouldn't have any problems.所以答案是,确保您用于事件的函数名称与触发事件的相关 HTMLElement 中的属性不匹配,然后您就不会有任何问题。 (I haven't checked, but it seems likely this would occur with other HTMLElements) (我没有检查过,但其他 HTMLElements 似乎可能会发生这种情况)

In my case I changed them to doMyEnded , doMyPaused and doMyPlayed and all was well.就我而言,我将它们更改为doMyEndeddoMyPauseddoMyPlayed ,一切都很好。

NOTE: I strongly recommend anyone who wants to know more about this read the answer by TJ Crowder注意:我强烈建议任何想了解更多信息的人阅读 TJ Crowder 的答案

This is one of the many reasons not to use onxyz -attribute-style event handlers.这是使用onxyz样式事件处理程序的众多原因之一。 Not only can they only call global functions (which aren't best practice), but they run in a complicated scoping environment which includes not only the current element's properties (the problem you had) but in some cases properties from other elements as well (such as the form an input is located in).它们不仅可以调用全局函数(这不是最佳实践),而且还可以在复杂的范围环境中运行,该环境不仅包括当前元素的属性(您遇到的问题),而且在某些情况下还包括其他元素的属性(例如input所在的form )。 (More below.) (更多见下文。)

Instead, use modern event handling (and modules when possible [all modern browsers support them]).相反,使用现代事件处理(和模块(如果可能)[所有现代浏览器都支持它们])。

For example:例如:

<!DOCTYPE html>
<html>
<head>
</head>
<body>
    <div>
        <video src="videoFile.mp4" controls></video>
    </div>
    <script type="module">
        function ended(e) {
            console.log("Ended");
        }
        
        function paused(e) {
            console.log("Paused");
        }

        function played(e) {
            console.log("Played");
        }       

        const videoElement = document.querySelector(`video[src="videoFile.mp4"]`);
        videoElement.addEventListener("ended", ended);
        videoElement.addEventListener("pause", paused);
        videoElement.addEventListener("play", played);
    </script>
</body>
</html>

About the "complicated scoping environment": The code in an onxyz -attribute-style event handler runs in a scope that is effectively created like this (for your example):关于“复杂的范围环境”: onxyz -attribute-style 事件处理程序中的代码在有效创建的范围内运行(对于您的示例):

with (document) {
    with (theTargetVideoElement) {
        // ...your code here...
    }
}

(That's right, the dreaded (and deprecated) with statement .) (没错,可怕的(和弃用的) with statement 。)

For an element in a form , it's even worse:对于form的元素,情况更糟:

with (document) {
    with (theForm) {
        with (theTargetElementInTheForm) {
            // ...your code here...
        }
    }
}

Here's an example of that:这是一个例子:

 <form method="POST"> <input type="button" onclick=" console.log(documentElement.tagName); // 'HTML' console.log(method); // 'post' console.log(type); // 'button' " value="Click Me"> </form>

  • documentElement comes from document documentElement来自document
  • method comes from the form element method来自form元素
  • type comes from the input element type来自input元素

Just Say No. 😃只说不😃

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Uncaught (in promise) TypeError: X is not a function - Uncaught (in promise) TypeError: X is not a function 反应:未捕获的类型错误:X 不是 function - React: Uncaught TypeError: X is not a function 未捕获的类型错误:x.function 不是 function - Uncaught TypeError: x.function is not a function Javascript中的“未捕获的TypeError:x.toUpperCase不是函数” - “Uncaught TypeError: x.toUpperCase is not a function” in Javascript jQuery Uncaught TypeError:$(…).editRule不是函数-click事件 - jQuery Uncaught TypeError: $(…).editRule is not a function - click event 未捕获的TypeError:jQuery.event.addProp不是函数 - Uncaught TypeError: jQuery.event.addProp is not a function 实例化函数中的对象会给出“未捕获的TypeError:未定义不是函数” - Instantiating object in a function gives “Uncaught TypeError: undefined is not a function” jQuery(window).load(function($) 仍然给出 Uncaught TypeError: $ is not a function - jQuery(window).load(function($) still gives Uncaught TypeError: $ is not a function HTML中的“未捕获的TypeError:bgColor不是函数”选择onchange - “Uncaught TypeError: bgColor is not a function” in HTML select onchange HTML5 视频未捕获类型错误:.play 不是函数 - HTML5 video Uncaught TypeError: .play is not a function
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM