JS动态添加video标签后jQuery的canplay等事件无法触发问题
解决动态添加Video元素后事件无法触发的问题
这个问题我之前也踩过坑!核心原因很简单:你最初的事件绑定是直接绑定在页面加载完成时就存在的<video>元素上的,而通过replaceWith动态生成的新<video>元素是在事件绑定完成后才被插入DOM的,这些新元素自然没有带上那些事件监听。
下面给你两种可行的解决方案:
方案一:事件委托(推荐,更灵活)
利用DOM事件冒泡的特性,把事件绑定到一个始终存在的父级元素(比如document,或者你页面中固定存在的容器)上,然后指定触发事件的目标是<video>元素。这样不管是初始的还是后续动态添加的video,只要匹配选择器,事件都会生效。
修改你的事件绑定代码:
$(document).ready(function(){ // 用事件委托方式绑定所有video元素的事件 $(document).on('canplay', 'video', function(){ // 你的canplay回调逻辑 }); $(document).on('timeupdate', 'video', function(){ // 你的timeupdate回调逻辑 }); $(document).on('progress', 'video', function(){ // 你的progress回调逻辑 }); $(document).on('ended', 'video', function(){ // 你的ended回调逻辑 }); });
这种方式的优势是:不用管后续什么时候添加video元素,只要符合选择器,事件都会自动生效,特别适合需要多次动态生成视频播放器的场景。
方案二:动态创建后直接绑定事件
如果你只需要单次动态添加视频播放器,也可以在生成新的<video>元素后,立即给它绑定事件。修改你的动态生成代码:
if($(".myVideo").length > 0){ $('.myVideo').each(function(){ var th = $(this), vidSrc = th.attr('data-src'), playerHTML = '<div class="videoPlayer videoPlayerNew"><video width="300" height="200"><source src='+vidSrc+'></video><div>...myControls...</div></div>'; // 先把HTML转为jQuery对象,方便后续操作 var newPlayer = $(playerHTML); // 替换原有元素 th.replaceWith(newPlayer); // 给新生成的video元素绑定事件 var newVideo = newPlayer.find("video"); newVideo.on('canplay', function(){ // 你的canplay回调逻辑 }).on('timeupdate', function(){ // 你的timeupdate回调逻辑 }).on('progress', function(){ // 你的progress回调逻辑 }).on('ended', function(){ // 你的ended回调逻辑 }).load(); // 加载视频 // 移除多余类名(修正原代码的类名笔误) newPlayer.removeClass("videoPlayerNew"); }); }
注意:原代码里有两处小笔误需要修正:
- 循环选择器应该是
.myVideo(你的源HTML是<div class="myVideo">),而不是.videoPlayer - 移除类名应该是
videoPlayerNew,而不是videoBlockNew
总结
如果你的页面会多次动态添加视频播放器,优先选择事件委托,代码更简洁且维护性强;如果只是单次操作,两种方案都可以满足需求。
内容的提问来源于stack exchange,提问作者Vigen Cholakyans
相关产品推荐
相关产品推荐

