事件是可以被JavaScript侦测到的行为。网页中的每个元素都可以产生某些可以触发JavaScript函数的事件。
事件是一瞬间触发。
一、 事件绑定方式
DOM节点绑定(格式):节点.on+事件名 = 事件处理函数;
1、DOM节点绑定
(1)同名事件会被覆盖
(2)事件处理函数只能冒泡阶段执行
div.onclick = function(){}
2、作为html属性(不常用,不实用)
<div onclick="sum()"></div> 不常用,不实用。
3、事件监听器
(1)同名事件不会被覆盖
(2)事件处理函数默认冒泡阶段执行
二、事件分类
(一)、鼠标事件
1、onclick ==> (onclick = onmousedown + onmouseup)
当用户点击某个对象时调用的事件
(2) ondblclick ==> 双击
* ondblclick = onclick*2
当用户双击某个对象时调用的事件
(3)onmousedown ==> 鼠标按钮被按下。
(4)onmouseup ==> 鼠标按键被松开。
(5)onmouseover ==> 鼠标移到某元素之上。
(5)onmouseenter ==> 鼠标移到某元素之上。(这个事件不冒泡)
(6)onmouseout ==> 鼠标从某元素移开。
(6)onmouseleave ==> 鼠标从某元素移开。(这个事件不冒泡)
(7)onmousemove ==> 鼠标被移动时触发。
(8)oncontextmenu ==> 鼠标右键菜单展开时触发。
(二)、键盘事件
(1) onkeydown ==> 某个键盘按键被按下。
(2) onkeyup ==> 某个键盘按键被松开。
(3) onkeypress ==> 键盘<字符键>被按下,而且如果按住不放的话,会重复触发此事件。
(三)UI事件
(1) onload ==> 页面元素(包括图片多媒体等)加载完成后
(2) onscroll ==> 滚动时触发。
(3) onresize ==> 窗口或框架被重新调整大小
(四)表单事件
(1) onselect ==> 输入框文本被选中。
(2) onblur ==> 元素失去焦点时触发。
(3) onfocus ==> 元素获得焦点时触发。
(4) onchange ==> 元素内容被改变,且失去焦点时触发。
(5) onreset ==> 重置按钮被点击。
(6) onsubmit ==> 确认按钮被点击。
(7) oninput ==> 输入字符时触发
三、event对象
(兼容ie浏览器 e = e||window.event)
兼容写法,一般直接给e赋值再用:e = e || window.event;
1、作用:监听事件执行过程中的状态,用来保存当前事件的信息
2、event对象的属性
(一)与鼠标相关的
1、 鼠标按键
(1.1)、鼠标按键
*button 返回当事件被触发时,哪个鼠标按键被点击。
* 标准浏览器:0,1,2(左,滚,右)
* IE8-(IE8以下的浏览器)
1鼠标左键, 2鼠标右键, 3左右同时按, 4滚轮, 5左键加滚轮, 6右键加滚轮, 7三个同时
1 例:<div id="output"></div> 2 var output = document.getElementById("output"); 3 output.onmousedown = function(e){ 4 if(e.button == 0){ 5 output.innerHTML = "开火"; 6 }else if(e.button == 1){ 7 output.innerHTML = "切枪"; 8 }else if(e.button == 2){ 9 output.innerHTML = "开镜"; 10 } 11 }
2、光标位置信息
(1) clientX /clientY ==> 可视区域的位置
1 光标相对于浏览器可视区域的位置,也就是浏览器坐标。 2 document.onmousemove = function(e){ output.children[0].innerHTML = "client:"+e.clientX+','+e.clientY; 3 }
(2) screenX /screenY ==> 电脑屏幕
1 光标指针相对于电脑屏幕的水平/垂直坐标 2 document.onmousemove = function(e){ output.children[1].innerHTML = "screen:"+e.screenX+','+e.screenY; 3 }
(3)pageX /pageY ==> 与滚动关联
* 鼠标相对于文档的位置
* 包括滚动条滚动的距离,即:e.clientX+window.scrollX
* IE8-不支持
1 document.onmousemove = function(e){ output.children[2].innerHTML = "page:"+e.pageX+','+e.pageY; 2 }
(4)offsetX/offsetY ==>光标相对偏移量
* 光标相对于事件源对象左上角相对偏移量。
* 事件源对象:触发事件的对象
(二)event与键盘有关的属性
1、 which/(event.which)
keyCode ==> (IE8)
兼容写法 var e.which = e.which || e.keyCode
* 对于keypress事件,该属性声明了被敲击的键生成的 Unicode 字符码(ASCII码)
* 对于keydown和keyup事件,它**指定了被敲击的键的虚拟键盘码**。虚拟键盘码可能和使用的键盘的布局相关。
2、ctrlKey ==> CTRL 键
* 当事件被触发时,CTRL 键是否被按下。返回值为布尔值
3、 altKey ==> Alt键
* 当事件被触发时,Alt键是否被按下。返回值为布尔值
4、 shiftKey ==> Shift键
* 当事件被触发时,Shift键是否被按下。返回值为布尔值
案例:愤怒的小鸟
1 //键盘按下,根据上下左右移动小鸟 2 document.onkeydown = function(e){ 3 // 1.获取小鸟当前位置 4 var top = bird.offsetTop; 5 var left = bird.offsetLeft; 6 //2.初始化速度及类名变量 7 var speed = 10; 8 var className = ''; 9 // 3.判断按下上下左右方向键,设置left值及类名变量值 10 switch(e.keyCode){ case 37:left -= speed; className = ''; break; //同理其他方向 } 11 // 4.通过变量值,设置bird的位置,及类名 12 bird.style.left = left + 'px'; 13 bird.style.top = top + 'px'; 14 bird.className = className;}
两个按键同时按的案例
1 document.onkeydown = function(e){ 2 if(e.ctrlKey && e.which == 66){ 3 alert("打开背包,拿出意大利炮"); 4 } 5 } 6
四、事件冒泡
1、涵义
在一个对象上触发某类事件(如onclick事件),那么事件就会沿着DOM树向这个对象的父级传播,从里到外,直至事件到达了最顶层(document/window)
2、阻止事件冒泡 ==> event.stopPropagation()
1 例: erzi.onclick = function(e){ 2 console.log("erzi"); 3 e.stopPropagation(); 4 }
3、事件委托
(1)、涵义
* 利用事件冒泡原理,把本来绑定给某个元素的事件委托给它的父级(已经存在页面元素)处理。
(2)影响页面性能的三大操作
(1) 频繁操作dom节点
(2) 过多的事件绑定
(3) 页面请求过多
(3)事件源对象:获取到触发事件的元素 (event.target)
备注:兼容写法 var target = e.target || e.srcElement
五、阻止浏览器默认行为
链接跳转
表单提交
右键菜单
文本的选择
标准:event.preventDefault();
兼容:e.preventDefault ? e.preventDefault(): e.returnValue = true;
IE8-:event.returnValue = false;
1 案例:自定义右键菜单 2 window.onload = function(){ 3 // 1.获取菜单,鼠标右键展开时,触发函数:出现菜单,跟随光标位置 4 // 2.取消默认行为 5 // 3.点击空白区域,隐藏菜单 6 // 4.点击菜单里面的li,将文字呈现在txt里面.点击菜单里面的span,将li的文本呈现在txt里面 7 var contextMenu = document.getElementsByClassName("contextMenu")[0]; 8 var txt = document.getElementsByClassName("txt")[0]; 9 document.oncontextmenu = function(e){ 10 e = e || window.event; 11 e.preventDefault(); 12 contextMenu.style.display = "block"; 13 contextMenu.style.left = e.pageX + 'px'; 14 contextMenu.style.top = e.pageY + 'px'; 15 } 16 document.onclick = function(e){ 17 e = e || window.event; 18 if(e.button == 0){ 19 contextMenu.style.display = "none"; 20 } 21 } 22 contextMenu.onclick = function(e){ 23 // e.target 触发事件的对象 24 if(e.button == 0){ 25 if(e.target.tagName == "LI"){ 26 txt.value = e.target.innerText; 27 }else if(e.target.tagName == "SPAN"){ 28 txt.value = e.target.innerText; 29 } 30 } 31 } 32 33 }
六、事件捕获(反冒泡)
1、事件的执行阶段:事件冒泡、事件捕获,先捕获再冒泡
2、同一元素的同一事件只能在其中一个阶段执行
3、默认情况下,事件的执行都是默认在冒泡阶段执行
4、事件的传播:
(1)事件冒泡:从下往上
(2)事件捕获:从上往下
*监听器
1、标准浏览器:元素.addEventListener(事件名,事件处理函数,是否捕获(默认false,为冒泡))
例:target.addEventListener("click", fn, false);
2、IE8-:元素.attachEvent(on+事件名,事件处理函数)
例:target.attachEvent("on"+"click",fun);
备注:
- 可以绑定多个处理函数在一个对象上, 执行顺序按照绑定的顺序来(标准)
- 不同元素事件执行顺序跟html结构有关
- 相同元素事件执行顺序跟绑定先后有关
- 可以绑定多个函数在一个对象上, 执行顺序按照绑定的反序(ie8-)
七、事件的绑定方式
1、html属性[onclick="函数名(实参)"] 不推荐使用,维护不方便,调用数据困难
2、"on"+type :
* ele.onclick = 函数名;
* ele.onclick = function(){}
* 只能在冒泡阶段执行,只能给同一个元素绑定一个相同事件
3、事件监听器
1、可以绑定多个处理函数在一个对象上, 执行顺序按照绑定的顺序来(标准)
(1.1)不同元素事件执行顺序跟html结构有关
(1.2)相同元素事件执行顺序跟绑定先后有关
2、可以绑定多个函数在一个对象上, 执行顺序按照绑定的反序(ie8-)
(1) ele.addEventListener(type,fn,isCapture) ==>标准浏览器
* type 事件类型
* fn 函数
* isCapture 是否捕获,若为true为捕获阶段,默认为false冒泡阶段
* 允许给同一个元素添加多个相同事件
(2) ele.attachEvent("on"+type,fn) ==> ie8-不支持捕获
封装:绑定事件,兼容浏览器
1 function bind(ele,type,fn,isCapture){ 2 // 优先使用事件监听器 3 if(ele.addEventListerner){ 4 // 标准浏览器 5 ele.addEventListerner(type,fn,isCapture); 6 }else if(ele.attachEvent){ 7 // IE8- 8 ele.attachEvent('on' + type,fn); 9 }else{ 10 // DOM节点绑定方式 11 ele['on' + type] = fn 12 } 13 }
4、取消事件绑定
(1) ele["on"+ type] = null
1 例:ele.onclick = null
(2) ele.removeEventListener(type,fn) ==> 标准
移除事件的函数与添加事件的函数必须是同一个,才可以移除,否则不能移除事件
(3) ele.detachEvent("on"+type,fn) ==> IE8
传入的参数fn要跟添加时一样,否则不能移除事件
八、拖拽的思路
1 原理:鼠标按下且移动鼠标时,改变当前元素的top,left值 2 //给目标元素添加onmousedown事件 3 //- 拖拽的前提是目标元素设置css定位 4 //- 记录按下鼠标位置与元素左上角的偏移量offsetX,offsetY 5 box.onmousedown = function(e){ 6 var ox = e.offsetX; 7 var oy = e.offsetY; 8 //当onmousedown发生以后,此刻给document添加onmousemove事件 9 // - 意味着此刻鼠标在网页的移动都将改变目标元素的位置 10 // - 目标元素的left = 鼠标的pageX – ox 11 // - 目标元素的top = 鼠标的pageY– oy 12 document.onmousemove = function(e){ 13 box.style.left = e.pageX - ox + 'px'; 14 box.style.top = e.pageY - oy + 'px'; 15 } 16 } 17 //给目标元素或者document(效果有差异)添加onmouseup事件,清空document的onmousemove事件 18 document.onmouseup = function(){ 19 document.onmousemove = null; 20 } 21