使用for循环设置事件处理程序。
使用for循环设置事件处理程序。
我在jsfiddle上尝试了一些javascript,并遇到了一个奇怪的问题。我似乎无法弄清楚为什么无法通过for循环设置onclick事件处理程序:\nHTML代码:\n
Header1 | Header2 | Header3 | Header4 |
books | red | peas | 321 |
tapes | blue | jello | 654 |
\nDOM准备好后执行的js代码:\nvar arr = document.getElementById(\'headerRow\').getElementsByTagName(\"td\");\n// 为什么这样能行??\n/*arr[0].onclick = function() { alert(arr[0].innerHTML); };\narr[1].onclick = function() { alert(arr[1].innerHTML); };\narr[2].onclick = function() { alert(arr[2].innerHTML); };\narr[3].onclick = function() { alert(arr[3].innerHTML); };\n*/\n// 但是这样就不行了???\nfor(var i = 0; i < arr.length; i++) {\n arr[i].onclick = function() { alert(arr[i].innerHTML); };\n}\n链接:http://jsfiddle.net/xzmMj/4/
问题的出现原因是在for循环中,使用全局变量i进行递增操作。当循环结束时,i的值会变为4。然后在click事件处理函数中,尝试显示arr[i].innerHTML,即arr[4].innerHTML。显然,arr[4]并不存在,因此会出现错误。
解决方法是将alert(arr[i].innerHTML)改为alert(this.innerHTML)。在click事件处理函数的上下文中,this指向
问题的原因是在for循环中设置事件处理程序时,由于作用域的问题,arr[i]
会在一个交替的作用域中执行,从而导致错误。
解决方法是使用闭包,将arr[i].innerHTML
作为参数传递给一个立即执行的函数,并将返回的函数作为事件处理程序赋给arr[i].onclick
。这样就可以确保每个事件处理程序都在正确的作用域中执行,避免了错误的发生。
具体的代码如下:
for(var i = 0; i < arr.length; i++) { arr[i].onclick = function(text) { return function () { alert(text); }; }(arr[i].innerHTML); }
你可以点击以下链接查看演示效果:
通过使用闭包解决了作用域问题,确保了每个事件处理程序都能正确执行。这是一个常见的解决方法,对于熟悉闭包的开发人员来说是一个很好的技巧。
问题的原因是由于循环中的事件处理程序无法正确地访问循环变量的当前值。在这种情况下,变量i将不会包含您预期的"当前索引",而是i的最后一个值,即arr.length。这导致在点击事件发生时,无法正确地获取相应元素的值。
解决方法是使用一个立即执行的函数表达式(IIFE)来创建一个闭包,以捕获当前循环变量的值,并将其存储在一个新的变量_i中。通过这种方式,每个事件处理程序都有自己的_i的副本,而不会受到循环的影响。
以下是解决方法的示例代码:
for(var i = 0; i < arr.length; i++) { (function(_i){ arr[_i].onclick = function() { alert(arr[_i].innerHTML); }; })(i); }
在这段代码中,通过将立即执行的函数表达式包裹在一个闭包中,我们确保了每个事件处理程序都有一个独立的_i变量,它包含了当前循环迭代的索引值。这样,当点击事件发生时,我们可以正确地获取并显示相应元素的内容。
通过使用这种解决方法,我们可以避免循环中事件处理程序的问题,并确保每个处理程序都能正确地访问其所需的变量值。