8. 事件
8.1 事件基础
1 /// 事件就是用户或浏览器自身执行的某种动作。诸如 click、load 和 mouseover,都是事件的名字。而响应某个事件的函数就叫做事件处理程序(或事件侦听器)。事件处理程序的名字以"on"开头,因此click 事件的事件处理程序就是 onclick,load 事件的事件处理程序就是 onload。 2 3 4 ///【HTML事件处理程序】 5 <input type="button" value="按钮" onclick='func()'> 6 7 8 //【DOM 0级处理程序】 9 var input = document.getElementsByTagName('input')[0]; 10 input.onclick = function(){//令onclick指向一个函数对象 11 alert("点击"); 12 } 13 input.onclick = func;//注意没有括号,有括号的话就是函数的返回值了 14 input.onclick = null;//删除事件处理程序 15 16 17 ///【DOM 2级处理程序】 18 // 后面 19 20 21 //事件处理函数 22 //事件类型分为:鼠标事件、键盘事件、HTML事件 等 23 24 //----------鼠标常用事件---------- 25 onclick() 单机某个对象时触发 26 ondbclick() 双击某个对象时触发 27 onmouseup() 鼠标松开时触发 28 onmouseover() 鼠标移动到元素上时触发 29 onmousemove() 鼠标被移动时触发 30 onmouseup() 鼠标移走时触发 31 32 //----------键盘常用事件---------- 33 onkeydown() 某个键盘按键被按下 34 onkeyup() 某个按键被松开 35 onkeypress() 按下字符键,数字、字母、符号 36 37 38 //********* 39 //元素对象都有一个 click() 方法可以模拟鼠标点击
8.2 事件对象
在触发DOM上的某个事件时,会产生一个事件对象event,这个对象包含着所有与事件相关的信息。
事件对象,一般称为event对象,浏览器自动为事件处理函数所绑定的函数传递这个对象做为参数。
1 ///【事件对象】 2 document.onclick = function(){ 3 alert(arguments.length);// 输出 1 ;event被自动当做参数传进函数 4 alert(arguments[0]);//[Object MouseEvent] 5 } 6 7 document.onclick = function(event){ //【获得、接收event对象,名字自定义】 8 alert(event);//[Object MouseEvent] 9 } 10 11 12 ///【常用】【event.target】 Element类型,返回事件的目标,可以对它操作 13 document.onclick = function(e){ 14 alert(e.target); //[object HTMLBodyElement] 15 alert(this == e.target); //也可以使用 this,等同于 e.target 16 } 17 18 19 ///【event.preventDefault()】 阻止事件的【默认行为】 20 //例如:单击链接的默认行为就是在被单击打时导航到href属性指向的URL,要阻止,就可以用preventDefault() 21 var link = document.getELementsByTagName('a')[0]; 22 link.onclick = function(event){ 23 event.preventDefault(); //这样点击超链接时就没有反应了 24 //【return false; 这样也可以】 25 } 26 27 ///【event.type】 28 // 返回事件类型 29 30 ///【event.stopPropagation()】 取消事件的【进一步】冒泡或捕获 31 /* 32 <html> 33 <body> 34 <div>xxx</div> 35 </body> 36 </html> 37 */ 38 39 //【事件冒泡】:【子节点、父节点都使用相同的事件时取消冒泡】 40 //【并不是所有事件都冒泡,focus,load,unload,blur 不冒泡】 41 //当点击了<div>后,其父节点的onclick事件也全都会触发(因为是包含关系),onclick事件会沿DOM树向上传播:div -> body -> html -> Document -> window 42 div.onclick = funciton(evt){ 43 evt.stopPropagation();//这样就可以取消冒泡了,点击div时 body html document 的onclick事件就不会触发了,因为【事件流到了 div时,就被阻止了】 44 } 45 46 //【事件捕获】: 47 // 相反,onclick事件会沿DOM树向下传播:Document -> html -> body -> div 48 49 //【DOM事件流】 50 //DOM2级事件 规定的事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段 51 //如单击DIV:Document -> html -> body -------> div -------> body -> html -> Document 52 53 //在 DOM 事件流中,实际的目标(<div>元素)在捕获阶段不会接收到事件。这意味着在捕获阶段,事件从 document 到<html>再到<body>后就停止了。下一个阶段是“处于目标”阶段,于是事件在<div>上发生,【并在事件处理中被看成冒泡阶段的一部分】。然后,冒泡阶段发生,事件又传播回文档 54 55 56 //【chrome中的实际情况】 57 /* 58 <body> <button> </body> 59 60 button.onclick = function(){ log("on button") } 61 body.onclick = function(){ log("on body") } 62 document.onclick = function(){ log("on document") } 63 window.onclick = function(){ log("on window") } 64 65 最后输出为: button -> body -> document -> window 66 也就是说,click事件先在button上发生,再在冒泡阶段发生。时间冒泡方式更胜一筹,所以放心使用冒泡。 67 */ 68
8.3 事件类型
1 ///【【鼠标事件】】 2 //【鼠标按钮】 3 // 对于mousedown 和 mouseup 事件来说,在其event对象存在一个button属性,表示按下或释放的按钮。0表示鼠标左键,1表示鼠标中键,2表示鼠标右键 4 document.onmouseup = function(event){ 5 alert(event.button); 6 } 7 8 9 //【可视区与屏幕坐标】 10 document.onclick = function(event){ 11 alert(event.clientX + ',' +event.clientY);//表示以【当前可视页面左上角】为原点,鼠标的点击坐标,不受页面大小影响 12 } 13 14 document.onclick = function(event){ 15 alert(event.pageX + ',' +event.pageY);//表示以【真正页面左上角】为原点,鼠标的点击坐标,如果滚动条向下拉,再点击页面左上角,不会是 0,0 ,因为上面还有一部分 16 } 17 18 document.onclick = function(event){ 19 alert(event.screenX + ',' +event.screenY);//表示以【电脑屏幕左上角】为原点,鼠标的点击坐标 20 } 21 22 23 //【修改键】 24 //简单来说就是,判断【按下鼠标时是否同时按下了】:Shift、Ctrl、Alt、Meta(Windows键盘为Windows键,苹果味Cmd键)。分别用四个属性表示:shiftKey、ctrlKey、altKey、metaKey,保存的都是布尔值,如果按下了相应的键则值为true,否则值为false。 25 function getKey(evt){ 26 var keys = [];//数组存放按下了哪些键 27 if(evt.shiftKey) keys.push('shift'); 28 if(evt.ctrlKey) keys.push('ctrl'); 29 if(evt.altKey) keys.push('alt'); 30 if(evt.metaKey) keys.push('meta'); 31 alert(keys); 32 } 33 document.onclick = getKey; 34 35 36 37 38 39 40 ///【【键盘事件】】 41 //keydown: 按下任意键触发,按住不放的话,会重复触发此事件 42 //keyup: 吃放键盘上的任意键时触发 43 //keypress: 按下【字符键】触发,按住不放的话,会重复触发此事件 44 //textIput: 文本事件,是对keypress的补充,在文本插入文本框前会先触发textInput事件 45 //当按下字符键时,会触发:keydown -> keypress -> keyup 46 47 //【键码】 48 //发生keydown和keyup事件时,event对象的keyCode属性会返回一个与键盘上对应的键的代码 49 50 //【字符编码】 51 //发生keypress事件,事件对象event 的 charCode属性,返回字符的ASCII码。 52 document.onkeypress = function(e){ 53 alert(String.fromCharCode(e.keyCode));//String.fromCharCode 将ASCII码转换为字符 54 } 55 56 57 58 59 60 ///【【UI事件】】 61 //【load 事件】 62 //当页面加载完后触发(包括图像,JS、CSS文件,window,框架) 63 64 65 66 67 ///【【焦点事件】】 68 //焦点事件会在页面元素获得或失去焦点时触发。利用这些事件并与 document.hasFocus()方法及document.activeElement 属性配合,可以知晓用户在页面上的行踪。 69 /* 70 blur: 当元素失去焦点时触发,这事件不会冒泡。 71 focus: 同focusin,不冒泡。 72 focusin: 元素获得焦点时触发。 73 focusout: 同blur 74 75 76 */ 77 78
8.4 事件绑定
1 //HTML 绑定 2 //<div onclick='alert(this)'>xxx</div> 也可以打印this;onclick=doo(),function doo(){alert(this);} 不可以!!! 3 4 5 //DOM 0级 6 div.onclick = function(){//函数被绑定,被认为是这个对象的方法 7 alert(this);//【直接可以通过this访问到HTML元素对象】 8 } 9 10 11 //【addEventListener】 12 window.onload = function(){ 13 alert(1); 14 } 15 window.onload = function(){ 16 alert(2); 17 } 18 //最终会输出2,因为第一个被覆盖了 19 20 window.addEventListener('load',function(){ //第一个参数是事件类型(没有on),第三个【false表示在冒泡阶段调用事件处理程序】,true 表示在捕获阶段调用 21 alert(1); 22 },false); 23 window.addEventListener('load',function(){ 24 alert(2); 25 },false) 26 //1 和 2 都输出了,解决了覆盖的问题 27 28 29 30 31 //要移除这种方法添加的事件必须使用 removeEventListener(事件类型,要移除的函数,bool) 32 window.removeEventListener('load',function(){xx}) //这样不可以,因为addEventListener里的函数和这里的是两个不同的函数对象。 解决办法是:把函数对象赋值给一个变量,将变量分别给 add remove这两个函数 33 34 35
8.5 模拟事件