Web 前端开发

一个经典的闭包问题

2018-07-06  本文已影响2人  从小就很瘦

老生常谈的一个面试题,如何解决点击ul下的每个li,弹出这个li的元素索引呢?

<ul>
        <li>111</li>
        <li>222</li>
        <li>333</li>
</ul>

1. 绑定数据在DOM元素上

var oLi = document.getElementsByTagName('li');
        for (var i = 0; i < oLi.length; i++) {
            oLi[i]._index = i;
            oLi[i].onclick = function () {
                alert(this._index + 1)
            }
        }

遍历oLi,设置一个属性_index来记录i。

2. 闭包

var oLi = document.getElementsByTagName('li');
        for (var i = 0; i < oLi.length; i++) {
            oLi[i].onclick = fn(i)
        }
        function fn(j) {
            return function() {
                alert(j + 1)
            }
        }

IIFE写法

var oLi = document.getElementsByTagName('li');
        for (var i = 0; i < oLi.length; i++) {
            oLi[i].onclick = (function(j){
                return function() {
                    alert(j + 1)
                }
            })(i)
        }

这样的写法是最常见的:

var oLi = document.getElementsByTagName('li');
        for (var i = 0; i < oLi.length; i++) {
            (function (j) {
                oLi[j].onclick = function () {
                    alert(j + 1)
                }
            })(i)
        }

3. let

超级简单,ES6使用let就是为了解决作用域的问题。ES5的一些方法要逐渐淘汰了~

var oLi = document.getElementsByTagName('li');
        for (let i = 0; i < oLi.length; i++) {
            oLi[i].onclick = function() {
                alert( i + 1)
            }
        }

4. 事件委托

先将带有length属性的元素转换为数组,然后利用数组的indexOf方法。

var oLi = document.getElementsByTagName('li');
            ali = Array.prototype.slice.call(oLi);
            oUl = document.getElementsByTagName('ul')[0];
        oUl.addEventListener('click', function () {
            var event = event || window.event;
            var target = event.target || event.srcElement;
            alert(ali.indexOf(target) + 1)
        })

本人水平有限,如有错误,还望指出 _"

上一篇 下一篇

猜你喜欢

热点阅读