JavaScript事件模型

事件模型是JS里十分重要的一个部分,这两天查询了一些相关资料,用自己的文字记录一下。本文不讨论IE。

事件模型
DOM事件模型

最简单且兼容所有浏览器的事件模型,有两种方式。默认发生在冒泡阶段。

HTML中直接绑定(不推荐)

<button id="button" onclick="click()">ClickMe</button>

JS指定属性值

var button = document.getElementById("button")
button.onclick = function() {
    //...
}

DOM 2级模型
属于W3C标准模型,先事件捕获,到达目标后再进行冒泡。兼容现代浏览器。

//DOM 2级事件第三个参数是一个布尔值(默认为false),true表示捕获阶段调用事件处理程序,false表示冒泡阶段调用事件处理程序。
var button = document.getElementById("button")
button.addEventListener('click', function() {
    //...
}, false)

事件对象
触发DOM上的事件后,会产生一个事件对象event,作为参数传给监听函数。所有的事件都是这个事件对象的示例。

事件对象常用属性
type 被触发的事件的类型
target 事件的目标
currentTarget 注册这个事件监听的对象
事件对象常用方法
preventDefault() 取消事件的默认行为
stopPropagation() 阻止事件继续传播(冒泡和捕获),不包括在当前节点上其他的事件监听函数。
stopImmediatePropagation() 阻止所有事件继续传播,包括在当前节点上其他的事件监听函数。

<body>
	<div id="pop-up-window"></div>
</body>

<script>
	    var body = document.querySelector('body')
        var popUpWindow = document.getElementById('pop-up-window')
        
        body.addEventListener('click', function(e) {
            popUpWindow.style.display = 'none'
        }, false)
        popUpWindow.addEventListener('click', function(e) {
            e.stopPropagation() //在弹窗内部点击时阻止事件传播,因此不会触发body的click事件
        }, false)
</script>

事件委托
借助事件冒泡和事件对象,可以实现事件委托(又叫事件代理)。

先思考如何给下面的按钮都绑定一个click事件,点击后输出按钮的id

    <div id="contiainer">
        <button id="button1">button1</button>
        <button id="button2">button2</button>
        <button id="button3">button3</button>
        <!-- ... -->
        <button id="button10">button10</button>
    </div>

或许你或你以前会这么写

        for (var i = 1; i <= 10; i++) {
            document.getElementById("button" + i).addEventListener('click', function(e) {
                console.log(e.target.id)
            }, false)
        }

每个函数都是对象,都会占用内存,现在创建了10个监听事件,影响了页面性能。我们利用事件委托(又叫事件代理)可以解决这个问题。事件委托借助事件冒泡和事件对象,只需要创建一个监听器,就可以管理一个类型的所有事件。只需要在DOM树尽量最高的层次创建一个监听。

document.getElementById('container').addEventListener('click', function(e) {
           if (e.target.tagName.toLowerCase() === 'button') console.log(e.target.id)
       }, false)

猜你喜欢

转载自blog.csdn.net/qq_35178830/article/details/82831442