1. 程式人生 > >JavaScript 從入門到放棄(一)事件委托和使用innerHTML添加元素

JavaScript 從入門到放棄(一)事件委托和使用innerHTML添加元素

ont ntb innerhtml col 添加元素 pan div 基本 開發

一、使用事件委托

一個簡單的需求,比如想給ul下面的li加上點擊事件,點擊哪個li,就顯示那個li的innerHTML。這個貌似很簡單!代碼如下!

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<ul id="ul-test">
    <li>0</li>
    <li>1</li>
    <li>
2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> <li>7</li> <li>8</li> <li>9</li> </ul> </body> <script type="text/javascript"> var $ul = document.getElementById(ul-test
); var $li = $ul.getElementsByTagName(li); for (var i = 0, $len = $li.length; i < $len; i++) { $li[i].addEventListener(click,function () { alert(this.innerHTML); }) } </script> </html>

很簡單,這樣就實現了,實際上這裏有坑,也待優化!
1.for循環,循環的是li,10個li就循環10次,綁定10次事件,100個就循環了100次,綁定100次事件!


2.如果li不是本來就在頁面上的,是未來元素,是頁面加載了,再通過js動態加載進來了,上面的寫法是無效的,點擊li是沒有反應的!
所以就者需要用事件委托(即使不考慮上面的第二種情況,也是建議使用事件委托)!代碼如下:

<script type="text/javascript">
    var $_ul = document.getElementById("ul-test");
    $_ul.addEventListener("click", function (ev) {
        var $ev = ev || window.event;
        var target = $ev.target || $ev.srcElement;
        //如果點擊的最底層是li元素
        if (target.tagName.toLowerCase() === ‘li‘) {
            alert(target.innerHTML)
        }
    })
</script>

這樣寫,即使是動態添加進來的li點擊也有反應,還有一個就是ul只有一個,事件綁定在ul上,無論li多少個,都是添加一次事件!但是也是可能會有問題,如果li下面還有子元素,那麽點擊的時候,target可能不是li,而是鼠標點擊那個位置的最底層元素!如下圖,如果鼠標點擊白色區域,那個target就是body元素,鼠標點擊綠色區域target就是div元素,鼠標點擊藍色區域target就是ul,點擊橙色就是li。

技術分享

二、使用innerHTML添加元素

1、createElement方式創建

<ul id="ul-test">

</ul>

<script type="text/javascript">
    var $_ul = document.getElementById("ul-test");
    //createElement方式
    console.time();
    for(var i =0;i<10;i++){
        var $li = document.createElement(li);
        $li.innerHTML = i;
        $_ul.appendChild($li);
    }
    console.timeEnd();
</script>

註意:console.timeconsole.timeEnd這兩個方法可以用來讓WEB開發人員測量一個javascript腳本程序執行消耗的時間。

耗時:ul-test: 0.18603515625ms

2、innerHTML方式創建

<ul id="ul-test2">

</ul>
<script type="text/javascript">
    var $_ul = document.getElementById("ul-test2");
    //innerHTML方式
    console.time(ul-test2);
    var _html=‘‘;
    for(var i=0;i<10;i++){
        _html+=<li>+i+</li>
    }
    $_ul.innerHTML=_html;
    console.timeEnd(ul-test2);
</script>

耗時:ul-test2: 0.0849609375ms

兩個耗時對比:

技術分享

  發現基本是第二種方式更快,第8點也說了,DOM操作能少就少!第一種要操作10次DOM,第二種只需要操作1次DOM。還有一個就是,這個只是很簡單的li,如果是下面的列表呢?用第一種方式,得createElement多少次,innerHTML多少次,appendChild多少次?代碼多,各個節點的邏輯和嵌套關系也亂!用第二種方式就是一個拼接字符串的操作,比第一種方式好多了,如果用es6的模板字符串,就更簡單了!

javascript實用技巧和寫法建議

JavaScript 從入門到放棄(一)事件委托和使用innerHTML添加元素