事件
事件监听器
添加事件监听器
- vue中v-on指令用于绑定事件监听器
<button v-on:click="say('hi')">Say hi</button>
简化为:
<button @click="say('hi')">Say hi</button>
监听器的回调函数,第一个参数是事件对象event,之后才是传递的参数
2. js原生绑定监听器的方式:
el.addEventListener('click', function (event) {})
或者
el.onclick = function (event) {}
其中addEventListener可以为事件监听器添加多个回调函数,onclick只能添加一个
移除事件监听器
// callback为事件监听器的名称
el.removeEventListener('click', callback,option)
// 或者
el.onclick = null
事件流
事件流:事件在DOM中的传播过程,分为捕获和冒泡两个阶段,默认为冒泡
事件传播
- 捕获阶段:从根元素开始,向目标元素传播,直到目标元素
- 冒泡阶段:从目标元素开始,向根元素传播,直到根元素
捕获模式、冒泡模式的区别
- 捕获模式:在目标元素之前,捕获阶段会先触发捕获阶段,再触发冒泡阶段。绑定事件监听器时,默认是冒泡模式,需要特别设置才能开启捕获模式
// 第三个参数为true开启捕获模式
el.addEventListener('click', function (event) {},true)
<!-- 或者 -->
<button @click.capture=""></button>
- 冒泡模式:在目标元素之后,冒泡阶段会先触发冒泡阶段,再触发捕获阶段
事件委派
- 事件委派:通过给一个父元素绑定事件监听器,来监听其子元素的事件,从而实现事件监听器的解耦
- 不会冒泡的事件:鼠标、键盘、滚轮、focus、blur、load、unload、DOMContentLoaded 、error、scroll、resize等,这些事件在捕获阶段不会触发,只会在冒泡阶段触发
原理
在DOM结构中,当一个元素上的事件被触发时,如果该元素没有处理该事件,事件会向上冒泡到其父元素,直至文档根节点。事件委派就是利用这一特性,在父元素上设置事件监听器,通过判断事件的实际目标(event.target)来决定是否执行相应的处理逻辑
使用场景
- 动态添加的元素:如果页面中有动态添加或删除的元素,直接绑定事件处理程序会变得很麻烦,而使用事件委托可以简化代码并提高性能。
- 大量元素的场景:如果页面上有大量的相似元素,为每个元素单独绑定事件处理程序会导致性能下降,事件委托可以避免这种情况。
- 表格行点击:在表格应用中,当用户点击某一行时,可以通过事件委托来处理这一行为,而不需要为每一行单独绑定事件。
- 列表项点击:在列表中,用户可能需要点击列表项,事件委托可以简化这种场景下的事件处理。
<ul id="list" @click="say">
<li v-for="item in items">{{ item }}</li>
<ul>
事件对象
- 事件对象event,在回调函数中第一个参数就是事件对象,可以通过event.target获取触发事件的元素
event有哪些属性和方法?
- 属性
- target:触发事件的元素,是DOM对象
- currentTarget:当前绑定事件的元素,是DOM对象
- type:触发事件的类型,字符串
- clientX和clientY:鼠标光标的位置(相对于视口)。
- pageX和pageY:鼠标光标的位置(相对于整个文档)。
- event.keyCode 或 event.key:按键事件中的键码或键值。
- 方法
- stopPropagation():阻止事件冒泡
- preventDefault():阻止默认行为
修饰符
事件修饰符
- stop:阻止事件冒泡
- 用于调用事件对象的 event.stopPropagation() 方法。这个方法的作用是阻止事件在 DOM 中继续传播,即阻止事件冒泡到父元素。
- 在处理表单提交、阻止点击事件冒泡导致不必要的页面滚动或其他不期望的行为时特别有用
- prevent:阻止默认行为
- 用于调用事件对象的 event.preventDefault() 方法。这个方法的作用是阻止事件的默认行为。例如,如果你有一个表单的提交按钮,通常它会提交表单到服务器的 URL,但是使用 .prevent 修饰符可以阻止这一默认行为,让你能够自定义处理表单数据的方式
- once:只触发一次
- 用于调用事件对象的 event.once() 方法。这个方法的作用是只触发一次事件处理函数,之后不再触发。这在需要处理一些只执行一次的逻辑时很有用,例如,在组件销毁时清理一些资源
- capture:捕获阶段触发
- 用于调用事件对象的 event.addEventListener(eventName, handler, true) 方法。这个方法的作用是给事件绑定一个捕获阶段触发的事件处理函数,而不是冒泡阶段触发的事件处理函数。
- self:当前元素触发才触发
- 用于调用事件对象的 event.currentTarget === event.target
- passive:不阻止默认行为,但会阻止滚动事件的默认行为
- 用于调用事件对象的 event.addEventListener(eventName, handler, { passive: true }) 方法。这个方法的作用是给事件绑定一个不阻止默认行为,但会阻止滚动事件的默认行为。
- .navtive :使用原生事件监听器
- 用于监听组件根元素的原生事件。这是因为在Vue组件中,事件监听默认是绑定到组件实例上的,而不是直接绑定到组件的根DOM元素上。如果你想要在组件的根元素上监听原生事件,就需要使用.native修饰符。
- .native修饰符只对自定义组件有效,对普通的HTML标签使用.native修饰符是无效的。
- .exact :精确匹配修饰符
- 用于匹配精确的按键组合,如:.enter、.tab、.delete、.esc等。
<!-- 即使 Alt 或 Shift 被一同按下时也会触发 -->
<button v-on:click.ctrl="onClick">A</button>
<!-- 有且只有 Ctrl 被按下的时候才触发 -->
<button v-on:click.ctrl.exact="onCtrlClick">A</button>
<!-- 没有任何系统修饰符被按下的时候才触发 -->
<button v-on:click.exact="onClick">A</button>
按键修饰符
- enter:回车键
- tab:Tab键
- delete:删除键
- esc:Esc键