JS一个非常经典的问题:在遍历数组时对DOM监听事件,索引值将始终等于遍历结束后的值
一个简单的Tab选项卡点击事件。
<style type="text/css">
ul{padding:0;margin:0;}
.tab{width:400px;}
.tab-menuWrapper{padding-left:20px;}
.tab-menuWrapper li{float:left;display:inline;padding:5px;border:1px solid #333;border-bottom:none;margin-right:5px;}
.tab-contentWrapper{border:1px solid #333;clear:left;padding:5px;}
</style>
<div class="tab">
<ul class="tab-menuwrapper">
<li>menu1</li>
<li>menu2</li>
<li>menu3</li>
</ul>
<div class="tab-contentwrapper">
<div>content1</div>
<div style="display:none">content2</div>
<div style="display:none">content3</div>
</div>
</div>
然后我们需要一点js来实现,鼠标点击时content内容的切换。
<script type="text/javascript">
var tabMenu=document.getElementById("tab-menuWrapper").getElementsByTagName("li");
var tabContent=document.getElementById("tab-contentWrapper").getElementsByTagName("div");
for(var i=0;i<tabmenu .length;i++){
tabMenu[i].onclick=function(){
for(var j=0;j<tabContent.length;j++){
tabContent[j].style.display="none";
}
tabContent[i].style.display="block";
}
}
</script>
我们希望借助于数组和循环来完成这个任务,但是我们发现上述代码不能完成我们的任务,会报错:“tabContent[i] is undefined”. 我们利用alert(i)检测一下。
for(var i=0;i<tabmenu .length;i++){
tabMenu[i].onclick=function(){
alert(i); //3,3,3 why???
for(var j=0;j<tabContent.length;j++){
tabContent[j].style.display="none";
}
tabContent[i].style.display="block";
}
}
当我们点击tabMenu1,2,3时,不是弹出0,1,2而是弹出3,3,3。所以后面的tabContent[i]会是undefined。(tabContent[i]中i实际上只有0,1,2)解决这个问题,我们可以使用闭包。
for(var i=0;i</tabmenu><tabmenu .length;i++){
(function(_i){
tabMenu[_i].onclick=function(){
for(var j=0;j<tabContent.length;j++){
tabContent[j].style.display="none";
}
tabContent[_i].style.display="block";
}
})(i);
}
或者我们给DOM节点添加_index属性,属性值等于索引:
for(var i=0;i</tabmenu><tabmenu .length;i++){
tabMenu[i]._index=i;
tabMenu[i].onclick=function(){
for(var j=0;j<tabContent.length;j++){
tabContent[j].style.display="none";
}
tabContent[this._index].style.display="block";
}
}
虽然解决了问题。但是为什么在onclick里的索引值是循环结束后的最终值???一直不是很明白,求高人指点!!!
JS一个非常经典的问题:在遍历数组时对DOM监听事件,索引值将始终等于遍历结束后的值的更多相关文章
- jQuery监听事件经典例子
关键字:jQuery监听事件经典例子 js代码: ============================================================ $(function( ...
- node.js绑定监听事件EventEmitter类
Node.js 有多个内置的事件,我们可以通过引入 events 模块,并通过实例化 EventEmitter 类来绑定和监听事件,如下: // 引入 events 模块 var events = r ...
- php 中遍历数组时使用引用出现的问题
今天在使用foreach遍历数组时发现,当使用&时会出现问题: $arr = array( array('id' => 100, 'error'=> 'aa'), array('i ...
- JAVAscript学习笔记 js句柄监听事件 第四节 (原创) 参考js使用表
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- JS,JQ及时监听input值的变化,MUI的input搜索框里的清除按钮的点击监听事件
JS: document.getElementById("input对象的ID").addEventListener('input',function(){ console.log ...
- Android 属性动画监听事件与一个菜单的例子
简单监听事件 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 3 ...
- js监听事件的绑定与移除
监听事件的绑定与移除主要是addEventListener和removeEventListener的运用. addEventListener语法 element.addEventListener(ty ...
- 以forin的方式遍历数组时进行删除操作的注意点
今天在修改某项需求的时候,需要在遍历的时候将匹配项移除掉,采用的时forin的方式遍历,然后运行的时候却crash掉了 for (NSString*str in self.btnArray) { if ...
- JS监听事件错误:Uncaught TypeError: xx(函数名)is not a function at HTMLInputElement.onclick
事件监听一直出错,提示已定义的函数名不是一个函数,折腾了好久才想到,原来是函数名和JS内部关键字重名造成的. 以前也遇到过这种情况,但因为发生的概率比较小,就没太在意,但是这次感觉这方面确实需要注意, ...
随机推荐
- redis---安全设置
redis的安全性是通过设置口令来实现的. 首先打开redis的配置文件,我的是在/etc/redis/redis.conf,个人的路径可能会有不同,可以自行查找. 打开redis.conf文件以后, ...
- OpenFirewall
1.写一份json文件:将要添加防火墙例外的应用程序和端口写入到json文件中 2.打开防火墙,读取json文件添加例外 /// <summary> /// Firewall.xaml 的 ...
- 初学者:Git常用命令总结
git init 在本地新建一个repo,进入一个项目目录,执行git init,会初始化一个repo,并在当前文件夹下创建一个.git文件夹. git clone 获取一个u ...
- MySQL使用一张表的一列更新另一张表的一列
使用MySQL中,在一张表etl_table_field_info上新增了一个字段tgt_table_en_name,该字段的值想从表etl_table_property_info的tgt_table ...
- String和string
String和string的区别 从位置讲: 1.String是.NET Framework里面的String,小写的string是C#语言中的string 2.如果把using ...
- IFEO 映像文件劫持
“映像劫持”,也被称为“IFEO”(Image File Execution Options) 映像劫持的根本就是被恶意篡改了注册表HKEY_LOCAL_MACHINE\SOFTWARE\Micros ...
- Spring,FetchType.LAZY和FetchType.EAGER什么区别?
1.FetchType.LAZY:懒加载,加载一个实体时,定义懒加载的属性不会马上从数据库中加载. 2.FetchType.EAGER:急加载,加载一个实体时,定义急加载的属性会立即从数据库中加载. ...
- python_53_函数补充
def test1(x,y=2): print(x,y) test1(1) test1(1,3) test1(1,y=4) #默认参数特点:调用函数的时候,默认参数非必须传递,默认参数放在后边 #用途 ...
- 国产中标麒麟Linux部署dotnet core 环境并运行项目 (二) 部署运行控制台项目
背景 在上一篇文章安装dotnet core,已经安装好dotnet core了.之前只是安装成功了dotnet, 输入dotnet --info,可以确认安装成功了,但是在运行代码时,还是报错了,本 ...
- java基础面试题:switch语句能否作用在byte上,能否作用在long上,能否作用在String上?
package com.swift; public class Switch_Test { public static void main(String[] args) { /* * switch语句 ...