以下代码出自《DOM Enlightenment》一书
1.三种事件形式
1 <body onclick="alert('触发内联属性事件')"> 2 <div>click me</div> 3 </body> 4 <script> 5 var div = document.querySelector('div'); 6 7 div.onclick = function() { 8 alert("触发属性事件"); 9 }; 10 11 div.addEventListener('click', function() { 12 alert('触发addEventListener'); 13 }, false); 14 </script>
2.事件流程
先捕获后冒泡
捕获:从树主干到分支
冒泡:从树分支到主干
1 <html> 2 <body> 3 <div>click me to start event flow</div> 4 </body> 5 </html> 6 <script> 7 // 捕获阶段 window 8 window.addEventListener('click', function() { 9 alert(1); 10 }, true); 11 12 // 捕获阶段 document 13 document.addEventListener('click', function() { 14 alert(2); 15 }, true); 16 17 // 捕获阶段 html 18 document.documentElement.addEventListener('click', function() { 19 alert(3); 20 }, true); 21 22 // 捕获阶段 body 23 document.body.addEventListener('click', function() { 24 alert(4); 25 }, true); 26 27 // 捕获阶段 div 28 document.querySelector('div').addEventListener('click', function() { 29 alert(5); 30 }, true); 31 32 // 冒泡阶段 div 33 document.querySelector('div').addEventListener('click', function() { 34 alert(6); 35 }, false); 36 37 // 冒泡阶段 body 38 document.body.addEventListener('click', function() { 39 alert(7); 40 }, false); 41 42 // 冒泡阶段 html 43 document.documentElement.addEventListener('click', function() { 44 alert(8); 45 }, false); 46 47 // 冒泡阶段 document 48 document.addEventListener('click', function() { 49 alert(9); 50 }, false); 51 52 // 冒泡阶段 window 53 window.addEventListener('click', function() { 54 alert(10); 55 }, false); 56 57 </script>
3.移除事件
1 <body> 2 <div>click to say hi</div> 3 </body> 4 <script> 5 var sayHi = function() { 6 alert('hi'); 7 }; 8 document.querySelector('div').addEventListener('click', sayHi, false); 9 10 document.querySelector('div').removeEventListener('click', sayHi); 11 12 document.body.addEventListener('click', function() { 13 alert('hello'); 14 }, false); 15 16 // 不是同一个回调,是不起作用的 17 document.body.removeEventListener('click', function() { 18 alert('hello'); 19 }); 20 </script>
4.事件状态对象
1 <body> 2 <div>click me</div> 3 </body> 4 <script> 5 document.querySelector('div').addEventListener('click', function(event) { 6 console.dir(event); 7 }, false); 8 9 window.addEventListener('load', function(event) { 10 console.dir(event); 11 }, false); 12 </script>
5.监听函数this指向
this指向绑定事件的节点,即event.currentTarget属性
1 <body> 2 <div>click me</div> 3 </body> 4 <script> 5 document.body.addEventListener('click', function(event) { 6 alert(this); 7 alert(this == event.currentTarget) 8 }); 9 </script>
6.获取事件触发元素(事件源头)
1 <body> 2 <div>click me</div> 3 </body> 4 <script> 5 document.body.addEventListener('click', function(event) { 6 alert(event.target); 7 }); 8 </script>
7.阻止默认事件
1 <body> 2 <a href="http://www.baid.com">链接</a> 3 <input type="checkbox"/> 4 <textarea></textarea> 5 </body> 6 <script> 7 8 // 点击链接时,阻止跳转 9 document.querySelector('a').addEventListener('click', function(e) { 10 e.preventDefault(); 11 }); 12 13 // 点击复选框时,阻止选中 14 document.querySelector('input').addEventListener('click', function(e) { 15 e.preventDefault(); 16 }); 17 18 // 在文本框中尝试输入字符时,阻止输入(使用输入法时,不一定会触发keypress事件) 19 document.querySelector('textarea').addEventListener('keypress', function(event) { 20 event.preventDefault(); 21 }); 22 </script>
8.阻止事件冒泡
1 <body> 2 <div>click</div> 3 </body> 4 <script> 5 document.querySelector('div').addEventListener('click', function(e) { 6 alert('div'); 7 e.stopPropagation(); 8 }); 9 document.body.addEventListener('click', function() { 10 alert('body'); 11 }); 12 </script>
9.阻止冒泡和其他相同事件监听器
1 <body> 2 <div>click</div> 3 </body> 4 <script> 5 document.querySelector('div').addEventListener('click', function(e) { 6 alert(1); 7 }); 8 document.querySelector('div').addEventListener('click', function(e) { 9 alert(2); 10 e.stopImmediatePropagation(); 11 }); 12 document.querySelector('div').addEventListener('click', function(e) { 13 alert(3); 14 }); 15 document.body.addEventListener('click', function() { 16 alert('body'); 17 }); 18 </script>
10.自定义事件
1 <body> 2 <div>click</div> 3 </body> 4 <script> 5 var customEvent = document.createEvent('CustomEvent'); 6 // 参数是:name,bubble,cancelable,detail 7 customEvent.initCustomEvent('hello', true, false,{ 8 msg: 'hello' 9 }); 10 var div = document.querySelector('div'); 11 div.addEventListener('click', function() { 12 alert('click'); 13 this.dispatchEvent(customEvent); 14 }) 15 div.addEventListener('hello', function(e) { 16 alert(e.detail.msg); 17 }) 18 </script>
11.模拟鼠标点击事件
1 <body> 2 <div>自动触发</div> 3 </body> 4 <script> 5 var div = document.querySelector('div'); 6 div.addEventListener('click', function() { 7 alert('click'); 8 }) 9 10 var autoClick = document.createEvent('MouseEvent'); 11 // 参数是: name,bubble,cancelable,view,detail,screenx,screeny,clientx,clienty,ctrlkey,altkey,shiftkey,metakey,button,relatedTarget 12 autoClick.initMouseEvent('click', true, true, document.defaultView,0,0,0,0,0,false,false,false,0,null,null); 13 div.dispatchEvent(autoClick); 14 </script>
12.事件委托
1 <p>点击某个单元格</p> 2 <table border="1"> 3 <tr> 4 <td>row 1 col 1</td> 5 <td>row 1 col 2</td> 6 </tr> 7 <tr> 8 <td>row 2 col 1</td> 9 <td>row 2 col 2</td> 10 </tr> 11 <tr> 12 <td>row 3 col 1</td> 13 <td>row 3 col 2</td> 14 </tr> 15 <tr> 16 <td>row 4 col 1</td> 17 <td>row 4 col 2</td> 18 </tr> 19 </table> 20 <script> 21 document.querySelector('table').addEventListener('click', function(event) { 22 if (event.target.tagName.toLowerCase() == 'td') { 23 alert(event.target.textContent); 24 } 25 });