Tornado应用中多Range Slider仅能访问最后实例的问题求助
Tornado循环生成Range Slider仅最后一个生效的解决方案
问题根源
你用var声明的slider和output变量是函数作用域,循环生成多个Proposal模块时,所有script块里的这两个变量会共享同一作用域,最后一次循环的值会把之前的全部覆盖,导致所有滑块的oninput事件都绑定到最后一个滑块和显示元素上。
三种解决办法
1. 改用块级作用域变量(最简单)
把var换成let或者const,这俩是块级作用域,每个script块的变量都是独立的,不会互相干扰:
<div class="proposal"> Here is proposal {{ proposal_id }}. We need info on all parameters here. <input type="range" min="1" max="100" value="100" class="slider" id="proposal_slider_{{ proposal_id }}"> <p>Value: <span id="score_value_{{ proposal_id }}"></span></p> <script> const slider = document.getElementById("proposal_slider_{{ proposal_id }}"); const output = document.getElementById("score_value_{{ proposal_id }}"); output.innerHTML = slider.value; slider.oninput = function() { output.innerHTML = slider.value; } </script> </div>
2. 依赖DOM关系获取元素(不用写一堆ID)
不用给每个滑块和显示元素加唯一ID,直接通过当前模块的DOM结构找到对应元素,代码更简洁:
<div class="proposal"> Here is proposal {{ proposal_id }}. We need info on all parameters here. <input type="range" min="1" max="100" value="100" class="slider"> <p>Value: <span class="score_value"></span></p> <script> // 找到当前模块里的滑块和显示元素 const slider = document.currentScript.parentElement.querySelector('.slider'); const output = slider.parentElement.querySelector('.score_value'); output.innerHTML = slider.value; slider.oninput = function() { output.innerHTML = this.value; // 用this指代当前拖动的滑块 } </script> </div>
3. 闭包隔离变量(兼容旧浏览器)
如果要支持不支持let/const的旧浏览器,用闭包把每个滑块的变量单独包裹起来:
<div class="proposal"> Here is proposal {{ proposal_id }}. We need info on all parameters here. <input type="range" min="1" max="100" value="100" class="slider" id="proposal_slider_{{ proposal_id }}"> <p>Value: <span id="score_value_{{ proposal_id }}"></span></p> <script> var slider = document.getElementById("proposal_slider_{{ proposal_id }}"); var output = document.getElementById("score_value_{{ proposal_id }}"); output.innerHTML = slider.value; // 用闭包将当前的slider和output传递给事件函数 slider.oninput = (function(sliderEl, outputEl) { return function() { outputEl.innerHTML = sliderEl.value; } })(slider, output); </script> </div>
效果验证
修改后拖动任意滑块,对应的数值都会实时更新,不会再只动最后一个。
内容的提问来源于stack exchange,提问作者kakben
相关产品推荐
相关产品推荐

