JavaScript事件列表
事件 解说
一般事件 onclick 鼠标点击时触发此事件
ondblclick 鼠标双击时触发此事件
onmousedown 按下鼠标时触发此事件
onmouseup 鼠标按下后松开鼠标时触发此事件
onmouseover 当鼠标移动到某对象范围的上方时触发此事件
onmousemove 鼠标移动时触发此事件
onmouseout 当鼠标离开某对象范围时触发此事件
onkeypress 当键盘上的某个键被按下并且释放时触发此事件.
onkeydown 当键盘上某个按键被按下时触发此事件
onkeyup 当键盘上某个按键被按放开时触发此事件
页面相关事件 onabort 图片在下载时被用户中断
onbeforeunload 当前页面的内容将要被改变时触发此事件
onerror 出现错误时触发此事件
onload 页面内容完成时触发此事件
onmove 浏览器的窗口被移动时触发此事件
onresize 当浏览器的窗口大小被改变时触发此事件
onscroll 浏览器的滚动条位置发生变化时触发此事件
onstop 浏览器的停止按钮被按下时触发此事件或者正在下载的文件被中断
oncontextmenu 当弹出右键上下文菜单时发生
onunload 当前页面将被改变时触发此事件
表单相关事件 onblur 当前元素失去焦点时触发此事件
onchange 当前元素失去焦点并且元素的内容发生改变而触发此事件
onfocus 当某个元素获得焦点时触发此事件
onreset 当表单中RESET的属性被激发时触发此事件
onsubmit 一个表单被递交时触发此事件
鼠标 / 键盘属性
altKey
返回当事件被触发时,"ALT" 是否被按下。
button
返回当事件被触发时,哪个鼠标按钮被点击。
clientX
返回当事件被触发时,鼠标指针的水平坐标。
clientY
返回当事件被触发时,鼠标指针的垂直坐标。
ctrlKey
返回当事件被触发时,"CTRL" 键是否被按下。
metaKey
返回当事件被触发时,"meta" 键是否被按下。
relatedTarget
返回与事件的目标节点相关的节点。
screenX
返回当某个事件被触发时,鼠标指针的水平坐标。
screenY
返回当某个事件被触发时,鼠标指针的垂直坐标。
shiftKey
返回当事件被触发时,"SHIFT" 键是否被按下。
IE 属性
cancelBubble
如果事件句柄想阻止事件传播到包容对象,必须把该属性设为 true。
fromElement
对于 mouseover 和 mouseout 事件,fromElement 引用移出鼠标的元素。
keyCode
对于 keypress 事件,该属性声明了被敲击的键生成的 Unicode 字符码。对于 keydown 和 keyup 事件,它指定了被敲击的键的虚拟键盘码。虚拟键盘码可能和使用的键盘的布局相关。
offsetX,offsetY
发生事件的地点在事件源元素的坐标系统中的 x 坐标和 y 坐标。
returnValue
如果设置了该属性,它的值比事件句柄的返回值优先级高。把这个属性设置为 fasle,可以取消发生事件的源元素的默认动作。
srcElement
对于生成事件的 Window 对象、Document 对象或 Element 对象的引用。
toElement
对于 mouseover 和 mouseout 事件,该属性引用移入鼠标的元素。
x,y 事件发生的位置的 x 坐标和 y 坐标,它们相对于用CSS动态定位的最内层包容元素。
标准 Event 属性
下面列出了 2 级 DOM 事件标准定义的属性
bubbles
返回布尔值,指示事件是否是起泡事件类型。
cancelable
返回布尔值,指示事件是否可拥可取消的默认动作。
currentTarget
返回其事件监听器触发该事件的元素。
eventPhase
返回事件传播的当前阶段。
target
返回触发此事件的元素(事件的目标节点)。
timeStamp
返回事件生成的日期和时间。
type
返回当前 Event 对象表示的事件的名称。
标准 Event 方法
下面列出了 2 级 DOM 事件标准定义的方法。IE 的事件模型不支持这些方法:
initEvent()
初始化新创建的 Event 对象的属性。
preventDefault()
通知浏览器不要执行与事件关联的默认动作。
stopPropagation()
不再派发事件。
Event对象
//W3C DOM把事件对象作为事件处理函数的第一个参数传入进去
document.onclick = function (evt) {//这样,事件对象只能在对应的事件处理函数内部可以访问到
alert(evt);
};
//IE将事件对象作为window对象的一个属性(相当于全局变量)
//貌似全局对象,但是只有是事件发生时才能够访问
alert(window.event);//null
window.onload = function () {
alert(window.event);
};```
#阻止事件发生时浏览器的默认行为
```javascript
document.onclick = function (evt) {
evt = evt || window.event;
var target = evt.target || evt.srcElement;
if (!target) {
return;
}
if (target.tagName=="A" && target.href) {
//使用传统的方法取消事件默认行为必须使用return false
//但使用了return ,函数便终止了运行,可以使用事件对象来取消
if (window.event) {//IE
window.event.returnValue = false;
} else {
evt.preventDefault();
}
window.open(target.href,"newWindow");
//这样让所有的链接在新窗口打开
}
};
```
冒泡事件流 从当前节点向根节点冒泡
捕获事件流 从根节点向触发节点传递事件
```javascript
function addEvent(obj,evtype,fn,useCapture) {
if (obj.addEventListener) {//useCapture true 捕获阶段执行
obj.addEventListener(evtype,fn,useCapture);
} else {
obj.attachEvent("on"+evtype,fn);//IE不支持事件捕获
} else {
obj["on"+evtype]=fn;//事实上这种情况不会存在
}
}
function delEvent(obj,evtype,fn,useCapture) {
if (obj.removeEventListener) {
obj.removeEventListener(evtype,fn,useCapture);
} else {
obj.detachEvent("on"+evtype,fn);
} else {
obj["on"+evtype]=null;
}
}
其它兼容性问题:IE不支持事件捕获?很抱歉,这个没有办法解决!但IE的attach方法有个问题,就是使用attachEvent时在事件处理函数内部,this指向了window,而不是obj!####
****解决方案
function addEvent(obj,evtype,fn,useCapture) {
if (obj.addEventListener) {
obj.addEventListener(evtype,fn,useCapture);
} else {
obj.attachEvent("on"+evtype,function () {
fn.call(obj);
});
} else {
obj["on"+evtype]=fn;//事实上这种情况不会存在
}
}
但IE的attachEvent方法有另外一个问题,同一个函数可以被注册到同一个对象同一个事件上多次,解决方法:抛弃IE的 attachEvent方法吧!IE下的attachEvent方法不支持捕获,和传统事件注册没多大区别(除了能绑定多个事件处理函数),并且IE的 attachEvent方法存在内存泄漏问题
****addEvent,delEvent现代版,暂时没看懂
function addEvent(obj,evtype,fn,useCapture) {
if (obj.addEventListener) {//优先考虑W3C事件注册方案
obj.addEventListener(evtype,fn,!!useCapture);
} else {//当不支持addEventListener时(IE),由于IE同时也不支持捕获,所以不如使用传统事件绑定
if (!fn.__EventID) {fn.__EventID = addEvent.__EventHandlesCounter++;}
//为每个事件处理函数分配一个唯一的ID
if (!obj.__EventHandles) {obj.__EventHandles={};}
//__EventHandles属性用来保存所有事件处理函数的引用
//按事件类型分类
if (!obj.__EventHandles[evtype]) {//第一次注册某事件时
obj.__EventHandles[evtype]={};
if (obj["on"+evtype]) {//以前曾用传统方式注册过事件处理函数
(obj.__EventHandles[evtype][0]=obj["on"+evtype]).__EventID=0;//添加到预留的0位
//并且给原来的事件处理函数增加一个ID
}
obj["on"+evtype]=addEvent.execEventHandles;
//当事件发生时,execEventHandles遍历表obj.__EventHandles[evtype]并执行其中的函数
}
}
}
addEvent.__EventHandlesCounter=1;//计数器,0位预留它用
addEvent.execEventHandles = function (evt) {//遍历所有的事件处理函数并执行
if (!this.__EventHandles) {return true;}
evt = evt || window.event;
var fns = this.__EventHandles[evt.type];
for (var i in fns) {
fns[i].call(this);
}
};
function delEvent(obj,evtype,fn,useCapture) {
if (obj.removeEventListener) {//先使用W3C的方法移除事件处理函数
obj.removeEventListener(evtype,fn,!!useCapture);
} else {
if (obj.__EventHandles) {
var fns = obj.__EventHandles[evtype];
if (fns) {delete fns[fn.__EventID];}
}
}
}
IE EVENT对象有些不兼容的地方,修改方式如下
function fixEvent(evt) {
if (!evt.target) {
evt.target = evt.srcElement;
evt.preventDefault = fixEvent.preventDefault;
evt.stopPropagation = fixEvent.stopPropagation;
if (evt.type == "mouseover") {
evt.relatedTarget = evt.fromElement;
} else if (evt.type =="mouseout") {
evt.relatedTarget = evt.toElement;
}
evt.charCode = (evt.type=="keypress")?evt.keyCode:0;
evt.eventPhase = 2;//IE仅工作在冒泡阶段
evt.timeStamp = (new Date()).getTime();//仅将其设为当前时间
}
return evt;
}
fixEvent.preventDefault =function () {
this.returnValue = false;//这里的this指向了某个事件对象,而不是fixEvent
};
fixEvent.stopPropagation =function () {
this.cancelBubble = true;
};
fixEvent函数不是单独执行的,它必须有一个事件对象参数,而且只有事件发生时它才被执行!最好的方法是把它整合到addEvent函数的execEventHandles里面
addEvent.execEventHandles = function (evt) {//遍历所有的事件处理函数并执行
if (!this.__EventHandles) {return true;}
evt = fixEvent(evt || window.event);//在这里对其进行标准化操作
var fns = this.__EventHandles[evt.type];
for (var i in fns) {
fns[i].call(this,evt);//并且将其作为事件处理函数的第一个参数
//这样在事件处理函数内部就可以使用统一的方法访问事件对象了
}
};
Load事件
使用JavaScript操纵DOM,必须等待DOM加载完毕才可以执行代码,但window.onload有个坏处,它非要等到页面中的所有图片 及视频加载完毕才会触发load事件。结果就是一些本来应该在打开时隐藏起来的元素,由于网络延迟,在页面打开时仍然会出现,然后又会突然消失,让用户觉 得莫名其妙。
大师们想出来的方法:
function addLoadEvent(fn) {
var init = function() {
if (arguments.callee.done) return;
arguments.callee.done = true;
fn.apply(document,arguments);
};
//注册DOMContentLoaded事件,如果支持的话
if (document.addEventListener) {
document.addEventListener("DOMContentLoaded", init, false);
}
//但对于Safari,我们需要使用setInterval方法不断检测document.readyState
//当为loaded或complete的时候表明DOM已经加载完毕
if (/WebKit/i.test(navigator.userAgent)) {
var _timer = setInterval(function() {
if (/loaded|complete/.test(document.readyState)) {
clearInterval(_timer);
init();
}
},10);
}
//对于IE则使用条件注释,并使用script标签的defer属性
//IE中可以给script标签添加一个defer(延迟)属性,这样,标签中的脚本只有当DOM加载完毕后才执行
/*@cc_on @*/
/*@if (@_win32)
document.write("<script id=\"__ie_onload\" defer=\"defer\" src=\"javascript:void(0)\"><\/script>");
var script = document.getElementById("__ie_onload");
script.onreadystatechange = function() {
if (this.readyState == "complete") {
init();
}
};
/*@end @*/
return true;
}