자바스크립트 이벤트 바인딩 학습포인트_기본지식
이벤트 바인딩은 두 가지 유형으로 구분됩니다. 하나는 전통적인 이벤트 바인딩(인라인 모델, 스크립트 모델)이고 다른 하나는 최신 이벤트 바인딩(DOM2 수준 모델)입니다. 최신 이벤트 바인딩은 기존 바인딩보다 더 강력하고 편리한 기능을 제공합니다.
1 기존 이벤트 바인딩의 문제점
기존 이벤트 바인딩의 인라인 모델은 논의되지 않으며 거의 사용되지 않습니다. 먼저 스크립트 모델을 살펴보겠습니다. 스크립트 모델은 이벤트 처리 기능에 기능을 할당합니다. 다음과 같은 전통적인 바인딩:
window.onload=function(){ var box=document.getElementById('box'); box.onclick = function(){ alert('Lee'); }; };
문제 1: 이벤트 처리 함수가 두 개의 이벤트를 트리거합니다
페이지에 두 개 이상의 j가 있고 첫 번째 js는 첫 번째 프로그래머가 개발한 경우 두 번째 js는 두 번째 프로그래머가 개발합니다.
과 같이 첫 번째 window.onload를 덮어씁니다.window.onload=function(){ alert('Lee'); }; window.onload=function(){ alert('Mr.lee'); }
이씨님 결과가 방금 출력되었습니다
실제로 이 문제를 해결하는 방법이 있습니다. 다음 두 가지 형태를 살펴보세요.
A:
alert(window.onload);//一开始没有注册window.onload,那么就是null window.onload=function(){ alert('Lee'); }; alert(window.onload);//如果已经有window.onload,打印的是函数function window.onload=function(){ alert('Mr.lee'); }
ㄴ:
alert(typeof window.onload);//一开始没有window.onolad,旧版火狐显示undefined,新版显示object, window.onload=function(){ alert('Lee'); }; alert(typeof window.onload);//如果已经有window.onload,所有浏览器都会显示function window.onload=function(){ alert('Mr.lee'); }
그래서 해결책이 있습니다.
window.onload=function(){ alert('Lee'); }; if(typeof window.onload=='function'){ var saved=null;//保存上一个事件对象 saved=window.onload; } //saved 就是window.onload,saved()相当于window.onload(),但是window.onload()不能执行的 //所以saved()相当于window.onload=function(){} window.onload=function(){ if(saved){ saved();//执行上一个事件 window.onload=function(){} } alert('Mr.lee'); //执行本事件 }
질문 2: 이벤트 전환기
상자의 ID로 div를 전환하고 내부의 빨간색과 파란색 배경을 직접 전환한 다음 전환하기 전에 다음과 같이 상자를 한 번 팝업합니다.
window.onload=function(){ var box=document.getElementById('box'); box.className="red"; box.onclick=function(){ alert('Lee'); //只执行了一次 blue.call(this);//通过匿名函数执行某一函数,那么里面的this就是代表的window,所以可以通过call传递 }; } function blue(){ this.className="blue"; this.onclick=red; } function red(){ this.className="red"; this.onclick=blue; }
위 코드에서는 전환 기능을 구현했지만 팝업 상자는 한 번만 실행됩니다.
//添加事件函数 //obj相当于window //type相当于onload //fn相当于function(){} function addEvent(obj,type,fn){ //用于保存上一个事件 var saved=null; if(typeof obj['on'+type]=='function'){ saved=obj['on'+type];//保存上一个事件 } obj['on'+type]=function(){ if(saved){ saved(); } fn.call(this); } } addEvent(window,'load',function(){ var box=document.getElementById("box"); //addEvent(box,'click',function(){ //目的达到,每次都执行了,没有被覆盖 // alert('ss'); //}); addEvent(box,'click',blue); }); function red(){ this.className="red"; addEvent(box,'click',blue); } function blue(){ this.className="blue"; addEvent(box,'click',red); } //当不停的切换的时候,浏览器突然卡死,并且报错:too much recursion,太多的递归 //因为积累了太多的保存的事件 //解决方案,就是用完的事件,就立刻移除掉
위 코드에 따르면 댓글에 오류가 발생했습니다. 해결 방법은 다음과 같습니다.
//添加事件函数 //obj相当于window //type相当于onload //fn相当于function(){} function addEvent(obj,type,fn){ //用于保存上一个事件 var saved=null; if(typeof obj['on'+type]=='function'){ saved=obj['on'+type];//保存上一个事件 } obj['on'+type]=function(){ if(saved){ saved(); } fn.call(this); } } //当不停的切换的时候,浏览器突然卡死,并且报错:too much recursion,太多的递归 //因为积累了太多的保存的事件 //解决方案,就是用完的事件,就立刻移除掉 //移除事件函数 function removeEvent(obj,type){ if(obj['on'+type]){ obj['on'+type]=null; } } addEvent(window,'load',function(){ var box=document.getElementById("box"); //addEvent(box,'click',function(){ //目的达到,每次都执行了,没有被覆盖 // alert('ss'); //}); addEvent(box,'click',blue); }); function red(){ this.className="red"; removeEvent(this,'click'); addEvent(box,'click',blue); } function blue(){ this.className="blue"; removeEvent(this,'click'); addEvent(box,'click',red); }
두 가지 W3C 이벤트 처리 기능
addEventListener() 및 제거EventListener()
두 가지 W3C 이벤트 처리 함수인 addEventListener()와 RemoveEventListener()가 있습니다.
//W3C에는 추가 이벤트와 삭제 이벤트 두 가지가 있습니다
1. 커버리지 문제 해결
window.addEventListener('load',function(){ alert('Lee'); },false); window.addEventListener('load',function(){ alert('Mr.Lee'); },false); window.addEventListener('load',function(){ alert('Mrs.Lee'); },false);
2. 동일한 기능을 차단하는 문제가 해결되었습니다
window.addEventListener('load',init,false); window.addEventListener('load',init,false); window.addEventListener('load',init,false); function init(){ alert('Lee'); }
3. 이걸 통과해서 해결이 가능할까요
예시 1:
window.addEventListener('load',function(){ var box=document.getElementById('box'); box.addEventListener('click',function(){ alert(this); },false); },false);
예 2:
window.addEventListener('load',function(){ var box=document.getElementById('box'); box.addEventListener('click',blue,false); },false); function red(){ this.className="red"; this.removeEventListener('click',red,false); this.addEventListener('click',blue,false); } function blue(){ this.className="blue"; this.removeEventListener('click',blue,false); this.addEventListener('click',red,false); }
4. 추가 메소드를 덮어쓰나요, 아니면 한 번만 실행할 수 있나요?
window.addEventListener('load',function(){ var box=document.getElementById('box'); box.addEventListener('click',function(){ alert('Lee'); },false); box.addEventListener('click',blue,false); },false);
요약하자면 W3C는 이러한 문제를 완벽하게 해결했으며 사용하기 매우 쉽습니다. 그러나 IE8 및 이전 브라우저에서는 이를 지원하지 않습니다. 대신 IE9에서는 이를 완벽하게 지원합니다. 두 가지 이벤트 처리 기능.
W3C에서는 버블링 및 캡처 방법을 설정할 수 있습니다.
W3C 표준을 지원하는 브라우저는 이벤트 추가 시 addEventListener(event,fn,useCapture) 메소드를 사용합니다. 베이스의 세 번째 매개변수인 useCapture는 부울 값으로, 이벤트 캡처 중에 이벤트를 실행할지 여부를 설정하는 데 사용됩니다. 이벤트가 발생하면 담그면 실행됩니다. W3C(IE)와 호환되지 않는 브라우저에서는 AttachEvent() 메서드를 사용합니다. 그러나 IE의 이벤트 모델은 기본적으로 이벤트가 발생할 때, 즉 useCapture가 false일 때 실행됩니다. 이벤트 처리 시 useCapture를 false로 설정하는 것이 더 안전하고, 브라우저 호환성도 확보됩니다.
이벤트 캡처 단계: 이벤트는 최상위 레이블부터 시작하여 이벤트 대상(target)이 캡처될 때까지 아래쪽으로 검색합니다.
이벤트 버블링 단계: 이벤트는 이벤트 대상(target)에서 시작하여 페이지의 최상위 레이블까지 버블링됩니다.
이벤트 확산을 막을 수 있습니다:
W3c에서는 stopPropagation() 메소드를 사용하세요
IE에서는 cancelBubble = true로 설정합니다.
3. IE 이벤트 처리 기능
attachEvent() 및 detachEvent()
IE는 DOM의 메소드와 유사한 두 가지 메소드(attachEvent() 및 detachEvent())를 구현합니다. 두 방법 모두 동일한 매개변수(이벤트 이름 및 기능)를 허용합니다.
이 두 가지 기능 세트를 사용할 때 먼저 차이점에 대해 이야기해 보겠습니다. 1. IE는 캡처를 지원하지 않고 버블링만 지원합니다. 2. IE 추가 이벤트는 중복 기능을 차단할 수 없습니다. 3. IE에서는 이 기능이 대신 창을 가리킵니다. DOM 객체. 4. 기존 이벤트에서 IE는 이벤트 객체를 받아들일 수 없지만 attchEvent를 사용하면 가능하지만 몇 가지 차이점이 있습니다.
1. 취재 문제는 해결됐지만 결과는 이씨, 이씨, 그리고 결국 이씨다
window.attachEvent('onload',function(){ alert('Lee'); }); window.attachEvent('onload',function(){ alert('Mr.Lee'); }); window.attachEvent('onload',function(){ alert('Mrs.Lee'); });
2. 동일 기능을 차단하는 문제가 해결되지 않았습니다.
window.attachEvent('onload',init); window.attachEvent('onload',init); function init(){ alert('Lee'); }
3. 이것이 통과될 수 있습니까? 아니요. 창을 의미합니다. 호출 방식을 사용해야 합니다.
window.attachEvent('onload',function(){ var box=document.getElementById('box'); box.attachEvent('onclick',function(){ //alert(this===box); alert(this===window); //true }); });
다음 방법은 window.event.srcElement를 전달하는 것입니다. 코드는 다음과 같습니다.
window.attachEvent('onload',function(){ var box=document.getElementById('box'); box.attachEvent('onclick',blue); }); function red(){ var that=window.event.srcElement; that.className="red"; that.detachEvent('onclick',red); that.attachEvent('onclick',blue); } function blue(){ var that=window.event.srcElement; that.className="blue"; that.detachEvent('onclick',blue); that.attachEvent('onclick',red); }
4. 추가 메소드를 추가하면 덮어쓰이나요, 아니면 한 번만 실행할 수 있나요?
기존 바인딩에서 IE는 W3C처럼 매개변수 전달을 통해 이벤트 객체를 받아들일 수 없지만, attachmentEvent()를 사용하면 가능합니다.
window.attachEvent('onload',function(){ var box=document.getElementById('box'); box.onclick=function(evt){ //传统方法IE无法通过参数获取evt alert(evt);//undefined } box.attachEvent('onclick',function(evt){ alert(evt);//object alert(evt.type);//click alert(evt.srcElement.tagName);//DIV alert(window.event.srcElement.tagName);//DIV }); });
크로스 브라우저 호환성
크로스 브라우저 이벤트
function addEvent(obj,type,fn){ if(obj.addEventListener){ obj.addEventListener(type,fn,false); }else if(obj.attachEvent){ obj.attachEvent('on'+type,fn); } }
크로스 브라우저 제거 이벤트
function removeEvent(obj,type,fn){ if(obj.removeEventListener){ obj.removeEventListener(type,fn,false); }else if(obj.detachEvent){ obj.detachEvent('on'+type,fn); } }
여러 브라우저에서 대상 개체 가져오기
function getTarget(evt){ if(evt.target){ return evt.target; }else if(window.event.srcElement){ return window.event.srcElement; } }
调用方式:
addEvent(window,'load',function(){ var box=document.getElementById('box'); addEvent(box,'click',blue); }); function red(evt){ var that=getTarget(evt); that.className="red"; removeEvent(that,'click',red); addEvent(that,'click',blue); } function blue(evt){ var that=getTarget(evt); that.className="blue"; removeEvent(that,'click',blue); addEvent(that,'click',red); }
四.事件对象的其他补充
relatedTarget事件
w3c中的一个relatedTarget事件。
例如:
addEvent(window,'load',function(){ var box=document.getElementById('box'); addEvent(box,'mouseover',function(evt){ alert(evt.relatedTarget); //得到移入box最近的那个DOM对象 }); addEvent(box,'mouseout',function(evt){ alert(evt.relatedTarget); //从box移出最近的那个DOM对象 }); });
IE提供了两组分别用于移入移出的属性fromElement和toElement,分别对应mouseover和mouseout。
addEvent(window,'load',function(){ var box=document.getElementById('box'); addEvent(box,'mouseover',function(){ alert(window.event.fromElement.tagName); //得到移入box最近的那个DOM对象 }); addEvent(box,'mouseout',function(){ alert(window.event.toElement.tagName); //从box移出最近的那个DOM对象 }); });
PS:fromElement和toElement如果分别对应相反的鼠标事件,没有任何意义。
剩下要做的就是跨浏览器兼容操作:
function getTarget(evt){ var e=evt || window.event; if(e.srcElment){ //IE if(e.type=='mouseover'){ return e.fromElement.tagName; }else if(e.type="mouseout"){ return e.toElement.tagName; } }else if(e.relatedTarget){ //w3c return e.relatedTarget; } }
屏蔽跳转操作
取消事件的默认行为有一种不规范的做法,就是返回false。
link.onclick=function(){ alert('Lee'); return false; }
PS:虽然return false;可以实现这个功能,但是有漏洞。
第一:必须写到最后,这样导致中奖的代码执行后,有可能执行不到return false;
第二:return false 写到最前那么之后的自定义操作就失效了。
所以最好的办法应该是在最前面就阻止默认行为,并且后面的代码还可以执行。
link.onclick=function(evt){ evt.preventDefault;//w3c,阻止默认行为 alert('Lee'); } link.onclick=function(evt){ window.event.returnValue=false;//IE,阻止默认行为 alert('Lee'); }
那么跨浏览器的兼容:
function preDef(evt){ var e=evt || window.event; if(e.preventDefault){ e.preventDefault(); }else{ e.returnValue=false; } }
右键菜单contextmenu
兼容:
function preDef(evt){ var e=evt || window.event; if(e.preventDefault){ e.preventDefault(); }else{ e.returnValue=false; } } addEvent(window,"load",function(){ var body=document.getElementsByTagName('body')[0]; addEvent(body,'contextmenu',function(evt){ preDef(evt); }) });
PS:contextmenu事件很常用,这直接导致浏览器兼容性较为稳定。
卸载前事件:beforeunload
这个事件可以帮助在离开本页的时候给出相应的提示,“离开”或者“返回”操作。
addEvent(window,'beforeonload',function(){ preDef(evt); });
鼠标滚轮(mousewheel)和DOMMouseScroll
用于获取鼠标上下滚轮的距离
addEvent(document,'mousewheel',function(evt){ //非火狐 alert(getWD(evt)); }); addEvent(document,'DOMMouseScroll',function(evt){ //火狐 alert(getWD(evt)); }); function getWD(evt){ var e=evt|| window.event; if(e.wheelDelta){ return e.wheelDelta; }else if(e.detail){ //火狐 return -evt.detail*30; } }
PS:通过浏览器检测可以确定火狐只执行DOMMouseScroll。
DOMContentLoaded事件和readystatechange事件
DOMContentLoaded事件和readystatechange事件,有关DOM加载方面的事件。

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











기사는 JavaScript 라이브러리 작성, 게시 및 유지 관리, 계획, 개발, 테스트, 문서 및 홍보 전략에 중점을 둡니다.

이 기사는 브라우저에서 JavaScript 성능을 최적화하기위한 전략에 대해 설명하고 실행 시간을 줄이고 페이지로드 속도에 미치는 영향을 최소화하는 데 중점을 둡니다.

프론트 엔드 개발시 프론트 엔드 열지대 티켓 인쇄를위한 자주 묻는 질문과 솔루션, 티켓 인쇄는 일반적인 요구 사항입니다. 그러나 많은 개발자들이 구현하고 있습니다 ...

이 기사는 브라우저 개발자 도구를 사용하여 효과적인 JavaScript 디버깅, 중단 점 설정, 콘솔 사용 및 성능 분석에 중점을 둡니다.

기술 및 산업 요구에 따라 Python 및 JavaScript 개발자에 대한 절대 급여는 없습니다. 1. 파이썬은 데이터 과학 및 기계 학습에서 더 많은 비용을 지불 할 수 있습니다. 2. JavaScript는 프론트 엔드 및 풀 스택 개발에 큰 수요가 있으며 급여도 상당합니다. 3. 영향 요인에는 경험, 지리적 위치, 회사 규모 및 특정 기술이 포함됩니다.

이 기사는 소스 맵을 사용하여 원래 코드에 다시 매핑하여 미니어링 된 JavaScript를 디버그하는 방법을 설명합니다. 소스 맵 활성화, 브레이크 포인트 설정 및 Chrome Devtools 및 Webpack과 같은 도구 사용에 대해 설명합니다.

Console.log 출력의 차이의 근본 원인에 대한 심층적 인 논의. 이 기사에서는 Console.log 함수의 출력 결과의 차이점을 코드에서 분석하고 그에 따른 이유를 설명합니다. � ...

엔트리 레벨 타입 스크립트 자습서를 마스터 한 후에는 TypeScript를 지원하고 JavaScript로 컴파일하는 IDE에서 자신의 코드를 작성할 수 있어야합니다. 이 튜토리얼은 TypeScript의 다양한 데이터 유형으로 뛰어납니다. JavaScript에는 NULL, UNDEFINED, BOOLEAN, 번호, 문자열, 기호 (ES6에 의해 소개 됨) 및 객체의 7 가지 데이터 유형이 있습니다. TypeScript는이 기반으로 더 많은 유형을 정의 하며이 튜토리얼은이 모든 튜토리얼을 자세히 다룹니다. 널 데이터 유형 JavaScript와 마찬가지로 Null in TypeScript
