🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
## 1. 事件简介 ```JS 不管什么语言,事件无处不在,点击后弹窗、在窗口移进移出、点击、关闭、滚动、改变窗口大小、都是一个事件 var btn = document.getELementByID('button'); var section = document.querySelector('section'); var flag = false; btn.addEventListener('click,function'() { section.style.backgroundColor = flag ? '#ddd' : '#bbb'; flag = !flag; },false); ``` ## 2. 事件模型 ```JS 上古时代的事件流 事件冒泡:Document <---- Element html <---- Element body <---- Element section <---- Element button 事件捕获:Document ----> Element html ----> Element body ----> Element section ----> Element button 现时代的标准事件流 DOM2级事件”规定的事件流包括三个阶段: 事件捕获阶段:Document ----> Element html ----> Element body ----> Element section ==> 处于目标阶段: Element section ----> Element button ==> 事件冒泡阶段: Element button ----> Document 事件捕获由于浏览器问题很少人用 首先发生的是事件捕获阶段,为截获事件提供了机会。然后是实际的目标接收事件。最后一个阶段是冒泡阶段。 ``` ## 3. 事件处理程序和事件对象 ```js var btn = document.getELementByID('button'); var section = document.querySelector('section'); var flag = false; btn.addEventListener('click,function'() { section.style.backgroundColor = flag ? '#ddd' : '#bbb'; flag = !flag; },false); addEventListener :给事件添加方法,可以无限添加 function :这是事件的处理程序 还有事件对象: flag ? '#ddd' : '#bbb'; ``` ```JS 事件处理程序: 1.包括添加(首先要把添加的那个元素找到)addEventListener 只推荐以下这种方法: 2.作用域: this 3.删除:removeEventListener 事件对象: 1.包含着所有与事件相关的信息 2.冒泡 var h1 = document.querySelector('hl'); // console.log(h1); // h1.addEventListener(type, handle, false) // h1.removeEventListener(type, handle) var handle = function(event) { console.log('event', event); };1 // h1.addEventListener('click', handle, false); // h1.removeEventListener('click', handle); document.body.addEventListener('click', handle, false); h1.addEventListener('click', function(event) { event.stopPropagation(); }, false); ``` ## 4. [资料] 事件兼容性初探 ### 事件兼容性初探 ```JS 兼容性当然是指浏览器的兼容性,而浏览器的兼容性基本上是指 IE的兼容性 。是的,如果要找出最痛恨 IE浏览器的人, 非前端工程师莫属。IE,不标准却用户量巨大,想不管它都不行。 当然,也不用为此沮丧,IE 的市场份额逐年下滑,胜利终将属于前端开发! ``` ### 几个重要的区别 #### 事件模型 ```JS IE9 之前只支持事件冒泡,不支持事件捕获,也因此事件捕获在实际开发的过程当中使用的非常少。 addEventListener IE9 之前不支持 addEventListener 和 removeEventListener , 但是有对应的方法 attachEvent 和 detachEvent ,影响也不是很大。 ``` #### 事件对象 ```JS IE9(不包括IE9) 之前的事件对象也不规范。 第一个是获取对象的方式不同。 elem.attachEvent('click', function (event) { // 这种绑定方式,`event` 对象可以正确拿到 }); elem.onclick = function() { var event = window.event; // 这种绑定方式,只能从 `window` 上拿 } 第二个,事件对象几个常用的属性和方法也不标准,但有对应的属性和实现相同的效果。 ``` 标准 | IE | 说明 ---- | ---- | ---- stopPropagation() | cancelBubble | cancelBubble默认值为 false ,设为 true 可以取消事件冒泡。 preventDefault() | returnValue | 默认值为 true ,设置为 false 可以取消事件的默认行为。 target | srcElement | 这个好说,事件的目标元素。 ``` 有必要说下事件的默认行为,举个例子, <a> 元素,点击就会跳转到一个新的页面,这个就是浏览器自带的事件的默认行为。 有时候我们不想要这个行为,那么调用事件对象上的 preventDefault() 方法就能达成效果。 ``` #### 跨浏览器的事件 ```JS 我们当然不能只局限于理论,而是要用于实战。 我们的思路就是封装一个函数,让它的可以在所有的浏览器中正确的绑定事件,让使用者不用关注各个浏览器之间的差异, 比如下面的 on 函数。 /** * 修复事件对象不兼容的地方 */ function fixEventObj(e) { e.target = e.target || e.srcElement; e.preventDefault = e.preventDefault || function() { e.returnValue = false; }; e.stopPropagation = e.stopPropagation || function() { e.cancelBubble = true; }; return e; } /** * 跨浏览器的绑定事件 */ function on(elem, type, handle) { if (elem.addEventListener) { // 检测是否有标准方法 elem.addEventListener(type, handle, false); } else if (elem.attachEvent) { // 试图使用 `attachEvent` elem.attachEvent('on' + type, function(event) { event = fixEventObj(event); handle.call(elem, event); // 使用 call 来改变 handle 的作用域,使其指向 elem }); } else { // 兜底 elem['on' + type] = function() { var event = fixEventObj(window.event); handle.call(elem, event); } } } // 调用 on(document.body, 'click', function(e) { console.log('哈哈哈,好用!', e); }); 这里有个实例页面,点击查看:http://coding.imweb.io/demo/p4/event-cross-browser.html 代码是次要的,思路是重点。大家可以模仿这个 on 写个 off 函数,来跨浏览器的解绑事件。 ```` ### 绑定事件的历史演进 上面我们在写兼容代码的时候,涉及到 DOM0 级和 DOM2 级事件处理。 ```JS elem.onclick = function() {}; // dom 属性的绑定方式就是 DOM0 级 elem.addEventListener(); // 这种就是 DOM2 级 ``` 这里不含糊,推荐后一种。 DOM 也有版本演进,DOM0 和 DOM2 就是不同的版本,当然,版本啥的不是我们的重点,我们想探讨的是这两者的区别。 ``` // 这种方式只能绑定一个 handle // 当你试图绑定第二个时,就会覆盖上一个 elem.onclick = function() {}; // 这种则可绑定任意个 handle // 在多人开发的项目中,这个特点非常重要,不同的伙伴给同一个元素绑定事件的几率很大的 elem.addEventListener(); // 这种就是 DOM2 级 ``` 兼容性问题是肯定存在的,遇到这类问题更要耐心,试着找到不同之处,写出兼容性代码,终有一天,你能写出自己的 jQuery ! ## 5. 事件类型 ### 鼠标类 不止 click 事件类型 * click * mousedown (鼠标按下去) * mouseup (鼠标反弹的那时刻) * mouseenter 和元素的子元素无关(鼠标移进来) * mouseleave 和元素的子元素无关(鼠标移出去) * mouseover 受子元素的影响(鼠标移进来) * mouseout 受子元素的影响(鼠标移出去) * mousemove (鼠标移来移去就是 mousemove 的意思) ```JS 选中一个 click 事件类型的父元素是 ul,绑定一个 mouseenter ;当鼠标移动到 ul 的时候,就会触发 ul 的 mouseenter, 当鼠标移动到 li 上不会触发ul 的 mouseleave;但是绑定一个 mouseover 和 mouseout 事件, 当鼠标移动到 ul 的时候就会触发 mouseover,接着当鼠标移动到 click 的 li之上, ul 就会触发 mouseout 事件; mouseup事件在释放按下的鼠标键时触发。 mousedown事件在按下鼠标键时触发。 click 在用户单击主鼠标按钮或者按下回车键时触发。只有在同一个元素上相继触发 mousedown 和 mouseup 事件, 才会触发 click 事件。因此正确的触发顺序是:mousedown首先触发,mouseup接着触发,click最后触发。 ``` #### 键盘类 :管理后台才常用 ```js document.addEventListener('keypress', function(event) { console.log(event. keyCode); }, false); ``` * keydown 键盘按下 * keypress 键盘按下 * keyup 鼠标放开 #### UI 类事件 (下面都是 window事件) ```JS window.addEventListener('scroll', function(event) { console.log(event.type); }, false); window.addEventListener('resize', function(event) { console.log(event.type); }, false); ``` * load 页面加载完成 * unload 页面卸载 * resize 页面调整大小 * scroll 页面滚动 ## 6. [资料] 键盘事件 keypres] #### 键盘事件 keypress 和 keydown ```JS 有个示例页面,大家试试,链接:http://coding.imweb.io/demo/p4/event-keypress-and-keydown.html keypress 按字符集触发 keydown 按所有键都会触发 两者设计的初衷就不同。 keypress 就是用来检测用户输了啥字符的,而 keydown 则是单纯的检测用户是否按了键盘上的按键,所以 keypress 常用。 两者事件对象上的 keyCode 值也不同。 keyCode是一个代码,与键盘上的一个键对应。在 keypress 事件中,这个 keyCode 还与 ASCII码对应,比如keyCode 等于 105 , 就是按了 i。最后说下,判断一个前端专业不专业,就问下他开发界面的时候有没有考虑过键盘事件。 参考文章 JavaScript Madness: Keyboard Events :http://unixpapa.com/js/key.html ASCII 对照表 ```