js-事件
事件:
1、事件冒泡:即事件开始由最具体的元素(文档中嵌套最深的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档)。
<div>--à<body>-à<html>---àdocument
2、事件捕获:不太具体的节点应该更早接收到事件,在事件到达预定目标之前捕获它
Document-à<html>-à<body>-à<div>
3、事件处理程序的名字以“on”开头
1) HTML事件处理程序
A:可以通过event变量可以直接访问事件对象
/*输出“click”*/
<input type="button" value="Click Me" onclick="alert(event.type)">
/*输出"Click Me" this值等于事件的目标元素 */
<input type="button" value="Click Me" onclick="alert(this.value)">
/*输出"Click Me" */
<input type="button" value="Click Me" onclick="alert(value)">
B;扩展作用域,eg:如果当前的元素是一个表单元素,作用域还会包含访问表单元素的入口
function(){
with(document){
with(this.form){
with(this){
//元素的属性值
}
}
}
}
这样就让事件处理程序无需引用表单元素就可以访问其他表单字段
<form method="post">
<input type="text" name="username" value="">
<input type="button" value="Echo Username" onclick="alert(username.value)">
</form>
2) DOM0级事件处理程序
A:this引用的是当前元素
var btn=document.getElementById("myBtn");
btn.onclick=function(){
alert(this.id); //"myBtn"
}
B:删除通过DOM0级方法指定的事件处理程序
btn.onclick=null;
3) DOM2级事件处理程序
A:处理指定和删除事件处理程序的操作:addEventListener()和removeEventListener(),所有的DOM节点都包含这两个方法,接受3个参数,要处理的事件名,作为事件处理程序的函数,一个布尔值;最后的布尔值参数为true表示在捕获阶段调用事件处理程序,如果是false,在冒泡阶段调用事件处理程序
B:可以添加多个事件处理程序
var btn=document.getElementById("myBtn");
btn.addEventListener("click",function(){
alert(this.id);
},false);
btn.addEventListener("click",function(){
alert("hello world");
},false);
C:在移除事件处理程序时,参数与添加事件处理程序的函数是应该是要一样的,
无效的:
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");
btn.addEventListener("click",handler,false);
btn.removeEventListener("click",handler,false);
D:IE实现了与DOM中类似的两个方法:attachEvent()以及detachEvent(),接收两个相同的参数,事件处理程序名称以及事件处理函数
attachEvent()--为元素添加一个事件处理程序:
var btn=document.getElementById("myBtn");
btn.attachEvent("onclick",function(){
alert("clicked");
})
E:DOM0级方法,事件处理程序会在其所属元素的作用域内运行,attachEvent()方法下,事件处理程序会在全局作用域中运行,因此this等于window
F:在为一个元素添加多个事件处理程序的时候,与DOM方法不一样,不是以添加顺序执行,而是以相反的顺序触发
4、跨浏览器的事件处理程序:EventUtil对象:下面有两个方法
A:addHandler()方法:视情况而定,分别使用DOM0,DOM2,或IE方法添加事件,接收3个参数-----传入事件类型,事件处理程序函数,false(在冒泡阶段);默认添加方式是DOM0
B:
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;
}
}
};
var btn=document.getElementById("myBtn");
var handler=function(){
alert("Clicked");
};
EventUtil.addHandler(btn, "click", handler);
EventUtil.removeHandler(btn, "click", handler);
5、DOM事件对象:
A:click事件对象;mouseover事件对象;mouseout事件对象;
var btn=document.getElementById("myBtn");
var handler=function(event){
switch(event.type){
case "click":
alert("clicked");
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;
B:event.type检测事件属性
C:阻止特定事件的默认行为:preventDefault()方法,在cancelable(是否可以取消事件的默认行为)等于true的情况下才可以使用。
var link =document.getElementById("myLink");
link.onclick=function(event){
event.preventDefault();
};
E:stopPropagation()方法用于立即停止事件在DOM层次中传播,取消进一步的事件捕获或冒泡
var btn=document.getElementById("myBtn");
btn.onclick=function(event){
alert("clicked");
event.stopPropagation();
}
document.body.onclick=function(event){
alert("body clicked");
};
6、IE中的事件对象
A:var btn=document.getElementById("myBtn");
btn.attachEvent("onclick",function(event){
alert(event.type); });
B:
cancelBubble ---默认值是false,取消事件冒泡,与DOM中的stopPropagation作用相同
returnValue---默认值是true,将其设置为true就可以取消事件的默认行为,与DOM中的preventDefault()方法作用相同
srcElement---事件的目标,与target属性相同
type---被触发事件的类型
7、跨浏览器的事件对象:
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;
}
},
getEvent:function(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;
}
},
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;
}
}
stopPropagation:function(event){
if(event.stopPropagation){
event.stopPropagation();
}else{
event.cancelBubble=true;
}
}
};
btn.onclick=function(event){
event=EventUtil.getEvent(event); -----传出的是window.event
}
btn.onclick=function(event){
event=EventUtil.getEvent(event);
var target=EventUtil.getTarget(event);
};
8、事件类型:
A:UI事件:当用户与页面上的元素交互时触发
焦点事件:当元素获得或失去焦点时的触发
鼠标事件:当用户通过鼠标在页面上执行操作的时候
滚轮事件:当使用鼠标滚轮时触发
文本事件:在文档中输入文本时触发
键盘事件:当用户通过键盘在页面上执行操作时触发
合成事件:当为IME(输入法编辑器)输入字符时触发
变得事件:当底层DOM结构发生变化时触发
B:UI事件
load:当页面完全加载后在window上面触发
unload:当页面完全卸载后在window上面触发
abort:当用户停止下载过程时,如果嵌入的内容没有加载完,则在<object>元素上面触发
error:当发生JavaScript错误时在window上触发
select:当用户选择文本框(<input>或<textarea>)中的一或多个字符时触发
resize:当窗口或框架的大小发生变化时在window或框架上触发
scroll:当用户滚动带滚动条的元素中内容时,在元素上面触发
a) load事件:当页面完全加载后,包含所有图像,js文件,css等外部资源
第一种用法:EventUtil.addHandler(window,"load",function(event){
alert("Load!!");
});
第二种用法:
<body onlaod=”alert(‘Loaded’)”>
Eg:
var image=document.getElementById("myimage");
EventUtil.addHandler(image,"load",function(event){
event=EventUtil.getEvent(event);
alert(EventUtil.getTarget(event).src); //事件的目标是<img>元素,可以通过src属性访问并显示该信息
})
在创建新的<img>元素时,可以先为其指定一个事件处理程序,以便图像加载完毕后给出提示(在src属性之前指定事件):
EventUtil.addHandler(window,"load",function(){
var image=document.createElement("img");
EventUtil.addHandler(image,"load",function(event){
event=EventUtil.getEvent(event);
alert(EventUtil.getTarget(event).src);
});
document.body.appendChild(image);
image.src="smile.gif";
})
b) 新的图像元素只要设置了src属性就会开始下载
<script>元素,只有在设置了src属性并将元素添加到文档后才会开始下载
c) <link>元素与<script>类似,在未指定href属性并将<link>元素添加到文档之前也不会开始下载样式表
B、unload事件:只要用户从一个页面切换到另一个页面,就会发生unload事件。
C:resize事件:当浏览器窗口被调整到一个新的高度或宽度的时候,就会触发resize事件,该事件是在window上面触发的,
D:scroll事件:可以通过scrollLeft以及scrollTop监控这一变化
EventUtil.addHandler(window,"scoll",function(event){
if(document.compatMode == "CSS1Compat"){
alert(document.documentElement.scrollTop);
//可以通过scrollLeft以及scrollTop监控这一变化
}else{
alert(document.body.scrollTop);
}
});
E:焦点事件:在元素获得或者失去焦点时触发,利用这些事件与document.hasFocus()以及document.activeElement属性的配合,知道用户在页面上的行踪
blur:在元素失去焦点时触发,事件不会冒泡
focus:在元素获得焦点的时候,不会冒泡
focusin:在元素获得焦点的时候触发,会冒泡
focusout:在元素失去焦点时触发
当焦点从页面的一个元素移动到另一个元素,会依次触发下列事件:
i. focusout:在失去焦点的元素上触发
ii. focusin:在获得焦点的元素上触发
iii. blur:在失去焦点的元素上触发
iv. DOMFocusOut:在失去焦点的元素上触发
v. focus:在获得焦点的元素上触发
vi. DOMFocusIn在获得焦点的元素上触发
F:鼠标与滚轮事件
a) 鼠标事件:
click:在用户单击主鼠标按钮,或者按下回车键触发。这就意味着onclick事件处理程序既可以通过键盘也可以通过鼠标执行
dblclick:用户双击主鼠标按钮时触发
mousedown:用户按下了任意鼠标按钮时触发,不能通过键盘触发
mouseenter:在鼠标光标从外部首次移动到元素范围之内时触发,事件不冒泡
mouseleave:在位于元素上方的鼠标光标移动到元素范围之外时触发,事件不冒泡
mousemove:当鼠标指针在元素内部移动时重复的触发,不能通过键盘触发
mouseout:在鼠标指针位于一个元素上方,然后用户将其移入另一个元素时触发,不能通过键盘触发,又移入的另一个元素可能位于前一个元素的外部,也可能是这个元素的子元素
mouseover:在鼠标指针位于一个元素外部,然后用户将其首次移入另一个元素边界之内时触发,不能通过键盘触发这个事件
mouseup:用户释放鼠标按钮时触发,不能通过键盘触发这个事件
----click,dbclick事件会依赖于其他先行事件的触发,而mousedown以及mouseup不会受其他事件的影响;所有的鼠标事件都冒泡,除了mousedown以及mouseup
b) 鼠标事件中的滚轮事件:mousewheel事件----跟踪鼠标滚轮
客户区坐标位置:相对于浏览器视口;clientX,clientY
页面坐标位置:pageX;pageY-------在页面没有滚动的情况下,pageX与pageY的值与clientX以及clientY的值是一致的
屏幕坐标位置:相对于整个 浏览器的,screenX以及screenY
c) 鼠标滚轮事件:
该事件可以在任何元素上面触发,最终会冒泡到document(IE8)或者window(IE9,Opera,Chrome,Safari)对象;wheelDelta属性,当用户向前滚动是120的倍数,向后是-120倍数;
EventUtil.addHandler(document,"mousewheel",function(event){
event=EventUtil.getEvent(event);
alert(event.wheelDelta);
});
测方向:
EventUtil.addHandler(document,"mousewheel",function(event){
event=EventUtil.getEvent(event);
var delta=(client.engine.opera && client.engine.opera<9.5 ? -event.wheelDelta:event.wheelDelta);
alert(delta);
});
d) 修改建:在按下鼠标时,键盘上的某些键的状态也可以影响到所要采取的鼠标操作
ShiftKey;ctrlKey;altKey;metaKey,属性包含的都是布尔值,相应的键被按下,值为true
e) DOM通过event对象的relatedTarget属性提供了相关元素的信息,这个属性只对于mouseover以及mouseout有效,对于其他的都是null
Mouseover触发时,IE的fromElement属性中保存了相关元素,在mouseout事件触发时,IE的toElement属性保存了相关信息
var EventUtil={
getRelatedTarget:function(event){
if(event.getRelatedTarget){
return event.getRelatedTarget;
}else if(event.toElement){
return event.toElement;
}else if(event.fromElement){
return event.fromElement;
}else{
return null;
}
},
};
f) 鼠标按钮:只有在主鼠标被单击(或者键盘回车键被按下)时才会触发click事件
对于mousedown以及mouseup事件来说,则在其event对象存在一个button属性,表示按下或者释放按钮。DOM中的button属性有以下3个值,0表示主鼠标按钮,1表示中间鼠标按钮,2表示次鼠标按钮
可以再为对象EventUtil添加getButton()方法
g) 触摸设备:
不支持dbclick事件,双击浏览器窗口会变大,没办法改变该行为
轻击可单击元素会触发mousemove事件
mousemove事件也会触发mouseover以及mouseout事件
两个手指放在屏幕上且页面随手指移动而滚动的时候会触发mousewheel以及scroll事件
h) 无障碍性问题:可以通过键盘的回车键触发click事件
G:键盘与文本事件:
keydown:当用户按下键盘上的任意键时触发,如果按住不放的话,会重复触发事件
keypress:当用户按下键盘上的字符键时触发,如果按住不放的话,会重复触发事件
,按下esc键也会触发这个事件
keyup:当用户释放键盘上的按键时触发
文本事件:textInput
a) 键码:在发生keydown以及keyup事件时,event对象的keyCode属性会包含一个代码,与键盘上的特定对的键对应。---DOM以及IE都支持
b) 字符编码:发生keypress事件,按下能够插入或删除字符的键会触发keypress事件
charCode属性
c) textInput事件:当用户在可编辑区域中输入字符时,就会触发这个事件;任何可以获得焦点的元素都可以触发keypress事件,只有在可编辑区域才可以触发textInput事件;textInput事件只会在用户按下能够输入实际字符的键时才会被触发,而keypress事件则是在按下哪些能够影响文本显示的键时就会被触发
textInput事件还包含一个data属性,属性值就是用户输入的字符
inputMethod,表示把文本输入到文本框的方式
H:变动事件:
a) 删除节点:
在使用removeChild(),replaceChild(),从DOM中删除节点的时候,首先会触发DOMNodeRemoved事件,事件会冒泡,触发时,节点尚未从父节点处删除,其parentNode属性仍然指向父节点,event.relatedNode属性包含着对目标节点父节点的引用
之后会触发DOMNodeRemovedFromDocument事件,事件不会冒泡
最后触发DOMSubtreeModified事件,
b) 插入节点:
使用appendChild(),replaceChild(),insertBefore()插入节点时,首先会触发DOMNodeInserted事件,event.relatedNode属性包含着对目标节点父节点的引用,接着会触发DOMNodeInsertIntoDocument事件,最后是DOMSubtreeModified事件触发于新插入节点的父节点
I:HTML5事件:
a) contextmenu事件:通过单击鼠标右键可以调出上下文菜单,冒泡,onclick事件处理隐藏程序从而隐藏该菜单
EventUtil.addHandler("window","load",function(event){
var div=document.getElementById("myDiv");
EventUtil.addHandler(div, "contextmenu",function(event){
event=EventUtil.getEvent(event);
EventUtil.preventDefault(event);
var menu=document.getElementById("menu");
menu.style.left=event.clientX+"px";
menu.style.right=event.clientY+"px";
menu.style.visibility="visible";
});
EventUtil.addHandler(document,"click",function(event){
document.getElementById("mymenu").style.visibility="hidden";
});
});
b) beforeunload事件:告知用户页面将进行卸载,是否需要进行卸载
为了显示弹出对话框,需要将event.returnValue的值设置为要显示给用户的字符串,同时返回字符串
EventUtil.addHandler(window,"beforeUnload",function(event){
event=EventUtil.getEvent(event);
var message="Im hhhhhhhhhh";
event.returnValue=message;
return message;
});
c) DOMContentLoaded事件:在形成完整的DOM树之后就会触发,不理会图像或者是外部文件是否已经下载完毕
d) Readystatechange事件---支持的浏览器有IE,FIRFOX,Opera:readyState属性,值为5个之一:uninitialized(未初始化),loading,loaded,interactive(交互);complete
e) Haschange事件:在Ajax应用中,开发人员经常要利用URL参数列表来保存状态或导航信息,使用location对象来确定参数列表
EventUtil.addHandler(window,"hashchange",function(event){
alert("current hash"+location.hash);
});
J:触摸事件:
touchstart:当手指触摸屏幕时触发,即使有个手指放在了屏幕上也会触发
touchmove:当手指在屏幕上滑动时连续的触发,在这事件发生期间,调用preventDefault()可以阻止滚动
touchend:当手指从屏幕上移开时候触发
touchcancel:当系统停止跟踪触摸时触发,
3个跟踪触摸的属性:
touches:表示当前跟踪的触摸操作的Touch对象的数组
targetTouchs:特定于目标的Touch对象的数组
changeTouches:表示自上次触摸以来发生了什么改变的Touch对象的数组
每个Touch包含以下的属性:
clientX:clientY;indentifer(标识触摸的唯一ID);pageX;pagey;ScreenX;ScreenY;target
9、内存与性能
A:最适合采用事件委托技术的事件:click,mousedown,mouseup,keydown,keyup,keypress
B:移除事件处理程序:btn.onclick=null;在事件处理程序中删除按钮也可以阻止事件冒泡
10、模拟事件
createEvent事件可以是以下几件:UIEvents;MouseEvents;MutationWvent(一般化的DOM变动事件);HTMLevent事件
A:模拟鼠标事件
var btn=document.getElementById("myBtn");
//创建事件对象
var event=document.createEvent("mouseEvent");
//初始化事件对象
event.initMouseEvent("click",true,*************);
//触发事件
btn.dispatchEvent(event);
B:模拟键盘事件
通用型:
var textbox=document.getElementById("myTextBox");
//创建事件对象
var event=document.createEvent("Events");
//初始化事件对象
event.initEvent(type,bubbles,cancelable);
event.view=document.preventDefault;
event.altkey=false;
event.ctrlkey=false;
event.shiftkey=false;
event.metaKey=false;
event.keyCode=65;
event.charCode=65;
//触发事件
textbox=dispatchEvent(event);
C:IE中的事件模拟
var btn=document.getElementById("myBtn");
//创建事件对象
var event=document.createEventObject();
//初始化事件对象
event.screenX=100;
event.screenY=0;
event.clientX=0;
event.clientY=0;
event.ctrlkey=false;
event.altkey=false;
event.shiftkey=false;
event.button=0;
//触发事件
btn.fireEvent("onclick",event);