Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

从事件绑定聊到事件监听,再到事件委托 #16

Open
Jomsou opened this issue Mar 29, 2018 · 0 comments
Open

从事件绑定聊到事件监听,再到事件委托 #16

Jomsou opened this issue Mar 29, 2018 · 0 comments

Comments

@Jomsou
Copy link
Owner

Jomsou commented Mar 29, 2018

经常会遇到JavaScript的事件机制,例如,事件绑定、事件监听、事件委托(事件代理)等。So,what are these?

事件绑定

在JavaScript中,有三种常用的绑定事件的方法:
1、在DOM元素中直接绑定

 <button onclick="greet()">点我</button>
   <script>
        function greet(){
            alert('Hello world!');
        }
   </script> `

2、在JavaScript代码中绑定

<button id="btn1">点我</button>
   <script>
        document.getElementById('btn1').onclick = ()=>{
            alert('Hello world!');
        }
   </script> 

3、绑定事件监听函数

<button id='btn1'>点我</button>
    <script>
        document.getElementById('btn1').addEventListener('click',()=>{
            alert('Hello world!');
        })
    </script>

事件监听

关于事件监听,W3C规范中定义了3个事件阶段,依次是捕获阶段、目标阶段、冒泡阶段。

起初Netscape制定了JavaScript的一套事件驱动机制(即事件捕获)。随即IE也推出了自己的一套事件驱动机制(即事件冒泡)。最后W3C规范了两种事件机制,分为捕获阶段、目标阶段、冒泡阶段。IE8以前IE一直坚持自己的事件机制(前端人员一直头痛的兼容性问题),IE9以后IE也支持了W3C规范。

W3C规范

 element.addEventListener(event, function, useCapture)

event : (必需)事件名,支持所有DOM事件。
function:(必需)指定要事件触发时执行的函数。
useCapture:(可选)指定事件是否在捕获或冒泡阶段执行。true,捕获。false,冒泡。默认false。

IE标准

element.attachEvent(event, function)

event:(必需)事件类型。需加“on“,例如:onclick。
function:(必需)指定要事件触发时执行的函数。

<input type="button" value="click me" id="btn2">
<script>
document.getElementById("btn2").attachEvent("onclick",hello);
function hello(){	
alert("hello world!");
}
</script>

优点

1、可以绑定多个事件。
传统

<input type="button" value="click me" id="btn3">
<script>
    var btn3 = document.getElementById("btn3");
    btn3.onclick = function () {
        alert("hello 1"); //不执行
    }
    btn3.onclick = function () {
        alert("hello 2"); //执行
    }
</script>

事件监听

<input type="button" value="click me" id="btn4">
<script>
    var btn4 = document.getElementById("btn4");
    btn4.addEventListener("click", hello1);
    btn4.addEventListener("click", hello2);
    function hello1() {
        alert("hello 1");
    }
    function hello2() {
        alert("hello 2");
    }
</script>

2、可以解除相应的绑定。

<input type="button" value="click me" id="btn5">
<script>
    var btn5 = document.getElementById("btn5");
    btn5.addEventListener("click", hello1);//执行了
    btn5.addEventListener("click", hello2);//不执行
    btn5.removeEventListener("click", hello2);
    function hello1() {
        alert("hello 1");
    }
    function hello2() {
        alert("hello 2");
    }
</script>

封装事件监听

 <input type="button" value="click me" id="btn5">
    <script>
        //绑定监听事件 
        function addEventHandler(target, type, fn) {
            if (target.addEventListener) {
                target.addEventListener(type, fn);
            } else {
                target.attachEvent("on" + type, fn);
            }
        } //移除监听事件 
        function removeEventHandler(target, type, fn) {
            if (target.removeEventListener) {
                target.removeEventListener(type, fn);
            } else {
                target.detachEvent("on" + type, fn);
            }
        } //测试 
        var btn5 = document.getElementById("btn5");
        addEventHandler(btn5, "click", hello1); //添加事件hello1 addEventHandler(btn5,"click",hello2);//添加事件hello2 removeEventHandler(btn5,"click",hello1);//移除事件hello1
    </script>

事件委托

事件委托就是利用冒泡的原理,把事件加到父元素或祖先元素上,触发执行效果。

<ul id="parent-list">
    <li id="post-1">Item 1</li>
    <li id="post-2">Item 2</li>
    <li id="post-3">Item 3</li>
    <li id="post-4">Item 4</li>
    <li id="post-5">Item 5</li>
    <li id="post-6">Item 6</li>
</ul>
   <script>
       document.getElementById("parent-list").addEventListener("click", function(e) {
	// e.target is the clicked element!
	// If it was a list item
	if(e.target && e.target.nodeName == "LI") {
		// List item found!  Output the ID!
		console.log("List item ", e.target.id.replace("post-", ""), " was clicked!");
	}
});
   </script> 

优点

1、提高JavaScript性能。事件委托可以显著的提高事件的处理速度,减少内存的占用。

<ul id="list">
    <li id="item1">item1</li>
    <li id="item2">item2</li>
    <li id="item3">item3</li>
</ul>
<script>
    var item1 = document.getElementById("item1");
    var item2 = document.getElementById("item2");
    var item3 = document.getElementById("item3");
    document.addEventListener("click", function (event) {
        var target = event.target;
        if (target == item1) {
            alert("hello item1");
        } else if (target == item2) {
            alert("hello item2");
        } else if (target == item3) {
            alert("hello item3");
        }
    })
</script>

2、动态的添加DOM元素,不需要因为元素的改动而修改事件绑定。

<ul id="list">
    <li id="item1">item1</li>
    <li id="item2">item2</li>
    <li id="item3">item3</li>
</ul>
<script>
    var list = document.getElementById("list");
    document.addEventListener("click", function (event) {
        var target = event.target;
        if (target.nodeName == "LI") {
            alert(target.innerHTML);
        }
    })
    var node = document.createElement("li");
    var textnode = document.createTextNode("item4");
    node.appendChild(textnode);
    list.appendChild(node);
</script>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant