video元素绑定事件触发Uncaught TypeError: X is not a function错误求助
报错根源
内联事件(比如onplay、onpause这类写在HTML标签里的事件回调)的执行作用域存在优先级:会优先从当前绑定事件的DOM元素自身的属性开始查找标识符,再向上查找document属性,最后才到全局window作用域。
而你定义的三个函数名ended、paused、played,刚好都是HTMLVideoElement(视频元素对应的DOM接口)的内置原生属性:
played:返回已播放时间段的TimeRanges对象paused:返回表示视频是否处于暂停状态的布尔值ended:返回表示视频是否播放完毕的布尔值
所以当事件触发时,内联回调里优先找到的是元素自身的这几个原生属性,都不是函数类型,调用就会抛出xxx is not a function的错误。
解决办法
有几个可行的方案,按需选择即可:
方案1:修改自定义函数名,避开原生属性名
最简单的方案,只要把函数名改成不跟视频元素原生属性冲突的名称就行:
<!DOCTYPE html> <html> <head> <script> function onVideoEnded(e) { alert("Ended"); } function onVideoPaused(e) { alert("Paused"); } function onVideoPlayed(e) { alert("Played"); } </script> </head> <body> <div> <video src="videoFile.mp4" controls onended="onVideoEnded(event)" onpause="onVideoPaused()" onplay="onVideoPlayed(event)" > </video> </div> </body> </html>
方案2:显式指定从全局作用域调用函数
因为你定义的函数是挂载在window上的全局函数,直接在调用时加window.前缀,强制从全局作用域查找,就不会被元素自身的属性拦截了:
<video src="videoFile.mp4" controls onended="window.ended(event)" onpause="window.paused()" onplay="window.played(event)" > </video>
方案3:改用JS动态绑定事件,不使用内联事件
更符合现代开发规范的方案,避免内联事件的作用域问题,也能更好的做到逻辑和视图分离:
<!DOCTYPE html> <html> <head> </head> <body> <div> <video id="myVideo" src="videoFile.mp4" controls > </video> </div> <script> const video = document.getElementById('myVideo'); function ended(e) { alert("Ended"); } function paused(e) { alert("Paused"); } function played(e) { alert("Played"); } // 动态绑定事件 video.addEventListener('ended', ended); video.addEventListener('pause', paused); video.addEventListener('play', played); </script> </body> </html>
内容的提问来源于stack exchange,提问作者James Carlyle-Clarke
相关产品推荐
相关产品推荐

