search

Home  >  Q&A  >  body text

javascript - JS中this的问题

HTML部分:

    <ul id="ul">
        <li>hello</li>
        <li>yeah</li>
        <li>yes</li>
        <li>nope</li>
    </ul>

JS部分:

    var ul = document.getElementById('ul');
    var lis = ul.getElementsByTagName('li');
    for(var i = 0, len = lis.length; i < len; i++)
    {
        lis[i].onclick = function(){
            ***this***.style.fontSize = '30px';
        }
    }

为什么把this.style.fontSize的this改成lis[i]就没有点击li后字体变大的效果了呢?
这里的this难道不是指的是对象lis[i]吗?

大家讲道理大家讲道理2900 days ago244

reply all(7)I'll reply

  • PHPz

    PHPz2017-04-10 17:03:43

    因为onclick是一个异步的事件,当事件触发的时候循环已经执行完了,所以这个时候i已经是lis.length了,不行你可以打印一下看。你可以通过闭包的方式了解决这个问题

     for(var i = 0, len = lis.length; i < len; i++)
     {
         (function(i){
             lis[i].onclick = function(){
                lis[i].style.fontSize = '30px';
            }
         })(i);      
     }

    reply
    0
  • PHP中文网

    PHP中文网2017-04-10 17:03:43

    改成 lis[i] ,循环完毕的时候,闭包中的i始终等于lis.length 也就是4
    onclick的时候,lis[i]就报异常了, 具体你可以检查一下console,或者在onclick里输出一下 i 的值

    reply
    0
  • 天蓬老师

    天蓬老师2017-04-10 17:03:43

    this确实是指向点击的那个DOM对象,但lis[i]不是了,i是指向上一层闭包的一个引用,当onclick的事件处理发生的时候,i已经完成了循环遍历,它的值是len。
    具体请参阅javascript闭包机制方面的内容。

    reply
    0
  • 阿神

    阿神2017-04-10 17:03:43

    this是事件监听器函数声明时的lis[i],但不是事件监听器函数调用时的lis[i]。

    这样改一下:

    list[i].click = (function(j) {
        return function() {
            list[j].style.fontSize = '30px';
        };
    })(i);

    就可以把声明时的i保持到调用时了。

    reply
    0
  • 巴扎黑

    巴扎黑2017-04-10 17:03:43

    闭包 不信你点击最后一个li

    reply
    0
  • 大家讲道理

    大家讲道理2017-04-10 17:03:43

    this所指向的对象需要具体看其执行的环境,如果是在全局环境中执行,它代表的是window,如果是在类中执行则代表当前类,当然如果通过callapply调用还可以为this指定对象.

    reply
    0
  • 天蓬老师

    天蓬老师2017-04-10 17:03:43

    简单的说就是谁调用了函数,函数的this就是谁。
    所以dom的click事件触发了函数,this就是这个dom
    所以可以通过foo.func.call(bar)改变this指向bar。。

    reply
    0
  • Cancelreply