JavaScript事件学习笔记

一、事件流

    理解事件冒泡(event bubbling)和事件捕获(event capturing),这个不难。

    “DOM2级事件” 规定的事件流包括:事件捕获阶段、处于目标阶段和事件冒泡阶段。事件将从document传到目标元素的前一个(事件捕获阶段)元素,然后到达目标元素(处于目标阶段),目标元素的句柄开始执行时,就冒泡(事件冒泡阶段);

二、事件处理程序/侦听器/listener

1.HTML事件处理程序

    顾名思义就是写在html文档上的handler。比如:

<input type="button" value="点我" onclick="alert("clicked")"></input>   //示例1

要知道这种方式现在因为结构样式功能分离、存在“时差”、难以管理的原因已经很少被使用了,但还是要好好理解一下:某种元素支持的每种事件,都可以使用一个与相应事件处理程序同名的 HTML特性来制定。这里是onclick特性。

要知道“DOM0级事件”中使用“on” 加 “事件名”来确定相应事件的句柄,下面就是将一个匿名函数指定给click事件的句柄。

var oBtn = document.getElementById('btn');
oBtn.onclick = function(){
   //body...
}

接着深入理解一下那这句简单的 οnclick="alert("username.value"),

<form method="post">
  <input type="text" name="username" value="">
  <input type="button" value="Echo username" onclick="alert(username.value)">
</form>

相当于下面这个函数,使用with扩展了作用域,使得它这个局部函数得以访问页面中其他位置的元素,所以它可以在alert里面直接引用username元素。

function(){
 with(document){
  with(this.form){
   with(this){
     //body..
   }
  }
 }

}

2.DOM0级事件处理程序

3.DOM2级事件处理程序

addEventListener(type, handler, t/f);   removeEventListener(type, handler, t/f)

4.IE事件处理程序

attachEvent("on" + type, handler);detachEvent("on" + type, handler);

三、事件对象(event)

var event = event || window.event;

像实现什么拖拽效果、碰撞检测和做什么小游戏之类的很多东西都需要这个对象。更详细的看书,兼容的看下面。

//JavaScript Document
//兼容事件在IE和标准中的差异
var EventUtil = {
	//为事件添加侦听器,主要兼容标准IE、DOM0、DOM2
	addHandler: function(element, type, handler) {
		if(element.addEventListener){
			element.addEvenListener(type, handler, false); //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;
		}
	},

	//阻止默认行为
	preventDefault: function(event) {
		if (event.preventDefault) {
			event.preventDefault();	
		} else {
			event.returnValue = false;
		}
	},

	//阻止冒泡
	stopPropagation: function(event) {
		if (event.stopPropagation) {
			event.stopPropagation();
		} else {
			event.cancleBubble = true;
		}
	},

	//鼠标事件中按了哪些键;IE和标准虽然使用相同的属性但是属性值不一样,这里按标准
	getButton: function(event) {
		if (document.implementation.hasFeature("MouseEvents", "2.0")) {
			return event.button;
		} else {
			switch(event.button){
				case 0:
				case 1:
				case 3:
				case 5:
				case 7:
					return 0;
				case 2:
				case 6:
					return 2;
				case 4: 
					return 1;
			}
		}
	},

	//获得键盘事件中按下的是哪些键
	getCharCode: function(event) {
		if (typeof event.charCode == "number") {
			return event.charCode;
		} else {
			return event.keyCode;
		}
	},

	getEvent: function(event){
		return event ? event : window.event;
	},

	getTarget: function(event) {
		return event.target || event.srcElement;
	},

	getRelatedTarget: function(event) {
		if (event.relatedTarget) {
			return event.relatedTarget;
		} else if (event.toElement){
			return event.toElement;
		} else if (event.fromElement){
			return event.fromElement;
		}else {
			return null;
		}
	},

	getWheelDelta: function(event) {
		if (event.wheelDelta){
			return (client.engine.opera && client.engine.opera < 9.5 ? -event.wheelDelta : event.wheelDelta);   //这是另一个文件中return出来的判断客户端的对象
		}else {
			return -event.detail * 40;  //针对Firefox的实现差异进行兼容
		}
	},

	getClipboardText: function(event) {
		var clipboardData = event.clipboardData || window.clipboardData;
		return clipboardData.getData("text");
	},

	setClipboardText: function(event, value) {
		if(event.clipboardData){
			event.clipboardData.setData("text/plain", value);
		}else if (window.clipboardData){
			window.clipboardData.setData("text", value);
		}
	}
}

四、事件类型

1.UI事件:

当用户与页面上的元素交互时触发。(load、unload、abort(用户停止下载过程时,如果嵌入的内容没有加载完,则在<object>元素上面触发)、error、select、resize、scroll)

2.焦点事件:

当元素获得或失去焦点时。(blur、focus、 focusin、focusout。前两者不冒泡,后两者冒)

3.鼠标与滚轮事件

4.键盘与文本事件

 keydown和keypress的区别是:前者是按下任意键是触发,而后者是按下键盘上的字符键时触发

keydown和keypress都是在文本框发生变化之前,而唯一一个文本事件textInput是在文本插入文本框之前会触发,用意是在将文本显示给用户之前更容易拦截文本。(按下之后,显示之前)。

与textInput相关的有event.data 和 event.inputMethod

5.复合事件(DOM3级事件,支持不多,用处不大)

IME:Input Method Editor。可以让用户输入在物理键盘上找不到的字符。

1) compositionstart   IME的文本复合系统打开时触发

2) compositionupdate 向输入字段插入新字符时触发

3) compositionend  与1)相反

可通过以下检测

var isSupported = document.implementation.hasFeature("CompositonEvent", "3.0");

6.变动事件(mutation)

删除节点的:DOMNodeRemove(将要删除这个节点,会冒泡)---------DOMNodeRemovedFromDocument(不冒泡)--------------DOMSubtreeModified(DOM结构中发生任何变化时,在其他任何事件之后触发)

插入节点:DOMNodeInserted(已经插入到了新的父节点中,所以event.relatedNode包含对这个父节点的引用,会冒泡)----------------DOMNodeInsertedIntoDocument(不冒泡,event对象不包含任何信息)------------------DOMSubtreeModified

7.HTML5事件

contextmenu事件(右键菜单)我们可以通过阻止默认事件的发生来自定义右键菜单

beforeunload事件,我在写博客时草稿箱会自动保存,当我关闭页面想要离开时就会弹出这样一个对话框,让我在页面卸载前可以阻止这个卸载操作,但是我们不能彻底取消这个事件,因为那就意味着用户无法离开这个页面了,所以它把决定权交给我们,弹出一个询问对话框确认我们的下一步操作。应该是这样做:

window.addEventListener('beforeunload', function(event){
 var message = '确认放弃此文章\n确认要离开此页?';
 event.returnValue = message;
 return message;
});

DOMContentLoaded(在形成完整的DOM树之后触发,不理会图像、JavaScript文件、CSS文件或者其它资源是否已经下载完毕。比load快了一步)对于不支持这个事件的浏览器可以使用0毫秒的setTimeOut,可这也没办法完全保证与该事件,只是一个折中的方法。原因就是:在页面下载和构建期间,只有一个JavaScript处理过程,因此这个超时调用会在该过程结束后立即触发。

readystatechange  绑定该事件的对象会有一个属性readyState(uninitialized, loadinng, loaded, interactive, complete)

hashchange  hash:URL中“#” 后面的所有字符串,适用于Ajax应用中用来保存状态或者导航信息。(event.oldValue/newValue).

8.设备事件和触摸与手势事件很复杂,将在后面作为独立的一篇文章进行详细阐述。。。

五、内存和性能

尽量使用事件委托(事件冒泡),移除不再需要的句柄来使内存的使用保持在畅通的状态。

这样子就可以节省内存中的两个对象单位。

<ul id="myLink">
	<li id="a">a</li>
	<li id="b">b</li>
	<li id="c">c</li>
</ul>

var oMyList = document.getElementById('myList');
oMyList.onclick = function(event) {
	var event = event || window.event;
	var target = event.target || event.srcElement;

	switch(target.id){
		case 'a':
			alert("a");
		case 'b':
			alert("b");
		case 'c':
			alert("c");
	}
}

六、模拟事件

。。。

转载于:https://my.oschina.net/whirly77cai/blog/713522

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值