javascript - 添加事件上的一个小问题。

查看:94
本文介绍了javascript - 添加事件上的一个小问题。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

麻烦更新内容,保留原来的东西。你让原来的答题者,情何以堪

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Document</title>
 <style>
 .active{ background: red}
 </style>
</head>
<body>
 <input type="button" vlaue='anniu'>
 <input type="button" vlaue='anniu'>
 <input type="button" vlaue='anniu'>
 <script>
 var oBtn=document.getElementsByTagName('input');
 for(var i=0; i<oBtn.length;i++){
    oBtn[i].onclick=function(){
    //oBtn[i].className='active' //为什么这样添加属性会报错,
     this.className='active';
    }
 }
 </script>
</body>
</html>


更新之后代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
    #div1 .active{background:yellow;}
    #div1 div{width: 200px;height: 200px;background: #ccc;border: 1px solid #999;display: none;}
    </style>
    <script>
        window.onload=function(){
            var oDiv=document.getElementById('div1');
            var aBtn=oDiv.getElementsByTagName('input');
            var aDiv=oDiv.getElementsByTagName('div');
            for(var i=0; i<aBtn.length;i++){
                aBtn[i].index=i;
                aBtn[i].onclick=function(){
                    for(var i=0;i<aBtn.length;i++){
                       //而这里却不会报错。 
                        aBtn[i].className="";
                        aDiv[i].style.display='none';
                    }
                    //为什么这里用aBtn[i].className='active'添加报错 SCRIPT5007: 无法设置未定义或 null 引用的属性className 
                    this.className='active';
                    aDiv[this.index].style.display="block"
                }    
            }
        }
    </script>
</head>
<body>
    <div id='div1'>
        <input class="active" type="button" value='教育'>
        <input type="button" value='金融'>
        <input type="button" value='招生'>
        <input type="button" value='出国'>
        <div style='display:block;'>111</div>
        <div>222</div>
        <div>333</div>
        <div>444</div>
    </div>
</body>
</html>

解决方案

这是一个新手经常会遇到的问题。为什么会这样呢?一步一步来。先看下面的代码

for(var i=0; i<oBtn.length;i++){
    oBtn[i].onclick=function(){
        console.log(i);
    }
}

你会发现所有的输出都是2,也就是oBtn.length

click事件发生的时候,会执行代码console.log(i)

控制台会打印i
控制台会打印i
控制台会打印i

那么i又是什么?不是你想象的数字。这里i是一个变量,它最终打印出是这个变量的值。
这个值是oBtn.length,因为循环语句

for(var i=0; i<oBtn.length;i++){

}

执行完毕后,i已经变成了oBtn.length。因此,在内部使用oBtn[i]是不行的。


以下内容,初学者要耐心

如果,非要使用oBtn[i],那么就必须在oBtn[i].onclick赋值的时候,用变量把i的每次值保存起来。

for(var i=0; i<oBtn.length;i++){
    oBtn[i].onclick=(function(j){
        return function(){
            oBtn[j].className='active'
        }
    })(i)
}

这里,我们执行了一个匿名函数,并且把i,传给了这个函数。然后,这个匿名函数返回一个函数,作为click属性的值。当点击事件发生的时候,就会触发这个函数。

当匿名函数返回一个函数的时候,会形成一个闭包被返回的函数(内部函数)可以访问匿名函数(外部函数)的参数,以及两个函数中间的变量。

// 这是把i作为参数传给匿名函数,并执行函数。
(匿名函数)(i)

匿名函数 = function(j){
    return function(){
        oBtn[j].className='active'
    }
}

当i传过来的时候,j = i;当i的值发生变化的时候,j的值是不会跟着变的。这与下面代码是一个意思

var a, b = 5;

a = b;
b = 6;

a, b // 5, 6; a不会跟着变了

这样每一个不同的i的值就被保存下来了。也许你会有疑问,每一次都执行了j = i,为什么j的值没有变化呢?因为每次循环的时候,匿名函数都是新的,包括参数变量等。

显然,上一个j与下一个j已经不是同一个了。

这篇关于javascript - 添加事件上的一个小问题。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆