事件(上)
| 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 | 一个表单被递交时触发此事件 | |
了解上面的事件如此简单,那么事件还有什么可讲的呢?
问题一:每个事件只能注册一个函数
var oDiv = document.getElementById("oDiv");
oDiv.onclick = fn1;
oDiv.onclick =fn2;
function fn1() {alert("我被覆盖了!")}
function fn2() {alert("只有我被执行到!")}
解决方案一:
obj.onclick = function () {
fn1();
fn2();
fn3();
};
缺陷一:需要将所有函数一次添加进去,不能在运行时添加
缺陷二:在事件处理函数中this将指向window,而不是obj
解决方案二:
function addEvent(fn,evtype,obj) {
//obj是要添加事件的HTML元素对象
//evtype是事件名字,不包含on前缀,因为每个都有on,所以写个on是多余的
//fn是事件处理函数
var oldFn;
if (obj["on"+evtype] instanceof Function) {
oldFn = obj["on"+evtype];//当添加函数时,如果已注册过了,则将其保存起来
}
obj["on"+evtype]=function () {
if (oldFn) {
oldFn.call(this);
}
fn.call(this);//使用call方法,使事件处理函数中的this仍指向obj
};
}
这样已经解决了问题,但如何删除事件呢?如果直接将对象的onevtype这类的属性赋值为null将会删除所有的事件处理函数!
解决方案二的修改版:先将事件存储起来,存储在对象的__EventHandles属性里面
eventHandlesCounter=1;//计数器,将统计所有添加进去的函数的个数,0位预留作其它用
function addEvent(fn,evtype,obj) {
if (!fn.__EventID) {//__EventID是给函数加的一个标识,见下面给函数添加标识的部分
fn.__EventID=eventHandlesCounter++;
//使用一个自动增长的计数器作为函数的标识以保证不会重复
}
if (!obj.__EventHandles) {
obj.__EventHandles=[];//当不存在,也就是第一次执行时,创建一个,并且是数组
}
if (!obj.__EventHandles[evtype]) {//将所有事件处理函数按事件类型分类存放
obj.__EventHandles[evtype]=[];//当不存在时也创建一个数组
if (obj["on"+evtype] instanceof Function) {
//查看是否已经注册过其它函数
//如果已经注册过,则将以前的事件处理函数添加到数组下标为0的预留的位置
obj.__EventHandles[evtype][0]=obj["on"+evtype];
obj["on"+evtype]=handleEvents;//使用handleEvents集中处理所有的函数
}
}
obj.__EventHandles[evtype][fn.__EventID]=fn;
//如果函数是第一次注册为事件处理函数,那么它将被添加到数组中,函数的标识作为下标
//如果函数已经注册过相同对象的相同事件了,那么将覆盖原来的而不会被添加两次
function handleEvents() {
var fns = obj.__EventHandles[evtype];
for (var i=0;i< fns.length;i++) {
fns[i].call(this);
}
}
}
使用上面的函数已经可以在一个对象添加多个事件处理函数,在函数内部this关键字也指向了相应的对象,并且这些函数都被作了标识,那么移除某个事件处理函数就是轻而易举的了!
//使用传统方法:obj.onevtype = null;但这样会移除所有的事件处理函数
function delEvent(fn,evtype,obj) {
if (!obj.__EventHandles || !obj.__EventHandles[evtype] || !fn.__EventID) {
return false;
}
if (obj.__EventHandles[evtype][fn.__EventID] == fn) {
delete obj.__EventHandles[evtype][fn.__EventID];
}
}
JavaScript事件处理详解与实践
4624

被折叠的 条评论
为什么被折叠?



