jQuery中视频currentTime与select选项触发意外循环问题求助
视频与Select选项关联触发循环的问题解决思路
问题场景
视频播放到对应video.currentTime区间时,会修改#chapters选择框的值;而选择框的change事件又会修改video.currentTime,由此形成循环。尝试用return false终止循环但无效。
原实现代码
JavaScript代码
video.addEventListener('timeupdate', function() { if ((video.currentTime >= "0") && (video.currentTime <= "0.3")) { $("#chapters").val('ch1').change(); $('div[id^="ch"]').hide(500); $("#ch1").show(1000); return false; } if ((video.currentTime >= "93") && (video.currentTime <= "93.3")) { $("#chapters").val('ch2').change(); $('div[id^="ch"]').hide(1000); $("#ch2").show(1000); return false; } }); $('#chapters').on('change', function() { if ($(this).val() == 'ch1'){ video.currentTime = 0; return false; } if ($(this).val() == 'ch2'){ video.currentTime = 93; return false; } });
HTML代码
<video style="max-width:100%; width: 900px;" controls autoplay id="element"> <source src="******.mp4" type="video/mp4"> Your browser does not support the video. </video> <select value="chapters" id="chapters"> <option>- - -</option> <option value="all">ALL</option> <option>- - -</option> <option value="ch1">Section 1 - Intro - </option> <option value="ch2">Section 2 - blah blah </option> </select>
解决思路
核心是区分触发源:判断操作是用户手动选择Select,还是视频时间更新自动修改Select,以此避免双向触发循环。下面提供两种可行方案:
方案一:添加触发标记
通过全局变量标记当前操作是自动触发还是手动触发,在change事件中跳过自动触发的逻辑:
// 标记是否为自动触发的Select修改 let isAutoTrigger = false; video.addEventListener('timeupdate', function() { const currentSelectVal = $("#chapters").val(); // 检查当前章节已匹配,避免重复执行DOM操作 if ((video.currentTime >= 0) && (video.currentTime <= 0.3)) { if (currentSelectVal === 'ch1') return; isAutoTrigger = true; $("#chapters").val('ch1').change(); $('div[id^="ch"]').hide(500); $("#ch1").show(1000); isAutoTrigger = false; } else if ((video.currentTime >= 93) && (video.currentTime <= 93.3)) { if (currentSelectVal === 'ch2') return; isAutoTrigger = true; $("#chapters").val('ch2').change(); $('div[id^="ch"]').hide(1000); $("#ch2").show(1000); isAutoTrigger = false; } }); $('#chapters').on('change', function() { // 自动触发的change事件,直接跳过修改视频进度的逻辑 if (isAutoTrigger) return; if ($(this).val() == 'ch1'){ video.currentTime = 0; } else if ($(this).val() == 'ch2'){ video.currentTime = 93; } });
方案二:不触发change事件,手动执行UI逻辑
修改Select值时不调用.change()触发事件,只更新DOM状态,同时手动执行章节切换的UI逻辑:
video.addEventListener('timeupdate', function() { const currentSelectVal = $("#chapters").val(); if ((video.currentTime >= 0) && (video.currentTime <= 0.3)) { if (currentSelectVal === 'ch1') return; // 仅更新Select值,不触发change事件 $("#chapters").val('ch1'); $('div[id^="ch"]').hide(500); $("#ch1").show(1000); } else if ((video.currentTime >= 93) && (video.currentTime <= 93.3)) { if (currentSelectVal === 'ch2') return; $("#chapters").val('ch2'); $('div[id^="ch"]').hide(1000); $("#ch2").show(1000); } }); $('#chapters').on('change', function() { if ($(this).val() == 'ch1'){ video.currentTime = 0; } else if ($(this).val() == 'ch2'){ video.currentTime = 93; } });
额外优化点
- 将时间判断的字符串(如
"0")改为数字0,避免类型转换带来的潜在问题。 - 添加章节匹配判断,避免每次
timeupdate事件都重复执行DOM操作,提升页面性能。
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

