이벤트 스트림이란 무엇인가요? 이 글은 모든 사람에게 도움이 되기를 바라며 주로 js 이벤트 흐름과 확장된 애플리케이션 예제를 공유합니다.
DOM 표준에서는 이벤트 흐름에 이벤트 캡처 단계, 대상 단계, 이벤트 버블링 단계의 세 단계가 포함된다고 규정합니다.
● 이벤트 캡처 단계: 실제 대상(<p></p>
)은 캡처 단계 동안 이벤트를 수신하지 않습니다. 즉, 캡처 단계 동안 이벤트는 문서에서 ,
로 중지됩니다. 위 사진에서는 1~3 입니다.
● 대상 단계:
<p></p>
에서 이벤트가 발생하고 처리됩니다. 그러나 이벤트 처리는 버블링 단계의 일부로 간주됩니다. <p></p>
)在捕获阶段不会接收事件。也就是在捕获阶段,事件从document到再到
就停止了。上图中为1~3.
● 处于目标阶段:事件在<p></p>
上发生并处理。但是事件处理会被看成是冒泡阶段的一部分。
● 冒泡阶段:事件又传播回文档。
note:
1)、尽管“DOM2级事件”标准规范明确规定事件捕获阶段不会涉及事件目标,但是在IE9、Safari、Chrome、Firefox和Opera9.5及更高版本都会在捕获阶段触发事件对象上的事件。结果,就是有两次机会在目标对象上面操作事件。
2)、并非所有的事件都会经过冒泡阶段 。所有的事件都要经过捕获阶段和处于目标阶段,但是有些事件会跳过冒泡阶段:如,获得输入焦点的focus事件和失去输入焦点的blur事件。
捕获型事件流:事件的传播是从最不特定的事件目标到最特定的事件目标。即从DOM树的根到叶子。
冒泡型事件流:事件的传播是从最特定的事件目标到最不特定的事件目标。即从DOM树的叶子到根。
那么这里要实现的就是冒泡型事件流,从里面(叶子)到外面(根)
//只需要在window.onload里面给每一个圆添加点击事件处理程序就ok了哦,其余代码请看上[一篇文章](https://blog.csdn.net/weixin_38323736/article/details/79685589)当然是在圆画好之后执行这一段代码,所以位置放在后面,别放错var circles=document.getElementsByClassName("circle"); for(var i=0;i<n;i++){ circles[i].onclick=function(e){ //currentTarget表示当前处理该事件的元素、文档或窗口,childNodes是子节点的意思,这里遍历子节点 e.currentTarget.childNodes.forEach(function(v) { //把文本节点找出,不然html代码也会输出的 if(v instanceof Text) { //文字节点为Text()实例,用data或者wholeText可以取到String类型的文本 //解决方法参照:https://segmentfault.com/q/1010000009913772/a-1020000009914008 console.log(v.data); // console.log(v.wholeText); } }); } }
ok啦,就是这么简单。
好学的同学肯定想看看事件捕获了,干脆我把两种都写出来吧,让大家看看整个事件流是怎么样的
circles[i].onclick=function(e){}
这种写法是dom0级的写法,只能写一个事件,再写一个会覆盖,而且只支持冒泡事件 addEventListener
● 버블링 단계: 이벤트가 문서로 다시 전파됩니다.
1) "DOM2 수준 이벤트" 표준 사양에서는 이벤트 캡처 단계에 이벤트 대상이 포함되지 않는다고 명확하게 규정하고 있지만 IE9, Safari, Chrome, Firefox 및 Opera9.5에서는 이벤트 개체가 캡처 단계에서 트리거됩니다. 이상의 이벤트가 있습니다. 결과적으로 대상 객체에 대한 이벤트를 조작할 수 있는 기회는
두 가지입니다.
버블링 이벤트 흐름: 이벤트 전파는 가장 구체적인 이벤트 대상에서 가장 덜 구체적인 이벤트 대상으로 진행됩니다. 즉, DOM 트리의 잎부터 루트까지입니다. 그럼 여기서 구현하고 싶은 것은 내부(리프)에서 외부(루트)로의 버블링 이벤트 흐름입니다//这段代码包含了上面的js代码哦var circles=document.getElementsByClassName("circle");for(var i=0;i<n;i++){
circles[i].addEventListener("click",function(e){
e.currentTarget.childNodes.forEach(function(v) {
if(v instanceof Text) {
console.log(v.data+" 捕获阶段");
}
}); //true表示事件句柄在捕获阶段执行;
//false- 默认。事件句柄在冒泡阶段执行
},true);
circles[i].addEventListener("click",function(e){
e.currentTarget.childNodes.forEach(function(v) {
if(v instanceof Text) {
console.log(v.data+" 冒泡阶段");
}
});
},false);
}
circles[i].onclick=function(e){ }
이 작성 방법은 하나의 이벤트만 작성할 수 있으며, 다른 이벤트를 작성하면 이를 덮어쓰게 되며, addEventListener
는 여러 개 작성할 수 있습니다. 이벤트는 적용되지 않습니다var circles=document.getElementsByClassName("circle");for(var i=0;i<n;i++){ circles[i].addEventListener("click",function(e){ e.currentTarget.childNodes.forEach(function(v) { if(v instanceof Text) { console.log(v.data); } }); //阻止冒泡哦!!!不然不止输出15了 e.stopPropagation(); },false); }
사실 이벤트 버블링에는 좋은 응용 프로그램이 있습니다. 바로 이벤트 프록시
이벤트 프록시
입니다. ,이벤트 위임
<p></p>기존 이벤트 처리에서는 각 요소에 이벤트 핸들러를 추가해야 합니다. Node.js 이벤트 프록시는 상위 요소에 이벤트 핸들러를 추가하여 여러 하위 요소에 이벤트 핸들러를 추가하지 않아도 되는 간단하고 효과적인 기술입니다. <p></p>이벤트 프록시의 원리는 이벤트 버블링과 대상 요소를 사용합니다. 상위 요소에 이벤트 핸들러를 추가하고 하위 요소 이벤트가 버블링될 때까지 기다리면 상위 요소는 대상을 통해 어떤 하위 요소인지 결정할 수 있습니다. srcElement) 따라서 적절하게 처리하세요.● 여러 이벤트 핸들러를 하나로 줄입니다. 이벤트 핸들러는 메모리에 상주해야 하므로 성능이 향상됩니다. 100개의 행이 있는 테이블이 있다고 상상해 보십시오. 이벤트 프록시를 사용하여 각 셀에 이벤트 핸들러를 바인딩하는(즉, 테이블에 이벤트 핸들러를 추가하는) 전통적인 방법을 비교하면 이벤트 프록시가 이를 방지한다는 결론을 내리는 것은 어렵지 않습니다. 잠재적인 위험이 있고 성능이 향상되었습니다. ● 이벤트 프록시는 다양한 하위 요소에 대해 다양한 처리 방법을 사용할 수 있으므로 DOM 업데이트에는 리바인딩 이벤트 핸들러가 필요하지 않습니다. 다른 하위 요소(a,span,p 등)를 추가하면 이벤트 프록시의 이벤트 처리 기능을 직접 수정할 수 있습니다. 프로세서를 다시 바인딩하거나 다시 루프할 필요가 없습니다.
예를 들어 이제 15의 원을 클릭하면 15를 출력하려고 합니다. 먼저 전통적인 루프 방법을 사용하여 작성한 다음 이벤트 위임 방법을 사용하여 작성합니다//获取外面的大圆,只需要交给大圆来处理就okvar circle=document.getElementById("circle"); circle.addEventListener("click",function(e){ e=e||window.event; var targetElement=e.target||e.srcElement; targetElement.childNodes.forEach(function(v) { if(v instanceof Text) { console.log(v.data); } }); })
var circle=document.getElementById("circle"); circle.addEventListener("click",function(e){ e=e||window.event; var targetElement=e.target||e.srcElement; while(targetElement.nodeName!="BODY"){ targetElement.childNodes.forEach(function(v) { if(v instanceof Text) { console.log(v.data); } }); targetElement=targetElement.parentNode; } },false)
위 내용은 Node.js 이벤트 스트림 및 확장 애플리케이션 예제의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!