如何给现有YouTube视频播放器代码添加video.removeEventListener逻辑
解决方案
核心要解决两个问题:
addEventListener和removeEventListener必须绑定同一个函数引用才能生效,原来的匿名回调函数无法被匹配解绑,需要先把事件处理函数的引用保存下来- 每次绑定新事件前,要先清理之前绑定的旧事件,避免重复绑定
修改后完整代码
const videoPlayer = (function makeVideoPlayer() { const players = []; const tag = document.createElement("script"); tag.src = "https://www.youtube.com/player_api"; const firstScriptTag = document.getElementsByTagName("script")[0]; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); function createResetHandler(player) { // 先解绑之前绑定的旧事件,避免重复绑定 if (player.resetHandlers) { player.resetHandlers.forEach(({video, handler}) => { video.removeEventListener('click', handler); }) } // 初始化存储当前player绑定的所有事件映射 player.resetHandlers = []; const resetVideos = document.querySelectorAll('.exit'); resetVideos.forEach(function resetVideoHandler(video) { // 把匿名函数抽成可引用的变量 const clickHandler = function resetVideoHandler() { // 销毁播放器前先解绑所有绑定的事件 player.resetHandlers.forEach(({video, handler}) => { video.removeEventListener('click', handler); }) // 清空存储的事件映射 delete player.resetHandlers; player.destroy(); console.log('hit') } // 绑定事件 video.addEventListener('click', clickHandler); // 把元素和对应处理函数存到player实例上,后面解绑用 player.resetHandlers.push({ video: video, handler: clickHandler }) } ) } function onPlayerReady(event) { const player = event.target; player.setVolume(100); createResetHandler(player); } function addPlayer(video, settings) { const defaults = { height: 360, host: "https://www.youtube-nocookie.com", videoId: video.dataset.id, width: 640 }; defaults.events = { "onReady": onPlayerReady }; const playerOptions = combinePlayerOptions(defaults, settings); const player = new YT.Player(video, playerOptions); players.push(player); return player; } return { addPlayer }; }());
核心改动说明
- 给每个player实例新增
resetHandlers属性,存储所有绑定的.exit元素和对应点击事件处理函数的引用 - 每次调用
createResetHandler时先清理之前绑定的旧事件,避免同一元素重复绑定多个回调 - 触发点击销毁播放器时,先遍历所有存储的事件映射完成解绑,再执行销毁逻辑
内容的提问来源于stack exchange,提问作者user16940297
相关产品推荐
相关产品推荐

