目录
事件详解及应用
注册事件的另两种方式
- btn.click = function() { }注册事件的结果是,只能给按钮btn一次处理事件的函数,当再 赋值一次处理函数时会把第一次的给覆盖掉,因为这时等号=赋值的一次。无法给同一个对象的同一个事件注册多个事件处理函数。
- btn.addEventListener(type, listenner,[,option]); 有三个参数,第三个参数为中括号可选的意思。参数一type为监听器类型的意思如click,参数二listenner为一个实现了接口的对象或一个函数function。如 btn.addEventListener('click', function() { })。该注册事件方法的特点在于可为同一按钮注册多个监听事件且不会有覆盖的情况 。有浏览器兼容性问题,IE9以后才支持
- btn.attachEvent('onclick', function() { });注册事件的第三种方式,不支持多个事件处理函数。只有两个参数非标准方法,IE里特有的方法,浏览器兼容性问题,IE6-10的老版本才支持.
处理注册事件的兼容性问题
function addEventListener(element, eventName, fn) { //判断当前浏览器是否支持addEventListener方法 if (element.addEventListener) { //若该元素有addEventListener方法则为ture element.addEventListener(eventName, fn); //第三个参数可选,默认false }else if (element.attachEvent){ element.attachEvent('on' + eventName, fn); } else { element['on' + eventName] = fn; //相当于element onclick = fu;参数除了可以用.还可以用中括号 } }
移除事件
顺序对应上面的注册事件
- btn.onclick = null; 将注册点击事件赋值为null即可
- 如果要移除事件,注册事件的时候不能使用匿名函数,因为匿名函数使用过后就清除了,而且removeEventListener中参数中要写具体的函数名。如btn.addEventListener('click', btnClick); function btnClick() { ... btn.removerEventListener('click', btnClick); ... }
- chrome 中不支持attachEvent,因为它是IE6-10老版本特有的注册事件方法。 移除方式为: btn.detachEvent('onclick', btnClick);
处理移除事件的兼容性问题
function removeEventListener(element, eventName, fn) { //判断当前浏览器是否支持removeEventListener方法 if (element.removeEventListener) { //若该元素有removeEventListener方法则为ture element.removeEventListener(eventName, fn); //第三个参数可选,默认false }else if (element.detachEvent){ element.detachEvent('on' + eventName, fn); } else { element['on' + eventName] = fn; //相当于element onclick = fu;参数除了可以用.还可以用中括号 } }
事件的三个阶段
- 第一阶段:捕获阶段(true,从最外层开始执行)。而onclick和attachEvent没有布尔值,所有只有捕获阶段。
- 第二阶段:执行当前点击的元素
- 第三阶段:冒泡阶段(false,从最里层开始执行)
- addEventListener的第三个参数的作用。如给三个div注册三个点击事件,其id放到一个数组里var array = [box1, box2, box3];
//addEventListener的第三个参数为false的时候为事件冒泡 for (var i = 0; i < array.length; i++) { array[i].addEventListener('click', function () { console.log(this.id); //要打印对应的id方法是用this,指当前对象 //输出结果为body box3,box2,box1为事件冒泡,即从最里开始 }) ; }
即当addEventListener的第三个参数为false的时候为事件冒泡,第三个参数为true时,是事件捕获(从最外层开始执行,输出为box1,box2,box3,body)
事件冒泡的作用
有了事件冒泡,那么我们就不用给所有对象都注册点击事件,如ul下有很多li,那么我们如果想要获得其中的li只需要给ul注册事件即可,如案例
var ul = document.getElementById('ul'); ul.onclick = function (e) { //e事件参数(事件对象):当事件发生的时候,可以获取一些和事件相关的数据 //获取到当前点击的li,让当前点击的li高亮显示 e.target.style.backgroundColor = 'red'; //e.target是当前真正触发事件的对象 }
事件对象
通过事件对象,可以获取到事件发生的时候和事件相关的一些数据,如事件的类型,事件的坐标
//通过事件对象,可以获取到实践发生的时候和事件相关的一些数据 var btn = document.getElementById('btn'); btn.onclick = function (e) { //DOM标准中,e是给事件处理函数的一个参数,e就是事件对象 //在老版本的IE中获取事件对象的方式,window.event //处理事件对象的浏览器的兼容性 e = e || window.even; //若存在事件对象e则返回e,不存在即为false,则||为布尔判断,则返回window.even //事件的阶段: 1.捕获阶段 2.目标阶段 3.冒泡阶段 (了解即可) console.log(e.eventPhase); //根据返回的数字来判断事件的阶段 console.log(e.type); //获取事件名称,如获取正在触发的是click,mouseOver或mouseOut等 //e.target 为获取真正触发事件的对象 console.log(e.target); //获取到鼠标点击的x、y坐标,该坐标是相对于浏览器可视区域的坐标 console.log(e.clientX); console.log(e.clientY); //获取鼠标在当前页面的位置,当有滚动条的时候,注意有兼容性问题,IE9以后才支持 console.log(e.pageX); console.log(e.pageY); }
案例之跟着鼠标走的图片
首先是相对于整个文档document来动,其次要获取鼠标的位置就要用到事件对象e(事件对象e有兼容性问题),然后是图片的脱离文档流即设置(position:absolute;)
var ts = document.getElementById('ts'); //获取图片的id document.onmousemove = function (e) { e = e || window.event; ts.style.left = e.pageX - 10 + 'px'; ts.style.right = e.pageY - 10 + 'px'; //减10是为了图片离鼠标更近一些 }
获取页面滚动的距离
在以前的版本中是没有pageX属性的,那么当时的处理方法是: pageX = clientY + 页面滚动出去的距离。
页面滚动出去的距离的获取方式为:
document.onclick = function () { //给文档注册点击事件 //输出页面滚动出去的距离 console.log(document.body.scrollLeft); console.log(document.body.scrollTop); //documentElement 文档的根元素 即html标签 //console.log(document.documentElement); //输出为整个html的代码 //有些浏览器是使用这两个属性来获取的 console.log(document.documentElement.scrollLeft); console.log(document.documentElement.scrollTop); }
获取页面滚动距离的浏览器兼容性问题解决
//获取页面滚动出去的距离 function getScroll() { var scrollLeft = document.body.scrollLeft || document.documentElement.scrollLeft; var scrollTop = document.body.scrollTop || document.documentElement.scrollTop; return { //返回的是一个对象 scrollLeft: scrollLeft; scrollTop: scrollTop; } }
获取鼠标在页面上的位置的浏览器兼容性解决
//获取鼠标在页面的位置,处理浏览器兼容性的问题 function getPage( e ) { var pageX = e.pageX || e.clientX + getScroll().scrollLeft; var pageY = e.pageY || e.clientY + getScroll().scrollTop; return { //返回的是一个对象 pageX: pageX; pageY: pageY; } } document.onclick = function (e) { e = e || window.event; //处理e的兼容性问题 console.log(getPage(e).pageX); console.log(getPage(e).pageY); }
获取鼠标在盒子上的坐标
常用于获取 了鼠标在盒子上的位置后用于放大作用
var box = document.getElementById('box'); box.onclick = function (e) { //获取盒子在页面上的位置 console.log(this.offsetLeft); //offsetLeft为盒子在页面上的纵坐标 console.log(this.offsetTop); e = e || window.even; //e对象的兼容性处理,有e对象则返回e,无则返回window.even //获取鼠标在盒子中的位置 = 鼠标的坐标 - 盒子的坐标 var x = getPage(e).pageX - this.offsetLeft; //e.pageX有兼容性问题,所有这里是调用了前面的兼容性处理的函数getPage(),此函数有返回属性pageX var y = getPage(e).pageY - this.offsetTop; }
取消默认行为的执行
- 如取消a标签链接的跳转行为
link.onclick = function (e) { alert('hello'); //取消默认行为的执行 return false; //即在注册点击事件时没有参数对象e,可用此方法来取消链接点击跳转页面的问题 //DOM中的标准方法 e.preventDafault(); //IE的老版本方法,是一个非标准的方法 e.returnValue = false; }
- 取消冒泡行为
//Propagation 传播,stopPropagation为停止事件传播,取消冒泡,标准的DOM方法 e.stopPropagation(); //取消冒泡的另一种方式:IE浏览器老版本的方法,是一个非标准的方法 e.cancelBubble = true;
案例之文本框只能输入数字
首先涉及到一个键盘事件,keydown:键盘按下的时候; keyup:键盘弹起的时候
keydown和keyup之间的区别:keydown的时候我们所按的键还没有落入文本框,keyup弹起时所按的键已经落入文本框
//所以我们需要在键盘按下的时候判断是否是数字 var txt = document.getElementById('txt'); txt.onkeydown = function (e) { //判断当前用户按下的键是否是数字 e = e || window.event; //事件对象e存在兼容性问题,此处为兼容性处理,判断当前的e是否存在 //e.keyCode 为键盘码即二进制,键盘上的所有字符都代表一个二进制 数字的键盘码为48-57 //console.log(e.keyCode); //指当前点击事件的键盘码,若不知道该字符的键盘码可输出打印看看 if ((e.keyCode < 48 || e.keyCode > 57) && e.keyCode !== 8) { //后退键删除码为8 //如果输入的非数字则取消默认行为 e.preventDefault(); //这里不用return false;取消默认行为是因为若后面还有代码,则该return表示已结束退出并不会执行 } }