现在的很多网站为了用户体验,都会通过 AJAX 动态的加载内容。这些被插入到页面中的元素如果直接绑定事件是无法使用的。下面简单水一下 JavaScript 和 jQuery 给动态添加的元素绑定事件的方式。

原生 JavaScript

下面创建一个 li 并给创建的 li 绑定事件 :

HTML:

<ul>
    <li>第一</li>
    <li>第二</li>
</ul>

JavaScript:

for (var i = 0;i < document.querySelectorAll('li').length;i ++) {
    //  循环给 li 添加点击事件
    document.querySelectorAll('li')[i].onclick = function() {
        alert(this.innerHTML);
    }
}

var newLi = document.createElement('li');  //  创建 li
newLi.innerHTML = '第三';
document.querySelector('ul').appendChild(newLi);  //  把创建的li插入到 ul

上面循环给 li 添加了鼠标点击事件,然后又插入了一个 li

执行结果就是 HTML 中的两个 li 的点击事件可以正常触发,后面插入的 li 的点击事件不能触发。

要解决上面的问题就需要用到事件委托。因为事件冒泡的原因,给父元素绑定事件后点击子元素也能触发父元素的事件。所以这里可以给 ul 绑定事件,点击 li 后也能触发 ul 的事件。

上面的 HTML 不变,稍微改一下 JS 代码:

//  给 ul 绑定点击事件
document.querySelector('ul').onclick = function(ev) {
    //  判断点击的元素是否是 li
    if (ev.target.nodeName.toLocaleLowerCase() == 'li') {
        alert(ev.target.innerHTML);
    }
}

var newLi = document.createElement('li');  //  创建 li
newLi.innerHTML = '第三';
document.querySelector('ul').appendChild(newLi);  //  把创建的li插入到 ul

点击每个按钮都能触发事件。

在元素比较多的情况下,使用事件委托的性能也要比循环添加事件更好。

上面的每个 li 的功能都是一样的。 如果要让每个 li 的功能都不一样的话,可以给 li 添加 idclass ,然后继续通过 event.target 判断 classid

jQuery

下面创建一个 li 并给 li 绑定事件:

HTML:

<ul>
    <li>第一</li>
    <li>第二</li>
</ul>

jQuery:

//  给 li 绑定点击事件
$('li').on('click', function() {
    alert($(this).html());
});

$('ul').append('<li>第三</li>'); //  创建一个 li 插入到 ul 中

结果就是后面插入的元素还是无法触发事件。

这里还是需要用到事件委托,稍微改一下代码:

//  给 ul 绑定点击事件
$('ul').on('click', 'li', function() {
    alert($(this).html());
});

$('ul').append('<li>第三</li>'); //  创建一个 li 插入到 ul 中

上面给 ul 绑定了点击事件。on 的第二个参数就是触发事件的元素。上面触发事件的元素设置为 li ,也就是说每个 li 的功能都是一样的。如果要让 li 的功能不一样,触发事件的元素可以传入 liclassid

相关文章: