事件流JavaScript操作css称为脚本化CSS,而JavaScript与HTML的交互是通过事件实现的。事件就是文档或浏览器窗口中发生的一些特定的交互瞬间，而事件流(又叫事件传播)描述的是从页面中接收事件的顺序。历史当浏览器发展到第四代时(IE4及Netscape4)，浏览器开发团队遇到了一个很有意思的问题：页面的哪一部分会拥有某个特定的事件？想象画在一张纸上的一组同心圆。如果把手指放在圆心上，那么手指指向的不是一个圆，而是纸上的所有圆两家公司的浏览器开发团队在看待浏览器事件方面还是一致的**。如果单击了某个按钮，他们都认为单击事件不仅仅发生在按钮上，甚至也单击了整个页面**但有意思的是，IE和Netscape开发团队居然提出了差不多是完全相反的事件流的概念。IE的事件流是事件冒泡流，而Netscape的事件流是事件捕获流事件冒泡IE的事件流叫做事件冒泡(eventy bubbling),即事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收，然后逐级向上传播到较为不具体的节点(文档)以下列HTML结构为例，说明事件冒泡、事件捕获及事件流 如果单击了页面中的 元素，那么这个click事件沿DOM树向上传播，在每一级节点上都会发生，按照如下顺序传播：注意：所有现代浏览器都支持冒泡，但在具体实现还是有一些差别。IE9以上、Firfox、Chrome、safari 将事件一直冒泡到window对象事件捕获事件捕获的思想是不太具体的节点应该更早接收到事件，而最具体的节点应该最后接收到事件。事件捕获的用意在于在事件到达预定目标之前捕获它 以同样的HTML结构为例，说明事件捕获在事件捕获过程中，document对象首先接收到click事件，然后事件沿DOM树依次向下，一直传播到事件的实际目标，即 元素 注意：IE9、Firefox、Chrome、safari等现代浏览器都支持事件捕获，但从window对象开始获取addEventListener(eventType,eventListener,useCapture)方法中的第三个参数设置为true时，即为事件捕获阶段事件流​事件流又称为事件传播，DOM2级事件规定的事件流包括三个阶段：事件捕获阶段(capture phase)、处于目标阶段(target phase)和事件冒泡阶段(bubbling phase)首先发生的是事件捕获，为截获事件提供了机会。然后是实际的目标接收到事件，最后一个阶段是冒泡阶段，可以在这个阶段对事件做出响应事件处理程序事件处理程序又叫事件侦听器，实际上就是事件的绑定函数。事件发生时会执行函数中相应代码。事件处理程序：HTML事件处理程序DOM0级事件处理程序DOM2级事件处理程序IE事件处理程序下面将详细介绍该部分内容HTML事件处理程序​ 某个元素支持的每种事件，都可以使用一个与相应事件处理程序同名的HTML特性来指定。这个特性的值应该是能够执行的javascript代码​ 在事件处理程序函数内部，this等于事件的目标元素 在HTML中定义的事件处理程序也可以调用在页面其它地方定义的脚本 HTML事件处理程序会创建一个封装着元素属性值的函数。这个函数中有一个局部变量event，也就是事件对象。通过event变量，可以直接访问事件对象，不用自己定义它，也不用从函数的参数列表中获取。（下节会重点讲事件对象上的属性） 在事件处理程序函数内部，可以像访问局部变量一样访问document及该元素本身的成员。如此一来，事件处理程序要访问自己的属性就简单多了 缺点耦合问题​ 客户端编程的通用风格是保持HTML内容和javaScript行为分离，所以应该避免使用HTML事件处理程序属性，因为这些属性直接混合了javascript和HTML，且不易扩展DOM0级事件处理程序​ 通过javascript指定事件处理程序的传统方式，就是将一个函数赋值给一个事件处理程序属性。这种为事件处理程序赋值的方法是在第四代Web浏览器中出现的，而且至今仍然为所有现代浏览器所支持。原因一是简单，二是具有跨浏览器的优势每个元素都有自己的事件处理程序属性，这些属性通常全部小写，将这种属性的值设置为一个函数，就可以指定事件处理程序注意：以DOM0级方式添加的事件处理程序会在事件流的冒泡阶段被处理 ​ 可以通过将事件处理程序属性设置为null来删除事件处理程序box.onclick = null;缺点​ 围绕着每个事件目标对于每种事件类型只能添加一个事件处理程序DOM2级事件处理程序​ DOM2级事件处理程序定义了两个方法用于处理指定和删除事件处理程序的操作：addEventListener()和removeEventListener()。所有DOM节点中都包含这两个方法，并且它们都接受3个参数：要处理的事件名、作为事件处理程序的函数和一个布尔值。最后的布尔值参数如果是true，表示在捕获阶段调用事件处理程序；如果是false，表示在冒泡阶段调用事件处理程序。若最后的布尔值不填写，则和false效果一样 注意： IE8浏览器不支持DOM2级事件处理程序​ 使用DOM2级事件处理程序的好处是可以添加多个事件处理程序，并按照他们添加的顺序触发 得到输出结果为： 12可以做个延迟操作来验证： 得到输出的结果为：21参数​ 如果希望向监听函数传递参数，可以用匿名函数包装一个监听函数 移除​ 通过addEventListener()添加的事件处理程序只能使用removeEventListener()来移除，移除时传入的参数与添加处理程序时使用的参数相同。这意味着，addEventListener()添加的匿名函数将无法移除。 以下无效 以下有效 IE事件处理程序IE实现了与DOM中类似的两个方法：attachEvent()和detachEvent()。这两个方法接受相同的两个参数：事件处理程序名称与事件处理程序函数。由于IE8-浏览器只支持事件冒泡，所以通过attachEvent()添加的事件处理程序都会被添加到事件冒泡阶段 attachEvent()方法的第一个参数是"onclick"，而非DOM的addEventListener()方法中的"click" 注意：attachEvent()方法只冒泡到document，且IE10-浏览器支持this​ 与其他三个事件处理程序不同，IE事件处理程序的this指向了window,而非被绑定事件的元素。 顺序​使用attachEvent()方法添加的事件处理程序的触发顺序是有区别的。IE9、10浏览器是按正序执行的，而IE8-浏览器则是按倒序执行的 移除使用attachEvent()添加的事件可以通过detachEvent()来移除，条件是必须提供相同的参数。与DOM方法一样，这也意味着添加的匿名函数将不能被移除。不过，只要能够将对相同函数的引用传给detachEvent()，就可以移除相应的事件处理程序 以下无效 以下有效 【相同点】如果同时出现HTML事件处理程序和DOM0级事件处理程序，DOM0级会覆盖HTML事件处理程序【不同点】 chrome/safari/FF以及IE11浏览器结果为：DOM0级 DOM2级 IE9、10浏览器结果为：DOM0级 DOM2级 IE IE8-浏览器结果为：DOM0级 IE事件对象在触发DOM上的某个事件时，会产生一个事件对象event，这个对象中包含着所有与事件有关的信息。所有浏览器都支持event对象，但支持方式不同。本文将详细介绍事件对象获取事件对象event对象是事件程序的第一个参数注意： IE8 浏览器不支持 兼容​ 于是，获取事件对象的常见兼容性写法如下 ​ 通过点击按tab键将焦点切换到button按钮上可以出发focus事件 事件目标​ 关于事件目标，共有currentTarget、target、srcElement这三个属性currentTarget​ currentTarget属性返回事件当前所在的节点，即正在执行的监听函数所绑定的那个节点IE8 浏览器不支持currentTarget属性返回事件当前所在的节点，即正在执行的监听函数所绑定的那个节点 1 2 target​ currentTarget属性返回事件正在执行的监听函数所绑定的节点，而target属性返回事件的实际目标节点IE8 浏览器不支持以下代码中，点击该实际目标节点时，颜色变红；移出，颜色变浅蓝 1 2 srcElement​ srcElement属性与target属性功能一致注意：Firefox浏览器不支持 1 2 兼容var handler = function(e){ e = e || event; var target = e.target || e.srcElement; }事件代理由于事件会在冒泡阶段向上传播到父节点，因此可以把子节点的监听函数定义在父节点上，由父节点的监听函数统一处理多个子元素的事件。这种方法叫做事件的代理(delegation)，也叫事件委托事件代理应用事件目标的target和srcElement属性完成。利用事件代理，可以提高性能及降低代码复杂度。举个列子：有三个同事预计会在周一收到快递。为签收快递，有两种办法：一是三个人在公司门口等快递；二是委托给前台MM代为签收。现实当中，我们大都采用委托的方案（公司也不会容忍那么多员工站在门口就为了等快递）。前台MM收到快递后，她会判断收件人是谁，然后按照收件人的要求签收，甚至代为付款。这种方案还有一个优势，那就是即使公司里来了新员工（不管多少），前台MM也会在收到寄给新员工的快递后核实并代为签收。 需求：一个ul中有5个li，移入时变蓝，移出时变红下面分别用常规方法和事件代理方法来实现 1 2 3 4 5 需求：给未来添加的元素添加事件 1 2 3 4 5 事件冒泡事件冒泡是事件流的第三个阶段，通过事件冒泡可以在这个阶段对事件做出响应 关于冒泡，事件对象中包含bubbles、cancelBubble、stopPropagation()和stopImmediatePropagation()这四个相关的属性和方法。 bubblesbubbles属性返回一个布尔值，表示当前事件是否会冒泡。该属性为只读属性 发生在文档元素上的大部分事件都会冒泡，但focus、blur和scroll事件不会冒泡。所以，除了这三个事件bubbles属性返回了false外，其它事件该属性都为true 内容 stopPropagation()​ stopPropagation()方法表示取消事件的进一步捕获或冒泡，无返回注意：ie8 浏览器不支持 触发 stopImmediatePropagation()​ stopImmediatePropagation()方法不仅可以取消事件的进一步捕获或冒泡，而且可以阻止同一个事件的其他监听函数被调用，无返回值[注意]IE8-浏览器不支持​ 使用stopIPropagation()方法，可以阻止冒泡，但无法阻止同一事件的其他监听函数被调用 触发 使用stopImmediatePropagation()方法，即可以阻止冒泡，也可以阻止同一事件的其他监听函数被调用 触发 cancelBubble​ canceBubble属性只能用于阻止冒泡，无法阻止捕获阶段。该值可读写，默认值为false。当设置为true是，cancelBubble可以取消事件冒泡[注意]该属性全浏览器支持，但并不是标准写法 触发 兼容var handler = function(e){ e = e || event; if(e.stopPropagation){ e.stopPropagation(); }else{ e.cancelBubble = true; } }事件流阶段eventPhase​ eventPhase属性返回一个整数值，表示事件目前所处的事件流阶段0表示事件没有发生，1表示捕获阶段，2表示目标阶段，3表示冒泡阶段[注意]IE8-浏览器不支持【1】以下代码返回2，表示处于目标阶段 事件流 【2】以下代码返回1，表示处于捕获阶段 事件流 【3】以下代码返回3，表示处于冒泡阶段 事件流 取消默认行为​ 常见的默认行为有点击链接后，浏览器跳转到指定页面；或者按一下空格键，页面向下滚动一段距离​ 关于取消默认行为的属性包括preventDefault()和returnValue使用 1、在DOM0级事件处理程序中取消默认行为，使用returnValue、preventDefault()和return false都有效 2、在DOM2级事件处理程序中取消默认行为，使用return false无效 3、在IE事件处理程序中取消默认行为，使用preventDefault()无效 点击下列锚点时，会自动打开小猿圈首页小猿圈preventDefault()​ preventDefault()方法取消浏览器对当前事件的默认行为，无返回值 注意：IE8浏览器不支持链接 returnValue​ returnValue属性可读写，默认值是true，但将其设置为false就可以取消事件的默认行为，与preventDefault()方法的作用相同注意： firebox和IE9浏览器不支持链接 兼容var handler = function(e){ e = e || event; if(e.preventDefault){ e.preventDefault(); }else{ e.returnValue = false; } }return false​ 除了以上方法外，取消默认事件还可以使用return false链接 事件对象属性​ 在鼠标事件对象提供了丰富的信息坐标位置​ 关于坐标位置，事件对象提供了clientX/Y、pageX/Y、screenX/Y、x/y、offsetX/Y、layerX/Y这6对信息clientX/Y与x/yclientX/Y表示当鼠标事件发生时（不管是onclick，还是omousemove，onmouseover等），鼠标相对于浏览器（这里说的是浏览器的有效区域）x轴的位置和y轴的位置；x/y与clientX/Y相同 screenX/Y​ 当鼠标事件发生时，鼠标相对于显示器屏幕x轴的位置和y轴的距离； pageX/YpageX/Y表示相对于页面的水平和垂直坐标，它与clientX/clientY的区别是随滚动条的位置变化 offsetX与offsetY​ 当鼠标事件发生时，鼠标相对于事件源x轴的位置 offsetY：当鼠标事件发生时，鼠标相对于事件源y轴的位置 作者：前端开发小马哥链接：https://juejin.cn/post/6889217473892057095来源：稀土掘金