Javascript - DOM事件

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Javascript - DOM事件相关的知识,希望对你有一定的参考价值。

事件(Event)

javascript中处理事件的函数被称为事件侦听器,就像C#中的事件订阅者的事件处理器。要触发一个事件必须先注册(订阅)事,当事件被触发时,事件侦听器就会做出响应(invoke事件侦听)。

自定义事件

注册事件

//type是事件触发的方式
//func是处理事件的函数(事件侦听器),
//bool布尔值,为true表示事件会围捕,为false表示事件会冒泡。
object.addEventListener(type, func, bool)

为多个元素注册事件

如果用类似for的循环来为多个元素注册事件,如果你需要向事件处理器传递循环中的的参数,那么你需要在循环中包装并调用一个匿名函数,将参数放进去才行,否则循环完成后,那个计数器会变成最终值而不是循环中的那个值。

var elms = document.querySelectorAll( "a" );
for ( var i = elms.length - 1; i >= 0; i-- ) {
    ( function ( z ) {
        elms[z].addEventListener( "click", function ( ) {
            xxx( elms[z] )
        }, { passive: false } );
    } )( i );
}

注销事件

//object是绑定了事件的对象
//type是该对象的事件触发方式
//func是事件侦听器
object.removeEventListener(type, func)

例子

//注册和注销事件都是由绑定事件的对象来调用
window.onload = function () {

    var div = document.getElementById("divBox");
    div.addEventListener("mouseover", show);
    div.removeEventListener("mouseover", show);
}

但通常注销一个对象的事件都是交由另一个对象的事件来完成,比如点击一个div,触发事件,点击另一个div就注销前一个div的事件:

<div id="divBox" style="width:100px;height:100px;background:black;color:white;">双击触发事件</div>
<div id="deDivBox" style="width:100px;height:100px;background:red;color:white;">双击注销事件</div>
<script type="text/javascript">
    window.onload = function () {
        var div = document.getElementById("divBox");//获取第一个div对象
        div.addEventListener("click", show);//为第一个div注册click事件
        var deDiv = document.getElementById("deDivBox");//获取第二个div对象
        deDiv.addEventListener("click", removeEvent);//为第二个div注册click事件
        //第一个div双击时的处理函数
        function show() {

            alert("双击事件发生");
        }
        //第二个div双击时的处理函数,它将第一个div的事件移除
        function removeEvent() {

            div.removeEventListener("click", show);
            alert("双击事件被移除");
        }
    }
</script>

重复注册

重复注册相同类型的事件,后一个并不会覆盖前一个,事件发生时它们都会执行。但它们的执行顺序可能不是你预期的那样。想要事件执行顺序如你预期,最好将所有事件放在一个事件注册器上。

window.onload = function () {
    var div = document.getElementById("divBox");
    div.addEventListener("click", show);
    div.addEventListener("click", show2);
    function show() {
        alert("hello");
    }
    function show2() {
        alert("world");
    }
}

//改写
window.onload = function () {

    var div = document.getElementById("divBox");
    div.addEventListener("click", show);
    function show() {
        alert("hello world");
    }
}

手动调用事件

document.addEventListener( "click", function () { alert();});
var event = document.createEvent( \'Events\' );
event.initEvent( \'click\', true, true );
document.dispatchEvent( event ); //手动触发click

事件冒泡

如果子元素绑定了事件,子元素的上层元素(父、祖先)元素也绑定过事件,那么当子元素的事件被触发后,该事件就像上升的泡沫会连锁反应自动触发到上层元素的事件。也即子元素绑定了click事件,父元素也绑定了mouseup事件,那么子元素的click事件一旦被你手动触发,那么click事件执行完之后系统会自动触发父元素的mouseup事件。注:冒泡永远不会传递给body对象。

<div id="gBox" style="width:600px;background:#b6ff00;">
    祖先
    <div id="fBox" style="width:300px;background:red;">
        父亲
        <div id="cBox" style="width:100px;background:#ff6a00;">儿子</div>
    </div>
</div>
<span id="showMsg"></span>

    window.onload = function () {
        var message = document.getElementById("showMsg");
        var gBox = document.getElementById("gBox");
        var fBox = document.getElementById("fBox");
        var cBox = document.getElementById("cBox");
        cBox.addEventListener("mousedown", show, false);
        fBox.addEventListener("mouseup", show, false);
        gBox.addEventListener("mouseup", show, false);

        function show(W3CEvent_obj) {
            message.innerText += this.id + "的" + W3CEvent_obj.type + "事件被触发\\n";
        }           
    }

事件围捕

这个概念叫做事件捕获,我称其为事件围捕,它与冒泡恰恰相反,当子元素的事件被触发后,如果包含它的上层们注册过任何事件,那么就先从包含它的最顶层的元素的事件开始执行,逐层往下,最后才执行该子元素的事件。也即,冒泡是从下往上,围捕是从上往下。最后,这是W3C的标准,JQuery也不支持这个怪诞的概念,JQuery只支持冒泡。

事件信息

事件被触发后总是有一个叫做W3CEvent_obj的参数被隐式的传递到了事件侦听器中,事件中维护了这个参数,这个参数是一个特殊的event对象,当然你可以改名字,因为它在事件的参数中是个形参,它存储了事件发生时的信息。

event对象的属性

keyCode
//keypress事件发生时获取该键位的unicode码

type
//表示事件触发的方式

bubbles
//获取当前事件是否为冒泡阶段的事件

cancelable
//有些事件的默认动作是无法被取消的,此属性可以获取事件的默认动作是否可以被取消

currentTarget
//获取当前事件流中的注册了事件的父级别元素

target
//获取最早触发事件的对象

eventPhase
//获取当前事件侦听器处于事件流的哪一个阶段,返回的值和对应的常量如下:
//即将冒泡或捕获: Event.AT_TARGET:3
//事件处于起泡阶段:Event.BUBBLING_PHASE:2
//事件处于捕获阶段:Event.CAPTURING_PHASE:1

altKey
//是否按下了该键

ctrlKey
//是否按下了该键

shiftKey
//是否按下了该键

button
//获取被按下的鼠标键位
//鼠标左键:0
//鼠标中键:1
//鼠标右键:2

clientX
//事件发生位置相对于客户区的左边距(客户区指浏览器文档区,不包括浏览器工具栏)

clientY
//事件发生位置相对于客户区的上边距

screenX
//事件发生位置相对于浏览器窗体的左边距 (浏览器窗体指整个浏览器界面,包括工具栏等)

screenY
//事件发生位置相对于浏览器窗体的上边距
View Code

event对象的方法

stopPropagation()
//阻止事件围捕/冒泡,ID使用cancelBubble=true或false
 
stopImmediatePropagation()
//阻止事件围捕/冒泡、终止当前元素的其它事件的执行

preventDefault()
//阻止浏览器默认动作,该方法可以阻止类似当点击链接后跳转页面等等

新的事件参数

在最新规范中,addEventListener() 的第三个参数可以是一个对象,该对象有三个重要属性:

addEventListener( type, listener, {
  capture: false,//事件冒泡(false)或事件围捕(true),默认false
  passive: false, //是否不阻止浏览器默认行为,用于当你将触摸事件注册在document上时,chrome浏览器会卡顿,它的滑动监听器会一直阻塞到你的触摸事件结束后才运行,除非你将passive设为true
  once: false //是否只执行一次 目前的浏览器还未实现
} )

当你在document上注册滑动事件时,最好将passive设为true,这样可以避免滑动卡顿,而在其它非滑动事件中可将passive设为false,为false则表示告诉浏览器你将在事件中调用e.preventDefault阻止浏览器默认行为,让浏览器放弃监听。在remove事件的时候不需要传递这个匿名对象。

参考:passive 的事件监听器让 touch 系列事件触发的滚动响应更快 

 向事件传参

将事件包装到匿名函数中即可

element.addEventListener(\'mouseover\',function() {fn(e,some)}, false);

  

事件类型

对象、鼠标、键盘、表单、浏览器事件

 

内置事件

文档装载事件

load
//文档 / 图像加载完毕时发生

unload
//文档被卸载时发生

beforeunload
//文档被卸载前发生

document.DOMContentLoaded
//文档加载完成时发生。  * IE无效

error
//文档上程序错误时或图像载入失败时发生,会自动向事件处理器发送三个参数,可通过arguments获取
//示例:
window.Error = function () {

    var errorMessage = arguments[0];
    var errorProgramFileName = arguments[1];
    var errorCode = arguments[2];
    document.write("错误代码:" + errorCode + "错误信息:" + errorMessage + "错误程序文件地址:" + errorProgramFileName); 
}//images的error事件无这三个参数

鼠标事件

mousemove
//当鼠标在页面上移动时将连续发生,相当耗费系统资源,应尽量少用

mouseover
//当鼠标移动到某个元素对象上时发生

mouseout
//当鼠标移出某个对象时发生

mousedown
//发生当鼠标在对象上按下时

mouseup
//当鼠标按键被释放时发生

click
//当鼠标按下、抬起之后发生

dbclick
//当快速双击鼠标时发生 鼠标按下、抬起之后发生 即在click事件之后。鼠标点击事件发生顺序:mousedown、up、click。click表示鼠标按下并抬起才算一个完整的单击动作

鼠标事件详解

1.如果鼠标在对象上按下,在不抬起的情况下拖动鼠标离开对象,只会发生mousedown事件。

2.如果按下鼠标不抬起直到拖动到一个对象上时才抬起,只会发生mouseup事件。

3.即鼠标的某个动作必须是在某个对象上完成的才会触发相应的事件 离开该对象 鼠标事件就不存在。

4.不要在一个元素上同时注册click和dbclick事件,这会引发混乱,你几乎无法知道到底发生了什么。

5.当你需要冒泡或捕获时,不要定义鼠标移动事件,这会引起逻辑混乱。比如在元素注册一个mouseover事件,然后在其子元素上也注册一个mouseover事件。那么在冒泡的前提下,你可能认为先在子元素上发生mouseover,那么事件侦听将先处理子元素的事件,然后冒泡时才会处理父元素的mouseover事件。可实际情况可能更为复杂,程序有可能先处理父元素的事件,这是因为程序无法正确获取鼠标移动时它到底是移动到了子元素上还是父元素上,因为子元素总是包含在父元素里。但这种情况不会发生在鼠标点击事件上(当点击发生时程序可以确定你点的对象) 。 

键盘事件

keydown
//当某个键被按下时发生

keyup
//当键被按下并释放时发生

keypress
//当keyup发生后紧接着发生 表示有一个键被按过了

表单事件

submit
//当点击提交按钮(type = \'submit\')或按下某个键将表单提交到服务器之前发生

reset
//当点击重置按钮(type = \'reset\')或按下某个键将表单重置时发生

blur
//当表单元素失去焦点时发生

jQuery基础入门

JS 事件入门

学习Javascript

理解:javascript中DOM0,DOM2,DOM3级事件模型

JavaScript之DOM(下)

JavaScript DOM总结(文档事件)