先上代码:
(1)html部分:<dl id="listContainer">
<dt class="click">标题一</dt>
<dd class="block">内容一</dd> <dt>标题二</dt>
<dd>内容二</dd> <dt>标题三</dt>
<dd>内容三</dd> <dt>标题四</dt>
<dd>内容四</dd>
</dl>(2)css部分: *{ margin: 0;
padding: 0;} dl{ width: 300px;
margin: 100px auto;
border: #666 1px solid;
border-bottom: none;}
dt{ line-height: 40px;
background: #888;
color: #fff;
font-size: 14px;
font-weight: bold;
padding-left: 20px;
border-top: #999 1px solid;
border-bottom: #666 1px solid;
cursor: pointer;}
dt.click{ background: #dfdfdf;
color: #333;
border-bottom: #cfcfcf 1px solid;
border-top: #efefef 1px solid;}
dd{ display:none;
color: #444;
font-size: 12px;
text-align: center;
padding: 20px;
background: #efefef;}
dd.block{ display: block;
border-bottom:#666 1px solid;
}(3)脚本部分: /*分别获取dt,dd标签组*/
var listContainer=document.getElementById('listContainer'),
dts=document.getElementsByTagName('dt'),
dds=document.getElementsByTagName('dd'); /*(在给点击的dt改变类名,相邻的dd改变类名之前)判断dt.click,dd.block是否存在并设置类名为空*/
function disappear(){
for(var n=0;n<dts.length;n++){
if(dts[n].className=='click'){
dts[n].className='';
}
if(dds[n].className=='block'){
dds[n].className='';
}
}
} /*主要函数---用于隐藏旧选项卡显示新选项卡*/
function clickEffects(){
for(var i=0;i<dts.length;i++){
(function(){
dts[i].onclick=function(){
disappear();
dt[i].className= (this.className!=='click')? 'click':'';
dds[i].className= (this.className!=='block')? 'block':'';
}
})();
}
}
window.onload=clickEffects;
函数加载后执行失败。
测试后,该段代码的问题出在clickEffects函数中的匿名函数自执行部分,即: (function(){
dts[i].onclick=function(){
disappear();
dt[i].className= (this.className!=='click')? 'click':'';
dds[i].className= (this.className!=='block')? 'block':'';
}
})();之后,我将匿名函数引入参数,由i来递值,如下: (function(num){
dts[num].onclick=function(){
disappear();
this.className= (this.className!=='click')? 'click':'';
dds[num].className= (this.className!=='block')? 'block':'';
}
})(i);函数成功执行。分析之后,发现在最初的未引用参数的匿名函数中:
匿名函数的i值为当前i值;
而匿名函数内部的匿名函数,即click绑定的函数中,i值为4(即i作为clickEffects局部变量在for循环之后的最终值).所以针对每次的click实际上是:
dt[0].onclick=function(){dts[4].className=......;dds[4].className=.....};
dt[1].onclick=function(){dts[4].className=......;dds[4].className=.....};
dt[2].onclick=function(){dts[4].className=......;dds[4].className=.....};
dt[3].onclick=function(){dts[4].className=......;dds[4].className=.....};
因为dts[4]和dds[4]是不存在的,所以函数最终执行失败。而我的疑虑也正在于此:
其实,click绑定的函数中,i=4这个很好理解,作为闭包取clickEffects活动对象的最终值。但是,为什么在其外部的匿名函数中,i的值不总等于4而是取了i的当前值0,1,2,3?这个外部的匿名函数该怎么对待,难道不是clickEffects的闭包?
(1)html部分:<dl id="listContainer">
<dt class="click">标题一</dt>
<dd class="block">内容一</dd> <dt>标题二</dt>
<dd>内容二</dd> <dt>标题三</dt>
<dd>内容三</dd> <dt>标题四</dt>
<dd>内容四</dd>
</dl>(2)css部分: *{ margin: 0;
padding: 0;} dl{ width: 300px;
margin: 100px auto;
border: #666 1px solid;
border-bottom: none;}
dt{ line-height: 40px;
background: #888;
color: #fff;
font-size: 14px;
font-weight: bold;
padding-left: 20px;
border-top: #999 1px solid;
border-bottom: #666 1px solid;
cursor: pointer;}
dt.click{ background: #dfdfdf;
color: #333;
border-bottom: #cfcfcf 1px solid;
border-top: #efefef 1px solid;}
dd{ display:none;
color: #444;
font-size: 12px;
text-align: center;
padding: 20px;
background: #efefef;}
dd.block{ display: block;
border-bottom:#666 1px solid;
}(3)脚本部分: /*分别获取dt,dd标签组*/
var listContainer=document.getElementById('listContainer'),
dts=document.getElementsByTagName('dt'),
dds=document.getElementsByTagName('dd'); /*(在给点击的dt改变类名,相邻的dd改变类名之前)判断dt.click,dd.block是否存在并设置类名为空*/
function disappear(){
for(var n=0;n<dts.length;n++){
if(dts[n].className=='click'){
dts[n].className='';
}
if(dds[n].className=='block'){
dds[n].className='';
}
}
} /*主要函数---用于隐藏旧选项卡显示新选项卡*/
function clickEffects(){
for(var i=0;i<dts.length;i++){
(function(){
dts[i].onclick=function(){
disappear();
dt[i].className= (this.className!=='click')? 'click':'';
dds[i].className= (this.className!=='block')? 'block':'';
}
})();
}
}
window.onload=clickEffects;
函数加载后执行失败。
测试后,该段代码的问题出在clickEffects函数中的匿名函数自执行部分,即: (function(){
dts[i].onclick=function(){
disappear();
dt[i].className= (this.className!=='click')? 'click':'';
dds[i].className= (this.className!=='block')? 'block':'';
}
})();之后,我将匿名函数引入参数,由i来递值,如下: (function(num){
dts[num].onclick=function(){
disappear();
this.className= (this.className!=='click')? 'click':'';
dds[num].className= (this.className!=='block')? 'block':'';
}
})(i);函数成功执行。分析之后,发现在最初的未引用参数的匿名函数中:
匿名函数的i值为当前i值;
而匿名函数内部的匿名函数,即click绑定的函数中,i值为4(即i作为clickEffects局部变量在for循环之后的最终值).所以针对每次的click实际上是:
dt[0].onclick=function(){dts[4].className=......;dds[4].className=.....};
dt[1].onclick=function(){dts[4].className=......;dds[4].className=.....};
dt[2].onclick=function(){dts[4].className=......;dds[4].className=.....};
dt[3].onclick=function(){dts[4].className=......;dds[4].className=.....};
因为dts[4]和dds[4]是不存在的,所以函数最终执行失败。而我的疑虑也正在于此:
其实,click绑定的函数中,i=4这个很好理解,作为闭包取clickEffects活动对象的最终值。但是,为什么在其外部的匿名函数中,i的值不总等于4而是取了i的当前值0,1,2,3?这个外部的匿名函数该怎么对待,难道不是clickEffects的闭包?
解决方案 »
- 关于表单提交的问题
- jsp表单内表格传值问题
- 我怎么学习JavaScript好呢....
- js如何实现数据排序功能
- 如何将javascript封装成二进制代码
- 急切等待富文本框的问题
- 泣血求教:怎样在javascript里判断一个外部程序是否已启动,若没启动,启动之,然后向程序发送一个消息(消息带有参数),以求在程序里执
- 在网页内嵌入Mediaplayer,如何设定其“随机播放”列表中的音乐?
- <body designMode="On">test</body>在页面打开时出错,提示“这个窗口已被注册成拖放目标”
- 怎么样快选取CheckBox
- javascript的一个关于循环执行的问题
- 采用 append 添加的html input无法获得值?
for(var i=0;i<dts.length;i++){
(function(num){
dts[i].onclick=function(){
disappear();
dt[i].className= (this.className!=='click')? 'click':'';
dds[i].className= (this.className!=='block')? 'block':'';
}
})(i);
}
}
window.onload=clickEffects;
我来解释下,给添加的外层匿名函数的i是实参,是for循环中的i,当for循环中的i=0,这个i就作为实参传给num这个形参并立即执行,num是一个局部变量,之所以没有消失是因为 dts[i].onclick=function(){
disappear();
dt[i].className= (this.className!=='click')? 'click':'';
dds[i].className= (this.className!=='block')? 'block':'';
}函数引用了外层函数的变量i,当循环多次就产生多个内部函数,每个内部函数都分别引用外部相应的i
你把函数改成这样就好理解一些
function clickEffects(){
for(var i=0;i<dts.length;i++){
(function(){
alert(i);
}
})();
}
}
如上面的代码,每次循环执行的时候,匿名函数就会被调用,i就被使用了,当clickEffects执行结束,i就会被回收。
而不是像定义onclick那样,在定义完成之后并没有用到i,当用户真正去click的时候,才会用到i,这时候才形成了必包,i会一直存在内存里