1:三种注册事件的方式
法一:<input type="button" value="点我" id="btn">
var btn = document.getElementById("btn"); btn.onclick = function () { alert('btn'); }
缺点:无法给同一个对象的同一个事件注册多个不同的处理函数
法二:
btn.addEventListener('click', function () { alert('2') });
优点:弥补函数赋值带来的缺点
缺点:浏览器的兼容性老版本的ie,ie9+以后
法三:
attachEvent(btn, 'onclick', function () { alert(3) })
只是为了兼容ie浏览器
处理兼容性问题:兼容代码
function addf(element, eventName, fn) { if (element.addEventListener) { element.addEventListener(eventName, fn) } else if (element.attachEvent) { element.attachEvent('on' + eventName, fn) } else { // 相当于 element.onclick =fn element['on' + click] = fn } }
移除事件:
法一移除: var btn = document.getElementById("btn"); btn.onclick = function () { alert('btn'); //关键点: btn.onclick = null }
法二移除:
由于匿名函数只能使用一次,在注册的时候已经使用了匿名函数u,所以移除的时候,需要命名函数
function btnClick() { alert('移除'); // dome中标准的写法 btn.removeEventListener('click', btnClick) }
法三移除
function btnClick()
{ alert('移除');
btn.detaEvent('click', btnClick) }
移除代码的兼容写法
function removef(element, eventName, fn) { if (element.removeEventListener) { element.removeListener(eventName, fn) } else if (element.detachEvent) { element.detachEvent('on' + eventName, fn) } else { element['on' + eventName] = fn } }
2:事件的三个阶段
事件捕获阶段 目标阶段 事件冒泡阶段
addEventListener的三个参数:事件类型,事件处理函数,默认是false(事件冒泡)
box.onclick 只有事件冒泡 attachEvent只有两个参数:事件类型,事件处理函数 只有事件冒泡
3:事件委托:
事件委托(用到的是事件对象,说白了,就是传参)----原理是事件冒泡
事件委托:自己不用做,委托给父级来做
事件委托用到一个很重要的知识,事件对象,事件对象里面有很多属性,可以为我们提供服务
例子:通过ul,不用可以写出li,就能获取到li,并对其进行操作
4:巧用e.type
一个函数使用多个事件
5:鼠标跟着图片飞:
这里需要注意:图片要想动,必须脱离文档流
clientX,clientY是获取可视区域的坐标
pageX,pageY是获取页面的坐标
获取页面滚动的距离的兼容代码
获取鼠标在页面的位置,处理浏览器兼容问题
实用:
6:取消默认行为
7:阻止冒泡
8:只能输入数字的文本框
键盘事件:keyCode获取键值 ,从而进行判断,由于键盘输入也属于默认行为,所以可以用取消默认行为的方法来实现
事件面试
1:事件模型:事件模型有三种
脚本模型
内联模型
动态绑定
2:事件委托/事件代理(原理是事件冒泡和事件对象)
减少dom操作,优化性能
当用事件委托的时候(利用的是事件对象),根本就不需要去遍历元素的子节点,只需要给父级元素添加事件就好了,其他的都是在js里面的执行,这样可以大大的减少dom操作,这才是事件委托的精髓所在。
3:如何让事件先冒泡后捕获
给一个元素绑定两个addEventListener,其中一个参数为false(冒泡),一个参数是true(捕获),调整他们的代码顺序,将设置为冒泡(false)的监听是事件放在捕获的监听事件之后