首页 JavaScriptJS知识点正文

js事件(Event)知识整理

鼠标事件


鼠标移动到目标元素上的那一刻,首先触发mouseover
之后如果光标继续在元素上移动,则不断触发mousemove
如果按下鼠标上的设备(左键,右键,滚轮……),则触发mousedown
当设备弹起的时候触发mouseup
目标元素的滚动条发生移动时(滚动滚轮/拖动滚动条。。)触发scroll
滚动滚轮触发mousewheel,这个要区别于scroll
鼠标移出元素的那一刻,触发mouseout 


事件绑定

平常我们绑定事件的时候用dom.onxxxx=function(){}的形式
这种方式是给元素的onxxxx属性赋值,只能绑定有一个处理句柄。
但很多时候我们需要绑定多个处理句柄到一个事件上,而且还可能要动态的增删某个处理句柄
下面的事件绑定方式就能解决这个需求。

//IE以外 
/*
target.addEventListener(type,listener,useCapture) 
target.removeEventListener(type,listener,useCapture); 
*/
//target :文档节点、document、window 或 XMLHttpRequest。 
//type :字符串,事件名称,不含“on”,比如“click”、“mouseover”、“keydown”等。 
//listener :实现了 EventListener 接口或者是 JavaScript 中的函数。 
//useCapture :是否使用捕捉,一般用 false。 
//IE 
//target.attachEvent(type, listener); 
//target.detachEvent(type, listener); 
//target :文档节点、document、window 或 XMLHttpRequest。 
//type :字符串,事件名称,含“on”,比如“onclick”、“onmouseover”、“onkeydown”等。 
//listener :实现了 EventListener 接口或者是 JavaScript 中的函数。 
//两者使用的原理:可对执行的优先级不一样,实例讲解如下: 
//ele.attachEvent("onclick",method1); 
//ele.attachEvent("onclick",method2); 
//ele.attachEvent("onclick",method3); 
//执行顺序为method3->method2->method1 
//ele.addEventListener("click",method1,false); 
//ele.addEventListener("click",method2,false); 
//ele.addEventListener("click",method3,false); 
//执行顺序为method1->method2->method3 
//兼容后的方法 
//兼容后的方法 
var func = function(){}; 
//例:addEvent(window,"load",func) 
function addEvent(obj,sEv,fn){
    if(obj.addEventListener){
        obj.addEventListener(sEv,fn,false);
    }else{
        obj.addEvent("on"+sEv,fn);
    }
} 
//例:removeEvent(window,"load",func) 
function removeEvent(obj, sEv, fn) { 
    if (obj.removeEventListener) { 
        obj.removeEventListener(sEv, fn, false); 
    }else{
        obj.detachEvent('on'+ sEv, fn);     
    } 
}

获取事件对象和事件源(触发事件的元素) 

function eventHandler(ev){ 
//获取事件对象 
var oEvent = ev || event;//IE和Chrome下是.event FF下是e 
//获取事件源 
var target = ev.target || ev.srcElement;//IE和Chrome下是srcElement FF下是target 
}

取消事件默认行为(例如点击一个<a>后不跳转页面而是执行一个函数)

function eventHandler(ev) { 
    var oEvent = ev || event; 
    // 防止默认行为 
    if (ev.preventDefault) { 
        ev.preventDefault();//IE以外 
    } else { 
        ev.returnValue = false;//IE 
        //注意:这个地方是无法用return false代替的 
        //return false只能取消元素 
    } 
}


阻止事件冒泡

function myParagraphEventHandler(ev) { 
    var oEvent = ev || event;
    if (ev.stopPropagation) { 
        ev.stopPropagation();//IE以外 
    } else { 
        ev.cancelBubble = true;//IE 
    } 
}


事件委托

例如,你有一个很多行的大表格,在每个<tr>上绑定点击事件是个非常危险的想法,因为性能是个大问题。流行的做法是使用事件委托。

事件委托描述的是将事件绑定在容器元素上,然后通过判断点击的target子元素的类型来触发相应的事件。
事件委托依赖于事件冒泡,如果事件冒泡到table之前被禁用的话,那以下代码就无法工作了。

myTable.onclick = function (ev) { 
    var oEvent = ev || event;
    var targetNode = ev.target || ev.srcElement; 
    // 测试如果点击的是TR就触发 
    if (targetNode.nodeName.toLowerCase() === 'tr') { 
        alert('You clicked a table row!'); 
    } 
}


事件流

DOM同时支持两种事件模型:捕获型事件和冒泡型事件
并且每当某一事件发生时,都会经过捕获阶段->处理阶段->冒泡阶段(有些浏览器不支持捕获)

捕获阶段是由上层元素到下层元素的顺序依次。而冒泡阶段则正相反。 

    当事件触发时body会先得到有事件发生的信息,然后依次往下传递,直到到达最详细的元素。这就是事件捕获阶段。
还记得事件注册方法ele.addEventListener(type,handler,flag)吧,Flag是一个Boolean值,true表示事件捕捉阶段执行,false表示事件冒泡阶段执行。
    接着就是事件冒泡阶段。从下往上 依次执行事件处理函数(当然前提是当前元素为该事件注册了事件句柄)。
在这个过程中,可以阻止事件的冒泡,即停止向上的传递。
阻止冒泡有时是很有必要的,例如

<div onclick=funcA()> 
    <button onclick=funcB()>Click</button> 
</div>

    本意是如果点击div中按钮以外的位置时执行funcA,点击button时执行funcB。但是实际点击button时就会先后执行funcB,funcA。
而如果在button的事件句柄中阻止冒泡的话,div就不会执行事件句柄了。

版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

评论