• javascript高级程序设计笔记-第十三章(事件)


    一、事件流

    事件流包括三个阶段:事件捕获阶段、处于目标阶段、时间冒泡阶段。

    如图:捕获阶段是逐级向下,由不具体到具体节点;冒泡阶段是逐级向上传播到不具体的节点

    二、事件处理程序

    1、HTML事件处理程序

    通过使用一个与相应事件处理程序同名的HTML特性来指定

    <input type="button" value="click" onclick="alert('hi')">
    

    2、DOM0级事件处理程序

    将一个函数赋值给一个事件处理程序属性(每个元素都有自己的事件处理程序属性)

    var btn = document.getElementById("myBtn");
    btn.onclick = function() {
    	alert("hi");
    };
    

    使用DOM0级方法指定的事件处理程序是元素的方法。因此,这时候的事件处理程序是在元素的作用域中运行,即this引用当前的元素

    var btn = document.getElementById("myBtn");
    btn.onclick = function() {
    	alert(this.id);
    };
    

    删除事件处理程序

    btn.onclick = null;
    

    3、DOM2级事件处理程序

    addEventListener()removeEventListener()用于处理指定和删除事件处理程序的操作。接收3个参数:事件名、事件处理函数、布尔值。如果布尔值是true,表示在捕获阶段调用事件处理程序;如果是false,表示在冒泡阶段调用事件处理程序。

    var btn = document.getElementById('myBtn');
    btn.addEventListener("click", function() {
    	alert(this.id);
    }, false);
    //事件处理程序是在元素的作用域中运行,即this引用当前的元素
    

    通过addEventListener()添加的事件处理程序只能用removeEventListener()移除;移除时传入的参数与添加处理程序时使用的参数相同。(添加的匿名函数无法移除)

    var btn = document.getElementById('myBtn');
    btn.addEventListener("click", function() {
    	alert(this.id);
    }, false);
    btn.removeEventListener("click", function() {
    	alert(this.id);
    }, false);		//无效
    
    //将匿名函数赋值给变量
    var btn = document.getElementById('myBtn');
    var handler = function() {
    	alert(this.id);
    };
    btn.addEventListener("click", handler, false);
    btn.removeEventListener("click", handler, false);	//有效
    

    4、IE事件处理程序(IE8及更早版本)

    attachEvent()detachEvent(),接收2个参数:事件名、事件处理函数

    除了事件处理程序的作用域不一样外,其他类似。IE事件处理程序在全局作用域中运行

    var btn = document.getElementById('myBtn');
    var handler = function() {
    	alert(this === window);
    };
    btn.attachEvent("onclick", handler);	//true
    btn.detachEvent("onclick", handler);
    

    5、跨浏览器的事件处理程序

    var EventUtil = {
    	addHandler: function(element, type, handler) {
    		if (element.addEventListener) {
    			element.addEventListener(type, handler, false);
    		} else if (element.attachEvent) {
    			element.attachEvent("on" + type, handler);
    		} else {
    			element["on" + type] = handler;
    		}
    	},
    	removeHandler: function(element, type, handler) {
    		if (element.removeEventListener) {
    			element.removeEventListener(type, handler, false);
    		} else if (element.detachEvent) {
    			element.detachEvent("on" + type, handler);
    		} else {
    			element["on" + type] = null;
    		}
    	}
    };
    
    //使用EventUtil对象
    var btn = document.getElementById('myBtn');
    var handler = function() {
    	alert("hi");
    };
    EventUtil.addHandler(btn, "click", handler);
    

    三、事件对象

    1、DOM中的事件对象

    在事件处理程序内部,对象this始终等于currentTarget的值,而target则只包含事件的实际目标

    如果将事件处理程序指定给了目标元素,则this、currentTarget、target包含的值相同

    var btn = document.getElementById('myBtn');
    btn.onclick = function(event) {
    	alert(this === event.currentTarget);	//true
    	alert(this === event.target);			//true
    };
    

    如果事件处理程序存在于父节点中,单击当前元素时

    var btn = document.getElementById('myBtn');
    document.body.onclick = function(event) {
    	alert(document.body === event.currentTarget);	//true
    	alert(document.body === this);					//true
    	alert(btn = event.target);						//true
    };
    

    使用type属性,通过一个函数处理多个事件

    var btn = document.getElementById('myBtn');
    var handler = function(event) {
    	switch(event.type) {
    		case "click":
    			alert("hi");
    			break;
    		case "mouseover":
    			event.target.style.backgroundColor = "red";
    			break;
    		case "mouseout":
    			event.target.style.backgroundColor = "";
    			break;
    	}
    };
    
    btn.onclick = handler;
    btn.onmouseover = handler;
    btn.onmouseout = handler;
    

    preventDefault()方法,阻止特定事件的默认行为(只有在cancelable属性为true时才能使用)

    var link = document.getElementById('myLink');
    link.onclick = function(event) {
    	event.preventDefault();
    };
    

    stopPropagation()方法,取消事件的进一步捕获和冒泡(只有在cancelable属性为true时才能使用)

    var btn = document.getElementById('myBtn');
    btn.onclick = function(event) {
    	alert("hi");
    	event.stopPropagation();
    };
    document.body.onclick = function(event) {
    	alert("hi again");
    };
    //如果不使用stopPropagation(),单击按钮时,就会先后出现两次警告框
    

    2、IE中的事件对象

    在使用DOM0级方法添加事件处理程序时,event对象作为window对象的一个属性存在。即window.event

    var btn = document.getElementById('myBtn');
    btn.onclick = function(event) {
    	var event = window.event;
    	alert(event.type);
    };
    //通过window.event取得event对象
    

    使用attachEvent()添加事件处理程序时,event对象作为参数被传入事件处理函数

    var btn = document.getElementById('myBtn');
    btn.attachEvent("onclick", function(event) {
    	alert(event.type);
    });
    

    srcElement属性,表示事件的目标(与DOM中的target属性相同)

    var btn = document.getElementById('myBtn');
    btn.onclick = function() {
    	alert(window.event.srcElement === this);	//true
    };
    //都指向btn元素
    btn.attachEvent("onclick", function(event) {
    	alert(event.srcElement === this);			//false
    });
    //event.srcElement指向btn元素,this指向全局作用域window
    

    returnValue属性,默认为true,设置为false时可以取消事件的默认行为(与DOM中的preventDefault()方法相同)

    var link = document.getElementById('myLink');
    link.onclick = function() {
    	window.event.returnValue = false;
    };
    

    cancelBubble属性,与DOM中的stopPropagation()方法类似,默认为false,设置为true时可以取消事件的冒泡

    var btn = document.getElementById('myBtn');
    btn.onclick = function() {
    	alert("hi");
    	window.event.cancelBubble = true;
    };
    document.body.onclick = function() {
    	alert("hi again");
    };
    //设置为true,单击按钮,只显示一个警告框
    

    3、跨浏览器的事件对象

    var EventUtil = {
    	getEvent: function(event) {					//取得event对象
    		return event ? event : window.event;
    	},
    	getTarget: function(event) {				//取得事件的目标
    		return event.target || event.srcElement;
    	},
    	preventDefault: function(event) {			//阻止事件的默认行为
    		if (event.preventDefault) {
    			event.preventDefault();
    		} else {
    			event.returnValue = false;
    		}
    	},
    	stopPropagation: function(event) {			//阻止事件流
    		if (event.stopPropagation) {
    			event.stopPropagation();
    		} else {
    			event.cancelBubble = true;
    		}
    	}
    };
    

    四、事件委托

    只指定一个事件处理程序,就可以管理某一类型的所有事件

    <ul id="myLinks">
    	<li id="dosomething">do something</li>
    	<li id="gosomewhere">go somewhere</li>
    	<li id="sayhi">say hi</li>
    </ul>
    

    传统:

    var item1 = document.getElementById('dosomething');
    var item2 = document.getElementById('gosomewhere');
    var item3 = document.getElementById('sayhi');
    
    EventUtil.addHandler(item1, "click", function(event) {
    	document.title = "other title";
    });
    EventUtil.addHandler(item2, "click", function(event) {
    	location.href = "http://baidu.com";
    });
    EventUtil.addHandler(item3, "click", function(event) {
    	alert("hi");
    });
    

    事件委托:

    var list = document.getElementById('myLinks');
    EventUtil.addHandler(list, "click", function(event) {
    	event = EventUtil.getEvent(event);
    	var target = EventUtil.getTarget(event);
    	switch(target.id) {
    		case "dosomething":
    			document.title = "other title";
    			break;
    		case "gosomewhere":
    			location.href = "http://baidu.com";
    			break;
    		case "sayhi":
    			alert("hi");
    			break;
    	}
    });
  • 相关阅读:
    Tomcat 7 自动加载类及检测文件变动原理
    ElasticSearch查询
    ElasticSearch集群的基本原理
    ElasticSearch基础
    hbase时间不同步问题引起的bug
    IDEA运行异常java.lang.NoClassDefFoundError: org/apache/spark/api/java/function/Function
    spark任务提交之SparkLauncher
    spark调优(二)-Apache Spark 内存管理详解
    spark调优(一)-开发调优,数据倾斜,shuffle调优
    spark内核源码深度剖析(1)--Spark内核架构深度剖析
  • 原文地址:https://www.cnblogs.com/u14e/p/5257973.html
Copyright © 2020-2023  润新知