JS 事件委託

序言

這是我曾經面試的時候遇到過的一道面試題。很是基礎,並且出現頻率奇高,因此就留心總結一下。原題目以下:html

1到100個節點,點擊其中任意一個節點,彈出節點所在的序號。node

問題就是如此之簡單直接,但我對這撲面而來的題目彷佛尚未能力徹底作好準備。回想起當時的能力真是渣到醉的不行。不過「二哈」的我把這點當作一個須要我努力的理由。面試

既然已經不好了,學一點也不會比如今更差。放棄什麼的,就真的一點但願都沒有了。函數

說了這麼多都偏題了,下面咱們直接討論代碼吧。測試

完成與進階

原始代碼

我當時所編寫的代碼以下,代碼已通過測試,可實現題目要求。如今想一想我當時好渣啊,寫的代碼讓如今的我不忍直視。this

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>我點的究竟是誰呢</title>
    <style>
    .node {
        width: 200px;
        height: 50px;
        line-height: 50px;
        background: #ed145b;
        margin-bottom: 10px;
        text-align: center;
        color: #fff;
        cursor: pointer;
    }
    </style>
</head>
<body>
    <div class="node" onclick="showIndex(this);">有本事點我啊</div>
    <div class="node" onclick="showIndex(this);">有本事點我啊</div>
    <div class="node" onclick="showIndex(this);">有本事點我啊</div>
    <div class="node" onclick="showIndex(this);">有本事點我啊</div>
    <div class="node" onclick="showIndex(this);">有本事點我啊</div>
    <!-- 寫五個意思一下就好啦,話說複製粘貼感受好爽啊,根本停不下來!! -->
    <script>
    function showIndex(obj) {
        var oDiv = document.getElementsByTagName("div"),
            count = oDiv.length;
        for (var i = 0; i < count; i++) {
            if (oDiv[i] == obj) {
                alert(i + 1);
            }
        }
    }
    </script>
</body>
</html>

這麼作確實完成了題目所敘述的功能,可是這代碼看起來並不優美。如今來改進一下這渣渣的js代碼,最起碼不要讓事件註冊以onclick這種方式寫在html標籤裏面,看着好不爽呀!code

有一些問題的代碼

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>判斷點擊的是哪一個div</title>
    <style>
    .node {
        width: 200px;
        height: 50px;
        line-height: 50px;
        background: #ed145b;
        margin-bottom: 10px;
        text-align: center;
        color: #fff;
        cursor: pointer;
    }
    </style>
</head>
<body>
    <div class="node">有本事你點我啊</div>
    <div class="node">有本事你點我啊</div>
    <div class="node">有本事你點我啊</div>
    <div class="node">有本事你點我啊</div>
    <div class="node">有本事你點我啊</div>
    <script>
    var oDiv = document.getElementsByClassName("node");
    for (var i = 0; i < oDiv.length; i++) {
        oDiv[i].onclick = function() {
            alert(i);
        }
    }
    </script>
</body>
</html>

本想就這麼矇混過關,可是聰明的讀者在認真看了上面的改進代碼後,必定會一頓@我「你妹啊,運行結果果斷不對啊!」htm

確實不對,由於不管點擊哪一個div彈出的結果都是5。這是爲何呢?我先不解釋,我要賣個關子,我如今要在代碼裏面加入點匿名自執行函數。事件

改進後的代碼

變量的做用域是js的一個很是重要的概念。相信不少同窗理解起來都不是很難,可是也並非說全部人都懂得的東東。不信,看看下面的代碼,解釋一下爲何這麼作就不會有問題了吧。ip

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>判斷點擊的是哪一個div</title>
    <style>
    .node {
        width: 200px;
        height: 50px;
        line-height: 50px;
        background: #ed145b;
        margin-bottom: 10px;
        text-align: center;
        color: #fff;
        cursor: pointer;
    }
    </style>
</head>
<body>
    <div class="node">有本事你點我啊</div>
    <div class="node">有本事你點我啊</div>
    <div class="node">有本事你點我啊</div>
    <div class="node">有本事你點我啊</div>
    <div class="node">有本事你點我啊</div>
    <script>
    var oDiv = document.getElementsByClassName("node");
    for (var i = 0; i < oDiv.length; i++) {
        (function(i) {
            oDiv[i].onclick = function() {
                alert(i);
            }
        })(i)
    }
    </script>
</body>
</html>

就算我不說大家也都知道的事情

當改進過代碼以後,變量i的做用域的發生了改變。以前每一次循環中的變量i都是共享的,可是被包裹起來以後,就彼此獨立咯~問題也就解決咯~喜大普奔啊!

使用一下js類庫吧

上面的原生js當然能夠實現功能,可是不夠精簡。並且不少時候,咱們在工做中都會使用一些js類庫,好比:jQuery,Zpeto(移動端使用)什麼的。因此在此也貼上jQuery實現該功能的代碼。

$('.node').on('click', function(e) {
    alert($(this).index());
});

這樣一來代碼便簡潔了不少,對於擁有代碼潔癖的我來講,這實在是太舒爽了,哈哈哈!

相關文章
相關標籤/搜索