Dojo HorizontalSliders多次实例化后功能失效原因咨询
为什么循环创建的HorizontalSlider只有最后一个能正常工作?
嘿,这个问题我之前也踩过坑!核心原因出在你用innerHTML +=添加DOM元素的方式上——这种操作会重新渲染整个父容器内的所有DOM节点,直接导致之前创建的滑块实例和DOM元素“失联”了。
具体原因拆解:
当你执行innerHTML +=时,浏览器会做这些事:
- 把父容器(
ui)当前的所有DOM内容转换成字符串 - 拼接上新的HTML字符串
- 把拼接后的字符串重新解析成全新的DOM树,替换掉原来的内容
也就是说,第一次循环创建的slider_0实例,本来已经和对应的div绑定好了,但第二次循环执行innerHTML +=时,原来的slider_0的div被销毁了,新生成的slider_0div是完全陌生的新节点,旧的滑块实例根本不知道它的存在,自然就无法响应交互了。只有最后一次循环创建的滑块,因为之后没有再触发innerHTML的替换,所以它的DOM和实例一直保持绑定,能正常工作。
解决方案1:动态创建DOM节点(推荐)
直接用createElement创建滑块容器,再append到父容器里,这种方式不会破坏已有的DOM节点,所有滑块实例都能和对应的DOM正常绑定:
const uiContainer = dom.byId('ui'); for(let i = 0; i < 5; i++){ const sliderDiv = document.createElement('div'); sliderDiv.id = `slider_${i}`; uiContainer.appendChild(sliderDiv); const slider = new HorizontalSlider({ value: 100, minimum: 0, maximum: 100, style: 'width:300px;' }, sliderDiv); // 直接传入DOM元素,比通过id查找更高效 slider.startup(); }
解决方案2:一次性渲染所有滑块DOM再初始化
如果一定要用innerHTML,那就先把所有滑块的HTML拼接完成,一次性设置给父容器,之后再逐个初始化滑块,这样DOM只会被渲染一次:
let sliderHtml = ''; for(let i = 0; i < 5; i++){ sliderHtml += `<div id="slider_${i}"></div>`; } dom.byId('ui').innerHTML = sliderHtml; // 统一初始化所有滑块 for(let i = 0; i < 5; i++){ const slider = new HorizontalSlider({ value: 100, minimum: 0, maximum: 100, style: 'width:300px;' }, `slider_${i}`); slider.startup(); }
小提示:
日常开发里尽量避免使用innerHTML +=这种操作,它不仅会破坏已有的组件绑定,还会带来不必要的性能开销(重复渲染DOM)。动态创建节点或者一次性渲染都是更稳妥的选择。
内容的提问来源于stack exchange,提问作者Asher Chee YiLiang
相关产品推荐
相关产品推荐

