西安装修行业网站建设,苏州保洁公司有多少家,宁波seo教程,怎样做美瞳网站事件传递 ----冒泡和捕获
DOM事件标准定义了两种事件流#xff0c;这两种事件流分别是捕获和冒泡。
和许多Web技 术一样#xff0c;在它们成为标准之前#xff0c;Netscape和微软各自不同地实现了它们。Netscape选择实现了捕获事件流#xff0c;微软则实现了冒泡事件流。…事件传递 ----冒泡和捕获
DOM事件标准定义了两种事件流这两种事件流分别是捕获和冒泡。
和许多Web技 术一样在它们成为标准之前Netscape和微软各自不同地实现了它们。Netscape选择实现了捕获事件流微软则实现了冒泡事件流。幸运的 是W3C决定组合使用这两种方法,并且大多数新浏览器都遵循这两种事件流方式。
默认情况下事件使用冒泡事件流不使用捕获事件流。然而在Firefox和Safari里你可以显式的指定使用捕获事件流方法是在注册事件时传入useCapture参数将这个参数设为true。 冒泡事件流
在冒泡过程中的任何时候都可以终止事件的冒泡在遵从W3C标准的浏览器里可以通 过调用事件对象上的stopPropagation()方法在Internet Explorer里可以通过设置事件对象的cancelBubble属性为true。如果不停止事件的传播事件将一直通过DOM冒泡直至到达文档根。即从被点击的元素到此元素的祖先元素直至根元素从下到上。 捕获事件流
事件的处理将从DOM层次的根开始而不是从触发事件的目标元素开始事件被从目标元素的所有祖先元素依次往下传递。在这个过程中事件会被从文档 根到事件目标元素之间各个继承派生的元素所捕获如果事件监听器在被注册时设置了useCapture属性为true,那么它们可以被分派给这期间的任何 元素以对事件做出处理否则事件会被接着传递给派生元素路径上的下一元素直至目标元素。事件到达目标元素后它会接着通过DOM节点再进行冒泡。即根元素到被点击的元素从上到下。 事件代理委托
说明事件委托就是事件目标自身不处理事件而是把处理任务委托给其父元素或者祖先元素甚至根元素document。
原理事件委托是利用事件的冒泡原理来实现的 。事件监听器会分析从子元素冒泡上来的事件找到是哪个子元素的事件。
使用原因
绑定事件太多浏览器占用内存变大严重影响性能Ajax出现局部刷新盛行每次加载完都要重新绑定事件部分浏览器移除元素时绑定的事件没有被及时移除导致内存泄漏严重影响性能Ajax中重复绑定导致代码耦合性过大影响后期维护如下demo 01列表在给新增或删除的列表项时绑定或删除相应事件监听的工作枯燥并繁杂而使用事件委托将监听器安装在列表项的父元素上后当子元素的事件冒泡到父ul元素时只需要检查事件对象的target属性捕获真正被点击的节点元素的引用。
!DOCTYPE html
html langen
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0meta http-equivX-UA-Compatible contentieedgetitle测试/title
/head
bodydivul idparent-listli idpost-1Item 1/lili idpost-2Item 2/lili idpost-3Item 3/lili idpost-4Item 4/lili idpost-5Item 5/lili idpost-6Item 6/li/ul/divscript//找到父元素添加监听器。。。document.getElementById(parent-list).addEventListener(click, function (e) {//e.target是被点击的元素//如果被点击的是li元素if(e.target e.target.nodeName LI) { //注意这里的nodeName标签名要用大写e.target.style.colorred; //执行操作console.log(List item, e.target.id, was clicked);}})/script/body
/html demo02 当需要给所有的a标签绑定click事件时使用事件委托而部分a标签又包含图片img、span元素用户希望点击span或img标签也能触发相应的click事件。这时就需要从触发click事件的元素开始逐级向上查找直到找到a标签为止。代码如下
document.addEventListener(click, function(e) {var node e.target;while (node.parentNode.nodeName ! BODY) {if (node.nodeName A) {console.log(a);break;}node node.parentNode;}
}, false);JQuery中的事件委托 jQuery中的事件委托方式比较丰富如下
1、用on方法,代码如下
$(function(){$(#lists).on(click,li,function(event){var target $(event.target);target.css(background-color,red);})
}) 2.用delegate方法代码如下
$(function(){$(#lists).delegate(li,click,function(event){var target $(event.target);target.css(background-color,red);})
}) on()方法和delegate方法对于事件委托的写法很像。并且执行事件委托的时候只有子元素本文中的li会触发事件而代为执行的父元素本文中为ul不会触发事件所以我们不需要盘判断触发事件的元素节点名这一点明显优于原生的JavaScript。 3.用bind()方法代码如下
$(function(){$(#lists).bind(click,li,function(event){var target $(event.target);if(target.prop(nodeName)LI){target.css(background-color,red);}})
})
bind()方法同原生的JavaScript实现方法一样当父元素代子元素执行事件时父元素也会触发事件所以我们需要判断一下触发事件的元素名。此外用bind()方法给元素绑定事件的时候要注意它只能给已经存在DOM元素添加事件不能给未来存在DOM
元素添加添加事件。如果要频繁地添加DOM元素并且给新添加的DOM元素绑定事件的话用live(),delegate(),on()等方法。鉴于jQuery从1.7之后就不推荐live和delegate方法了所以大家还是使用on方法吧。 vue中使用$event
vue中直接套用上述代码会报错无法找到target使用$event 传入到vue组件方法中如下
templatediv classpagedivul idparent-list clickcheckClick($event)li idpost-1Item 1/lili idpost-2Item 2/li/ul/div/div
/templatescriptexport default {name: Login,methods: {checkClick:function(e){if(e.target e.target.nodeName LI) {//执行操作console.log(List item, e.target.id, was clicked)}}}}
/script vue中使用$event 获取当前元素、父子兄弟元素
tempaltebutton click “getEvent($event)”点击/button
/templatescriptexport default {methods:{getEvent(e) {console.log(e)// e.target 是你当前点击的元素// e.currentTarget 是你绑定事件的元素#获得点击元素的前一个元素e.currentTarget.previousElementSibling.innerHTML#获得点击元素的第一个子元素e.currentTarget.firstElementChild# 获得点击元素的下一个元素e.currentTarget.nextElementSibling# 获得点击元素中id为string的元素e.currentTarget.getElementById(string)# 获得点击元素的string属性e.currentTarget.getAttributeNode(string)# 获得点击元素的父级元素e.currentTarget.parentElement# 获得点击元素的前一个元素的第一个子元素的HTML值e.currentTarget.previousElementSibling.firstElementChild.innerHTML},}}
/scriptvue事件处理
如果需要在内联语句处理器中访问原生DOM事件。可以使用特殊变量$event把它传入到methods中的方法中。 在Vue中事件修饰符处理了许多DOM事件的细节让我们不再需要花大量的时间去处理这些烦恼的事情而能有更多的精力专注于程序的逻辑处理。在Vue中事件修饰符主要有
.stop等同于JavaScript中的event.stopPropagation()防止事件冒泡.prevent等同于JavaScript中的event.preventDefault()防止执行预设的行为比如阻止a链默认跳转和form表单提交注意如果事件可取消则取消该事件而不阻止事件的进一步传播.capture与事件冒泡的方向相反事件捕获由外到内.self只当事件在该元素本身而不是子元素触发时触发回调.once只会触发一次!-- 阻止单击事件冒泡 --
a v-on:click.stopdoThis/a!-- 提交事件不再重载页面 --
form v-on:submit.preventonSubmit/form!-- 修饰符可以串联 --
a v-on:click.stop.preventdoThat/a!-- 只有修饰符 --
form v-on:submit.prevent/form!-- 添加事件侦听器时使用事件捕获模式 --
div v-on:click.capturedoThis.../div!-- 只当事件在该元素本身而不是子元素触发时触发回调 --
div v-on:click.selfdoThat.../div .stop 阻止事件冒泡
冒泡事件嵌套两三层父子关系然后所有都有点击事件点击子节点就会触发从内至外 子节点-》父节点的点击事件如下
div classtestPage div classouteer clickouter div classmiddle clickmiddle button clickinner点击我(^_^)/button/div/div p{{ message }}/p
/div
scriptexport default {name: Login,data(){return {message:测试冒泡事件,}},methods: {inner: function () {this.message inner 这是最里面的Button;console.log(this.message);},middle: function () {this.message middle: 这是中间的Div;console.log(this.message);},outer: function () {this.message outer: 这是外面的Div;console.log(this.message);}}}
/script 在点击上加上.stop相当于调用了event.stopPropagation()阻止了事件冒泡传递点击子节点不会捕获到父节点的事件。代码如下
div classtestPage div classouteer clickouter div classmiddle click.stopmiddle button clickinner点击我(^_^)/button/div/div p{{ message }}/p
/div
效果如下 .prevent取消默认事件
说明该方法将通知 Web 浏览器不要执行与事件关联的默认动作如果存在这样的动作。例如如果 type 属性是 submit在事件传播的任意阶段可以调用任意的事件句柄通过调用该方法可以阻止提交表单。注意如果 Event 对象的 cancelable 属性是 fasle那么就没有默认动作或者不能阻止默认动作。无论哪种情况调用该方法都没有作用。
如下可以阻止a超链接标签的默认跳转
a hrefhome click.prevent跳转/a .native 修饰符
.native - 监听组件根元素的原生事件。 主要是给自定义的组件添加原生事件。普通的标签使用.native修饰事件是无效的如下 button click.nativeclickFn测试native的作用/buttonel-button typeprimary click.nativeclickFn组件上使用native的作用/el-button 按键修饰符
在监听键盘事件时我们经常需要监测常见的键值。 Vue 允许为 v-on 在监听键盘事件时添加按键修饰符
!-- 只有在 keyCode 是 13 时调用 vm.submit() --
input v-on:keyup.13submitinput v-on:keyup.entersubmit!-- 缩写语法 --
input keyup.entersubmit 全部的按键别名记住所有的 keyCode 比较困难所以 Vue 为最常用的按键提供了别名
.enter.tab.delete (捕获 “删除” 和 “退格” 键).esc.space.up.down.left.right可以通过全局 config.keyCodes 对象自定义按键修饰符
// 可以使用 v-on:keyup.f1
Vue.config.keyCodes.f1 112