프론트 엔드 개발 과정에서 우리는 종종 페이지 요소에 이벤트를 추가하는 문제가 발생합니다. 페이지 구조에 직접 추가 된 이벤트 및 일부 JS 이벤트 모니터링 방법을 포함하여 이벤트를 추가 할 수있는 많은 JS 방법이 있습니다. 각 브라우저에는 이벤트 버블 이벤트 모니터링을위한 다양한 메커니즘이 있으므로 LE 브라우저에는 이벤트 버블 만 있으며 이벤트 모니터링 메커니즘이 없으며 이벤트 청취의 호환성 문제가 가장 큰 문제입니다.
1. 페이지 구조에 직접 이벤트 메소드를 작성하십시오.
함수 eventFun () {//console.log(this); } <input type = "button"onclick = "eventFun ()"value = "button"/> // 이것은이 범위의 문제가 필요합니다. EventFun도 여기에서 글로벌 기능입니다. 객체는 [객체 창]이며, 이것은 창을 가리 킵니다.이 범위 문제를 해결하려면 이벤트 변수를 글로벌 함수에 추가하는 방법을 사용 하고이 객체를 페이지 구조 내의 함수로 매개 변수로 전달할 수 있습니다.
<입력 유형 = "button"onclick = "eventFun2 (this)"value = "button2"/> function eventFun2 (eve) {// 여기에서 이벤트 객체는 전역 메서드 eve.name = "Alex"로 매개 변수로 전달됩니다. Window.name = "Robin"; Console.log (this); // [Object Window] Console.log (Eve); // [Object HtmlinputElement] console.log (this.name); // robin console.log (eve.name); // alexvar self = eve; Console.log (this.name); // Robin Console.log (self.name); // Alex Alert (Window.name); 경고 (self.name); }2. 이벤트 속성에 값을 할당하는 방법을 사용하는 것은 이벤트에 바인딩하는 방법이지만,이 방법의 한계는 하나의 방법 만 이벤트에만 바인딩 할 수 있다는 것입니다. 다중 바인딩이 결합되면 하나의 방법이 우세합니다.
htmlelementobject.onclick = fucntion () {//이 메소드를 사용하여 이벤트 속성에 값을 할당하면이 포인터는 이벤트 객체가 아닌 창 객체를 가리 므로이 메소드는 참조입니다.
// js code fun1 (); fun2 (); fun3 (); console.log (this); // winde
3. 이벤트 전파 - 버블 및 캡처
DOM 이벤트 표준은 두 개의 이벤트 스트림을 정의합니다.이 스트림은 크게 다르고 응용 프로그램에 상당한 영향을 줄 수 있습니다. 이 두 이벤트 스트림은 캡처와 버블입니다. 많은 웹 기술과 마찬가지로 Netscape 및 Microsoft는 표준이되기 전에 다르게 구현했습니다. Netscape는 캡처 이벤트 스트림을 구현하기로 결정한 반면 Microsoft는 버블 이벤트 스트림을 구현했습니다. 다행히 W3C는 두 가지 방법을 모두 조합하여 사용하기로 결정했으며 대부분의 새로운 브라우저는이 두 이벤트 스트리밍 방법을 따릅니다.
기본적으로 이벤트는 버블 이벤트 스트림을 사용하며 캡처 이벤트 스트림이 사용되지 않습니다. 그러나 Firefox 및 Safari에서는 이벤트를 등록 할 때 usecapture 매개 변수를 전달 하고이 매개 변수를 true로 설정하여 캡처 이벤트 스트림 사용을 명시 적으로 지정할 수 있습니다.
버블 이벤트 스트림
예를 들어, DOM 요소에서 이벤트가 트리거되면 사용자는 클라이언트 이름 노드에서 마우스를 클릭하면 이벤트가 이벤트 유형 프로세서에 첨부 된 노드가 발생할 때까지 전체 DOM 노드 계층 구조를 통해 노드가 기포되는 다양한 상위 노드를 따릅니다. 현재 이벤트는 Onclick 이벤트입니다. 버블 링 과정에서 언제든지 사건의 버블 링을 종료 할 수 있습니다. W3C 표준을 준수하는 브라우저에서는 이벤트 객체에서 stopPropagation () 메소드를 호출 할 수 있으며 Internet Explorer에서는 이벤트 객체의 CANCLEBBLE 속성을 True로 설정할 수 있습니다. 이벤트가 중지되지 않으면 이벤트는 문서 루트에 도달 할 때까지 DOM을 통해 기포됩니다.
이벤트 흐름을 캡처하십시오
이벤트 처리는 이벤트를 트리거하는 대상 요소가 아닌 DOM 레벨의 근본에서 시작되며 이벤트는 대상 요소의 모든 조상 요소로부터 순서대로 전달됩니다. 이 과정에서 이벤트는 문서 루트에서 이벤트 대상 요소까지 다양한 상속 된 파생 요소로 캡처됩니다. 이벤트 리스너가 등록 할 때 usecapture 속성을 True로 설정하면이 기간 동안 모든 요소에 할당하여 이벤트를 처리 할 수 있습니다. 그렇지 않으면, 이벤트는 이후에 타겟 요소까지 파생 요소 경로의 다음 요소로 전달됩니다. 이벤트가 대상 요소에 도달하면 DOM 노드를 통해 기포됩니다.
현대 이벤트 바인딩 방법
이전 수업의 경우 전통적인 이벤트 바인딩을 사용하면 동일한 객체의 이벤트에 여러 이벤트 핸들러를 등록 할 수없는 것과 같은 많은 단점이 있습니다. 그리고 브라우저와 W3C는 이것을 고려하지 않기 때문에 현대식 브라우저에서는 이벤트를 바인딩하는 자체 방법이 있습니다.
W3C Dom
obj.addeventListener (Evtype, FN, UseCapture) -W3C는 이벤트 처리 기능을 추가하는 방법을 제공합니다. OBJ는 이벤트를 추가하는 객체이며, EvType는 이벤트 유형이며, 접두사가 없으면 FN이 이벤트 핸들러 기능입니다. usecapture가 사실이면 캡처 스테이지에서 이벤트 핸들러 기능이 실행됩니다. 그렇지 않으면 버블 단계에서 실행됩니다.
obj.removeeventListener (EvType, FN, UseCapture) -W3C는 이벤트 처리 기능을 삭제하기위한 방법을 제공합니다
Microsoft IE 방법
OBJ.ATTACHEVENT (EVTYPE, FN) - IE가 이벤트 처리 기능을 추가하기 위해 제공 한 방법입니다. OBJ는 이벤트를 추가하는 객체이며, EvType은 이벤트 유형이며, Prefix에 FN이 이벤트 처리기 기능을 사용하고 IE는 이벤트 캡처를 지원하지 않습니다.
obj.detachevent (Evtype, FN,) - IE는 이벤트 처리 기능을 삭제하는 메소드를 제공합니다.
둘 다 통합하는 방법
function addevent (obj, evtype, fn, usecapture) {if (obj.addeventListener) {obj.adeventListener (evtype, fn, usecapture); } else {obj.attachevent ( "on"+evtype, fn); // 즉, 이벤트 캡처를 지원하지 않습니다} else {obj [ "on"+evtype] = fn; // 실제로이 상황이 존재하지 않습니다}} function delevent (obj, evtype, fn, usecapture) {if (obj.removevevere) obj.removeeventListener (Evtype, FN, UseCapture); } else {obj.detachevent ( "on"+evtype, fn); } else {obj [ "on"+evtype] = null; }}IE 첨부 방법에 문제가 있습니다. 첨부 장치를 사용할 때 첨부이면 OBJ가 아닌 창을 가리 킵니다! 물론, 이것에 대한 해결책이 있습니다!
그러나 IE의 첨부 파일 벤트 방법에는 또 다른 문제가 있습니다. 동일한 기능을 동일한 객체와 동일한 이벤트에 여러 번 등록 할 수 있습니다. 솔루션 : IE의 첨부 파일 벤트 방법을 포기하십시오! IE에 따른 첨부 배치 방법은 기존 이벤트 등록과 크게 다르지 않으며 (다중 이벤트 핸들러 제외) 캡처를 지원하지 않으며 IE의 첨부 파일 이벤트 방법에는 메모리 누출 문제가 있습니다!
addevent, delevent 최신 버전
<! doctype html public "-// w3c // dtd xhtml 1.0 Transitional // en" "http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd"> <html xmlns = "http://www.w3.org/1999/xhtml"> <head> <meta http-equiv = "content-type"content = "text/html; charset = utf-8"/> <title> js 이벤트 청취 </title> <style> table td {font; Border-Bottom : 1px solid #efefefef;} < /style> < /head> <body> <div id = "outele"style = "padding : 10px; 테두리; 1px solid #b2b2b2; 배경 : #efefefefef;"> <input type = "button"onclick = "event ="id = "valling ="button " />>>>>>>>> <input type =. onclick = "EventFun2 (this);" id = "button2"value = "button2" /> <br /> <입력 유형 = "button"id = "button3"value = "button3" /> <br /> <입력 유형 = "button"id = "button4"value = "button4" /> <br /> <table id = "htmleletable"style = "테두리 : 1px solid # #"> ">"> ">"> <tr b2b2b2; id = "1111"> <td> 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 미포까지는 </td> </tr> <tr id = "22222"> <td> 2222222222222222222222222222222 </td> id = "33333333333333333333333333333333 </td> </tr> <tr id = "44444"> <td> 4444444444444444444444444444444444444444444444444444444444444444444444444444444 44444444444444444444444444444444444444444444444444444444444444444444444444444444444444 </td> </tr> <tr id = "555555555555555555555555555555 </td> </tr> </table> </div> <script language ="javaScript "type ="text/javaScript "> functionfun () {// 1. Page Structure Console.log (this)에 JS 메소드를 직접 작성하십시오. // 이것은이 범위에 문제가 있습니다. EventFun은 글로벌 함수이며 객체는 창이며 창은 창 경고 (this)를 가리 킵니다. } function eventFun2 (eve) {// 여기에서 이벤트 객체를 전역 메서드 eve.name = "alex"; // window.name = "robin"으로 전달합니다. Console.log (this); // [Object Window] Console.log (Eve); // [Object HtmlinputElement] console.log (this.name); // robin console.log (eve.name); // Alex var self = eve; Console.log (this.name); // Robin Console.log (self.name); // Alex Alert (Window.name); 경고 (self.name); } 함수 eventFun3 () {// 1. Page Structure Console.log (this)에 JS 메소드를 직접 작성하십시오. // 이것은이 범위의 문제를 포함합니다. EventFun은 글로벌 함수이며 객체는 창이며 Window Console.log (this.id)를 가리 킵니다. 경고 (this); 경고 (this); 경고 (this.id); // var outeleobj = eventutil. $ ( "outele"); // removeEvent (outELEOBJ, "click", eventFun3); } /* var eventUtil = {}; eventUtil. $ = function (id) {return document.getElementById (id); } eventUtil.openmes = EventFun3; eventUtil.addeventhandle = function (eventTarget, eventType, eventHandle) {// 객체 요소 정의, 이벤트 청취의 이벤트 유형, 이벤트 함수 if (eventTarget.attacheVent) {eventTarget.attacheVent ( "on"+eventtype, eventHandle); } else if (eventTarget.AdDeventListener) {eventTarget.AdDeventListener (EventType, EventHandle, False)} else {eventTarget [ " + eventType] = null; }}; eventUtil.deleeventhandle = function (eventTarget, eventType, eventHandle) {// 객체 요소 정의, 이벤트 청취의 이벤트 유형, 이벤트 함수 if (eventTarget.detacheVent) {alert ( "on"+eventType); 경고 ( "on"+eventHandle); eventTarget.detachevent ( "on"+eventType, eventHandle); } else if (eventTarget.removeEventListener) {eventTarget.removeEventListener (eventType, eventHandle, false)} else {eventTarget [on " + eventType] = null; }};*/ var eventUtil = {$ : function (id) {return document.getElementById (id); }, but4fun : function () {console.log (this); this.addeventhandle (); }, eventFun3 : function () {console.log (this); 경고 (this); Delevent (OBJ, EVTYPE, FN, USECAPTURE); }} /*** 청취 함수 addevent (obj, evtype, fn, usecapture) {if (obj.addeventListener) {obj.adeventListener (evtype, fn, usecapture); } else if (obj.attachevent) {obj.attachevent ( "on"+evtype, function () {fn.call (obj);}); } else {obj [ "on"+evtype] = fn; // 실제로이 상황은 존재하지 않습니다}} function delevent (obj, evtype, fn, usecapture) {if (obj.removeeventListener) {obj.removeeventListener (evttype, fn, usecapture); } else if (obj.detachevent) {obj.detachevent ( "on"+evtype, fn); } else {obj [ "on"+evtype] = null; }} function addevent (obj, evtype, fn, usecapture) {if (obj.addeventListener) {// 우선 순위는 W3C 이벤트 등록 체계 obj.addeventListener (Evtype, FN, !! usecapture)에 제공됩니다. } else {// addeventListener가 지원되지 않으면 (예 : IE), 즉 캡처를 동시에 지원하지 않기 때문에 (! fn .__ eventId) {fn .__ eventId = addevent .__ eventHandlesCounter ++;} // if (! obj .__ eventHandles) if (! fn .__ eventId) {fn .__ eventId) {fn .__ eventId)를 사용하는 것이 좋습니다. {obj .__ eventhandles = {};} // _ eventhandles 속성 속성은 모든 이벤트 핸들러에 대한 참조를 저장하는 데 사용됩니다. // 이벤트 유형으로 분류 if (! obj .__ eventhandles [evtype]) {// 이벤트가 OBJ ._ eventHandles [evType] = {}; if (obj [ "on"+evtype]) {// 이벤트 처리 기능이 전통적인 방식으로 등록되었습니다 (OBJ .__ EventHandles [evType] [0] = OBJ [ "on"+evType]). obj [ "on"+evtype] = addevent.execeventhandles; // 이벤트가 발생하면 execeventhandles는 테이블 obj ._ eventHandles [evType]를 가로 지르고 함수를 실행하고 addevent .__ eventHandleScounter = 1; // 카운터, 0 비트가 addEvent.ExeCeventhandles = function (evt) {// tranquility and this (___ ___ handwendes) {___ __ __ __ __ ___ true;} evt = evt || Window.event; var fns = this .__ eventHandles [evt.type]; for (fns의 var i) {fns [i] .call (this); }}; /* function delevent (obj, evtype, fn, usecapture) {if (obj.removeeventListener) {// 우선 w3c 메소드를 사용하여 이벤트 핸들러 기능 obj.removeEventListener (Evtype, FN, !! UseCapture); } else {if (obj .__ eventHandles) {var fns = obj .__ eventHandles [evType]; if (fns) {fns [fn .__ eventId];}}}}} 함수 fixEvent (evt) {// fixEvent 함수는 별도로 실행되지 않습니다. 이벤트 객체 매개 변수가 있어야하며 이벤트가 발생할 때만 실행됩니다! 가장 좋은 방법은 (! evt.target) {evt.target = evt.srcelement; evt.preventDefault = fixEvent.preventDefault; evt.stoppropagation = fixevent.stoppropagation; if (evt.type == "mouseover") {evt.RelatedTarget = evt.fromElement; } else if (evt.type == "마우스 아웃") {evt.RelatedTarget = evt.toElement; } evt.charcode = (evt.type == "keypress")? evt.keycode : 0; evt.eventPhase = 2; // 즉, 버블 스테이지에서만 작동합니다. } fixEvent.preventDefault = function () {this.returnValue = false; // 여기에 픽스 벤트가 아닌 특정 이벤트 객체를 가리 킵니다}; fixevent.stopPropagation = function () {this.cancelBubble = true; };*///console.log(eventutil.$("Button3")) ;///return eventUtil function //eventutil.$("Button3").onclick= eventFun; // 2. 객체 이벤트 속성에 값을 할당하는 방법을 사용하여 이벤트의 청취를 실현하는 방법 //eventutil.$("button3").onclick= eventfun2; // 이벤트 속성에 여러 메소드를 추가 할 때 후자는 //eventutil.$("Button3").onclick= eventfun; // 이벤트 캡처에 대한 이벤트 캡처에서 비롯된 것입니다. = function () {function getById (id) {return document.getElementById (id); }; // Dean Edwards, 2005 // Tino Zijdel, Matthias Miller, Diego Perini // http://dean.edwards.name/weblog/2005/10/add-event/ function addevent (요소, 유형, 핸들러) {if (expert.addeventListener) {expert.addeventlistner (type) } else {// 각 이벤트 핸들러를 고유 ID IF (! handler. $$ guid) 핸들러를 할당합니다. $$ guid = addevent.guid ++; // 요소의 해시 테이블을 만듭니다. if (! element.events) 요소 = {}; // 각 요소/이벤트 쌍에 대한 해시 이벤트 핸들러 테이블 생성 var 핸들러 = Element.Events [type]; if (! handlers) {handlers = element.events [type] = {}; // 기존 이벤트 핸들러를 저장합니다 (하나가있는 경우) if (요소 [ " + type]) {핸들러 [0] = 요소 ["on " + type]; }} // 해시 테이블 핸들러에 이벤트 핸들러를 저장합니다 [핸들러. $$ guid] = 핸들러; // 모든 작업 요소를 수행하도록 글로벌 이벤트 핸들러를 지정합니다 [ "on" + type] = handleEvent; }}; // 고유 한 ID를 생성하는 데 사용되는 카운터 addEvent.guid = 1; 함수 removeEvent (요소, 유형, 핸들러) {if (element.removeEventListener) {element.removeEventListener (type, handler, false); } else {// 해시 테이블에서 이벤트 핸들러를 삭제 if (element.events && element.events [type]) {element.events [type] [handler. $$ guid]; }}}; 함수 handleEvent (이벤트) {var returnValue = true; // 이벤트 객체를 잡습니다 (즉, 글로벌 이벤트 개체 사용) 이벤트 = 이벤트 || fixEvent (((this.ownerDocument || this.thocument || this) .parentWindow || 창) .event); // 해시 핸들러의 해시 테이블에 대한 참조를 가져옵니다. var 핸들러 = this.events [event.type]; // 각 이벤트 핸들러를 실행합니다 (handlers in handlers) {this. $$ handleEvent = 핸들러 [i]; if (this. $$ handleEvent (event) === false) {returnValue = false; }} return returnValue; }; 함수 fixEvent (이벤트) {// W3C 표준 이벤트 메소드 추가 event.preventDefault = fixEvent.preventDefault; event.stoppropagation = fixevent.stoppropagation; 반환 이벤트; }; fixEvent.preventDefault = function () {this.returnValue = false; }; fixevent.stopPropagation = function () {this.cancelBubble = true; }; 함수 tableadDevent () {}; return {add : addevent, 제거 : removeEvent, $ : getById}} (); var outeleobj = eventutil. $ ( "outele"); //addevent.apply (eventutil,”, eventfun3]); //eventutil.add(outeleobj,"click", Eventfun3); var inputobj = eventUtil. $ ( "button4"); var tableele = eventUtil. $ ( "htmleletable"); var tabtrele = tableele.getElementsByTagName ( "tr"); eventUtil.add (tableele, "click", eventfun3); for (i = 0; i <tabtrele.length; i ++) {eventutil.add (tabtrele [i], "click", eventfun3); } eventUtil.remove (TableEle, "click", eventFun3); // event deletion method eventUtil.add (tableele, "click", eventfun3); // eventUtil.add (inputobj, "click", eventfun3); //eventutil.remove(outeleobj,"click", Eventfun3); //console.log(addevent); // addevent (inputoBj, "click", eventFun3, true); // delevent (outeleobj, "click", eventfun3, false); </script> </body> </html>추신 : 여기서는 JS 이벤트에 대한 온라인 도구를 제공합니다.이 행사는 일반적으로 사용되는 이벤트 유형과 JS의 기능 기능을 요약합니다.
JavaScript 이벤트 및 기능의 전체 목록 :
http://tools.vevb.com/table/javaScript_event