zoukankan      html  css  js  c++  java
  • 事件

    何为 DOM 事件,HTML DOM 使JavaScript 有能力对 HTML 事件做出反应。

    1. 事件流

    一个 DOM 事件可以分为捕获过程触发过程冒泡过程
    下面一个<a>元素被点击为例。

    1. 红虚线:捕获过程。当DOM事件发生时,它会从window节点一路跑下去直到触发事件元素的父节点为止,去捕获触发事件的元素。
    2. 红绿实线:触发过程。当事件被捕获之后就开始执行事件绑定的代码。
    3. 绿虚线:冒泡过程。当事件代码执行完毕后,浏览器会从触发事件元素的父节点开始一直冒泡到window元素(即元素的祖先元素也会触发这个元素所触发的事件)。

    看一个例子。

    <!DOCTYPE html>
    <html>
    	<head>		
    		<style></style>
    		<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
    		<script>
    		$(function(){
    			// 捕获过程
    			document.addEventListener('click',function(){
    				console.log('capture:'+1);
    			},true);
    			var tableNode = document.getElementsByTagName('table')[0];
    			tableNode.addEventListener('click',function(){
    				console.log('capture:'+2);
    			},true);
    			var tdNode = tableNode.getElementsByTagName('td');
    			for(let i = 0, tdlength = tdNode.length; i < tdlength; i++){
    				tdNode[i].addEventListener('click',function(){
    					console.log('capture:'+3);
    				},true);
    			}
    			
    			// 冒泡事件
    			document.addEventListener('click',function(){
    				console.log('bubble:'+1);
    			});
    			tableNode.addEventListener('click',function(){
    				console.log('bubble:'+2);
    			});
    			for(let i = 0, tdlength = tdNode.length; i < tdlength; i++){
    				tdNode[i].addEventListener('click',function(){
    					console.log('bubble:'+3);
    				},true);
    			}
    		});
    		</script>
    	</head>
    	<body>
    		<table>
    			<tbody>
    				<tr>
    					<td>Grove</td>
    					<td>Aeolian</td>
    				</tr>
    				<tr>
    					<td>Charlie</td>
    					<td>Dorian</td>
    				</tr>
    			</tbody>
    		</table>
    	</body>
    </html>
    


    每次点击td时触发点击事件,并执行代码console.log('...')
    DOM规范规定,同一节点同一阶段的事件应按照注册函数的顺序执行。

    2. 事件注册

    2.1 注册事件

    eventTarget.addEventListener(type, listener[,useCapture])
    
    • evenTarget表示要绑定事件的DOM元素。
    • type表示要绑定的事件。
    • listener表示要绑定的函数。
    • useCapture可选参数,表示是否捕获过程。

    useCapture为设定是否为捕获过程,默认事件均为冒泡过程,只有useCapturetrue时才会启用捕获过程。

    var tableNode = document.getElementsByTagName('table')[0];
    // 注册事件
    tableNode.addEventListener('click',function(){
    	console.log('capture:'+2);
    },true);
    
    var tableNode = document.getElementsByTagName('table')[0];
    // 注册事件
    tableNode.addEventListener('click', clickHandler,true);
    var clickHandler = function(event) {
    	console.log('capture:'+2);
    };
    
    <!DOCTYPE html>
    <html>
    	<head>		
    		<style></style>
    		<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
    		<script>
    		$(function(){
    			var div = document.getElementsByTagName('div')[0];			
    			//div.onclick = clickHandler;
    			// 注册事件的第二种方式,不推荐使用。
    			div.onclick = function(){
    				clickHandler();
    				foo();
    			  // 其他处理函数
    			};
    
    			function clickHandler(){
    				console.log('clickHandler');
    			}
    
    			function foo(){
    				console.log('foo');
    			}
    		});
    		</script>
    	</head>
    	<body>
    		<div>Hello</div>
    	</body>
    </html>
    

    2.2 取消事件

    eventTarget.removeEventListener(type, listener[,useCapture]);
    
    • evenTarget表示要绑定事件的DOM元素。
    • type表示要绑定的事件。
    • listener表示要绑定的函数。
    • useCapture可选参数,表示是否捕获过程。

    相关阅读:HTML DOM removeEventListener() 方法 | 菜鸟教程

    2.3 触发事件

    点击元素,按下按键均会触发 DOM 事件,当然也可以以通过代码来触发事件。
    看一个例子。

    <form>
      <textarea></textarea>
    </form>
    
    const form = document.querySelector('form');
    const textarea = document.querySelector('textarea');
    
    const eventAwesome = new CustomEvent('awesome', {
      bubbles: true,
      detail: { text: () => textarea.value }
    });
    
    form.addEventListener('awesome', function(e){
    	console.log(e.detail.text());
    });
    
    textarea.addEventListener('input', function(e){
    	e.target.dispatchEvent(eventAwesome);
    });
    


    相关阅读:Creating and triggering events - Developer guides | MDN

    3. 事件对象

    调用事件处理函数时传入的信息对象,这个对象中含有关于这个事件的详细状态和信息,它就是事件对象event。其中可能包含鼠标的位置,键盘信息等。

    <!DOCTYPE html>
    <html>
    	<head>		
    		<style></style>
    		<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
    		<script>
    			function whichButton(event){
    				var btnNum = event.button;
    				if (btnNum==2){
    					console.log("您点击了鼠标右键!")
    				} else if(btnNum==0){
    					console.log("您点击了鼠标左键!")
    				} else if(btnNum==1){
    					console.log("您点击了鼠标中键!");
    				} else{
    					console.log("您点击了" + btnNum + "号键,我不能确定它的名称。");
    				}
    			}
    		</script>
    	</head>
    	<body onmousedown="whichButton(event)">
    		<p>请在文档中点击鼠标。一个消息框会提示出您点击了哪个鼠标按键。</p>
    	</body>
    </html>
    

    相关阅读:HTML DOM Event 对象
    事件对象event的方法:

    • stopPropagation:阻止事件冒泡传播
    • stopImmediatePropagation:阻止冒泡传播
    • preventDefault:阻止默认行为

    event.stopPropagation():如果在当前节点已处理事件,则阻止事件被冒泡传播至 DOM 树最顶端即window对象。
    event.stopImmediatePropagation():除了阻止将事件冒泡传播至window对象外,还会阻止在此事件后的事件的触发。
    默认行为是指浏览器定义的默认行为(点击一个链接时,链接默认就会打开;双击文字的时候,文字就会被选中)。

    4. 事件分类

    <!DOCTYPE html>
    <html>
    	<head>		
    		<style></style>
    		<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
    		<script>
    			function foo(event){ 
    				console.log(event);
    			}
    		</script>
    	</head>
    	<body onmousedown="foo(event)">
    		<p>Click somewhere in the document.</p>
    	</body>
    </html>
    

    • Event
      • UIEvent
        • FocusEvent
        • InputEvent
        • KeyboardEvent
        • MouseEvent
          • WheelEvent

    5. 事件代理

    事件代理是指在父节点上(可为元素最近的父节点也可为上层的其他节点)处理子元素上触发的事件,其原理是通过事件流机制而完成的。可以通过事件对象中获取到触发事件的对象(如下所示)。

    <!DOCTYPE html>
    <html>
    	<head>		
    		<style></style>
    		<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
    		<script>
    		$(function(){
    			document.getElementById('list').addEventListener('click', function (e) {
    			  // 兼容性处理
    			  var event = e || window.event;
    			  var target = event.target || event.srcElement;
    			  console.log(target);
    			  // 判断是否匹配目标元素
    			  if (target.nodeName.toLocaleLowerCase() == 'li') {
    				console.log(target.innerHTML);
    			  }
    			});
    		});
    		</script>
    	</head>
    	<body>
    		<ul id="list">
    			<li>item 1</li>
    			<li>item 2</li>
    			<li>item 3</li>
    			<li>item 4</li>
    			<li>item 5</li>
    		</ul>
    	</body>
    </html>
    

    注意:注册事件时addEventListener需要包含在$(function(){})里面,否则报错。
    相关阅读:$(document).ready和window.onload的区别

    参考:

  • 相关阅读:
    HDU1255 覆盖的面积 —— 求矩形交面积 线段树 + 扫描线 + 离散化
    HDU1542 Atlantis —— 求矩形面积并 线段树 + 扫描线 + 离散化
    HDU1540 Tunnel Warfare —— 线段树 区间合并
    HDU3974 Assign the task —— dfs时间戳 + 线段树
    HDU4027 Can you answer these queries? —— 线段树 区间修改
    POJ3264 Balanced Lineup —— 线段树单点更新 区间最大最小值
    ZOJ1610 Count the Colors —— 线段树 区间染色
    HDU1698 Just a Hook —— 线段树 区间染色
    POJ2528 Mayor's posters —— 线段树染色 + 离散化
    POJ3468 A Simple Problem with Integers —— 线段树 区间修改
  • 原文地址:https://www.cnblogs.com/gzhjj/p/11416884.html
Copyright © 2011-2022 走看看