JavaScript 이벤트 메커니즘 호환성 솔루션을 자세히 설명하는 코드 그래픽 및 텍스트
이 문서의 솔루션은 Javascript 기본객체 그리고 호스트 객체(dom 요소)는
또는
var input = document.getElementsByTagName('input')[0]; var form = document.getElementsByTagName('form')[0]; Evt.on(input, 'click', function(evt){ console.log('input click1'); console.log(evt.target === input); console.log(evt.modified); //evt.stopPropagation(); console.log(evt.modified); }); var handle2 = Evt.on(input, 'click', function(evt){ console.log('input click2'); console.log(evt.target === input); console.log(evt.modified); }); Evt.on(form, 'click', function(evt){ console.log('form click'); console.log(evt.currentTarget === input); console.log(evt.target === input); console.log(evt.currentTarget === form); console.log(evt.modified); }); Evt.emit(input, 'click'); Evt.emit(input, 'click', {bubbles: true}); handle2.remove(); Evt.emit(input, 'click');
를 바인딩하고 트리거합니다.
After네이티브 객체에 이벤트를 추가하는 과정은 주로 after 함수에서 완료됩니다.- obj에 응답 함수가 있는 경우 이를 디스패처 함수로 대체
- 체인 구조를 사용하여 여러 바인딩된 이벤트 함수의 순차적 실행 보장
- remove 메소드를 호출하면 이 이벤트 바인딩을 제거할 수 있습니다.
댓글을 참고해주세요 독자님들도 따라해서 다시 실행해보시길 바랍니다
var after = function(target, method, cb, originalArgs){ var existing = target[method]; var dispatcher = existing; if (!existing || existing.target !== target) { //如果target中没有method方法,则为他添加一个方法method方法 //如果target已经拥有method方法,但target[method]中target不符合要求则将method方法他替换 dispatcher = target[method] = function(){ //由于js是此法作用域:通过阅读包括变量定义在内的数行源码就能知道变量的作用域。 //局部变量在声明它的函数体内以及其所嵌套的函数内始终是有定义的 //所以在这个函数中可以访问到dispatcher变量 var results = null; var args = arguments; if (dispatcher.around) {//如果原先拥有method方法,先调用原始method方法 //此时this关键字指向target所以不用target results = dispatcher.around.advice.apply(this, args); } if (dispatcher.after) {//如果存在after链则依次访问其中的advice方法 var _after = dispatcher.after; while(_after && _after.advice) { //如果需要原始参数则传入arguments否则使用上次执行结果作为参数 args = _after.originalArgs ? arguments : results; results = _after.advice.apply(this, args); _after = _after.next; } } } if (existing) { //函数也是对象,也可以拥有属性跟方法 //这里将原有的method方法放到dispatcher中 dispatcher.around = { advice: function(){ return existing.apply(target, arguments); } } } dispatcher.target = target; } var signal = { originalArgs: originalArgs,//对于每个cb的参数是否使用最初的arguments advice: cb, remove: function() { if (!signal.advice) { return; } //remove的本质是将cb从函数链中移除,删除所有指向他的链接 var previous = signal.previous; var next = signal.next; if (!previous && !next) { dispatcher.after = signal.advice = null; dispatcher.target = null; delete dispatcher.after; } else if (!next){ signal.advice = null; previous.next = null; signal.previous = null; } else if (!previous){ signal.advice = null; dispatcher.after = next; next.previous = null; signal.next = null; } else { signal.advice = null; previous.next = next; next.previous = previous; signal.previous = null; signal.next = null; } } } var previous = dispatcher.after; if (previous) {//将signal加入到链式结构中,处理指针关系 while(previous && previous.next && (previous = previous.next)){}; previous.next = signal; signal.previous = previous; } else {//如果是第一次使用调用after方法,则dispatcher的after属性指向signal dispatcher.after = signal; } cb = null;//防止内存泄露 return signal; }
IE 브라우저DOM2 IE9이벤트 처리프로그램부터 지원되었지만 이전 버전의 IE 브라우저에서는 DOM 요소에 이벤트를 추가하는 데 여전히 attachmentEvent 메서드가 사용됩니다. 다행히 Microsoft는 2016년에 더 이상 IE8을 유지하지 않을 것이라고 발표했습니다. 이는 대부분의 프런트 엔드 개발자에게 의심할 여지 없이 좋은 소식입니다. DOM2 수준 이벤트 핸들러를 지원하지 않는 브라우저에 대한 호환성은 여전히 처리되어야 하며 일반적으로 다음 사항이 필요합니다. be handler:
- more 한 번에 이벤트를 바인딩하면 이벤트 처리 함수의 호출 순서가 문제입니다
- this 키워드는 이벤트 처리 기능이 문제를 지적
- 표준화된 이벤트 이벤트 객체, 일반적으로 사용되는 이벤트 속성을 지원합니다
//1、统一事件触发顺序 function fixAttach(target, type, listener) { debugger; var listener = fixListener(listener); var method = 'on' + type; return after(target, method, listener, true); };
//1、统一事件触发顺序 function fixAttach(target, type, listener) { debugger; var listener = fixListener(listener); var method = 'on' + type; return after(target, method, listener, true); }; function fixListener(listener) { return function(evt){ //每次调用listenser之前都会调用fixEvent debugger; var e = _fixEvent(evt, this);//this作为currentTarget if (e && e.cancelBubble && (e.currentTarget !== e.target)){ return; } var results = listener.call(this, e); if (e && e.modified) { // 在整个函数链执行完成后将lastEvent回归到原始状态, //利用异步队列,在主程序执行完后再执行事件队列中的程序代码 //常规的做法是在emit中判断lastEvent并设为null //这充分体现了js异步编程的优势,把变量赋值跟清除代码放在一起,避免逻辑分散,缺点是不符合程序员正常思维方式 if(!lastEvent){ setTimeout(function(){ lastEvent = null; }); } lastEvent = e; } return results; } }
_preventDefault, _stopPropagation 및 _stopImmediatePropagation의 세 가지 함수에서 호출되면 리스너는 실행 후 이벤트 개체를 저장하기 위해 변수를 사용합니다(fixListener 참조). ), 후속 이벤트 핸들러가 이벤트 객체 속성에 따라 다음 단계를 수행할 수 있도록 합니다. stopImmediatePropagation 함수는 이 함수의 시뮬레이션을 위해 클로저를 통해 해결됩니다.
위의 fixListener도 마찬가지입니다.
우리는 다른 목적을 위해 이벤트를 표준화한다는 점에 유의해야 합니다. 다음과 같이 Emit 메소드에 매개변수를 설정하여 이벤트 프로세스를 제어할 수 있습니다. Evt.emit(input, 'click');//거품 없음
Evt.emit(input, 'click', {bubbles: true});//거품
내 의견에 따르면 테스트에서는 이벤트를 트리거하기 위해 fireEvent를 사용합니다. 버블링을 방지하기 위해 {bubbles:false}를 설정할 수 없으므로 여기서는 버블링 프로세스를 시뮬레이션하기 위해 Javascript를 사용합니다. 동시에 이 과정에서 이벤트 객체의 고유성도 보장되어야 합니다.
function _fixEvent(evt, sender){ if (!evt) { evt = window.event; } if (!evt) { // emit没有传递事件参数,或者通过input.onclick方式调用 return evt; } if(lastEvent && lastEvent.type && evt.type == lastEvent.type){ //使用一个全局对象来保证在冒泡过程中访问的是同一个event对象 //chrome中整个事件处理过程event是唯一的 evt = lastEvent; } var fixEvent = evt; // bubbles 和cancelable根据每次emit时手动传入参数设置 fixEvent.bubbles = typeof evt.bubbles !== 'undefined' ? evt.bubbles : false; fixEvent.cancelable = typeof evt.cancelable !== 'undefined' ? evt.cancelable : true; fixEvent.currentTarget = sender; if (!fixEvent.target){ // 多次绑定统一事件,只fix一次 fixEvent.target = fixEvent.srcElement || sender; fixEvent.eventPhase = fixEvent.target === sender ? 2 : 3; if (!fixEvent.preventDefault) { fixEvent.preventDefault = _preventDefault; fixEvent.stopPropagation = _stopPropagation; fixEvent.stopImmediatePropagation = _stopImmediatePropagation; } //参考:http://www.php.cn/ if( fixEvent.pageX == null && fixEvent.clientX != null ) { var doc = document.documentElement, body = document.body; fixEvent.pageX = fixEvent.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0); fixEvent.pageY = fixEvent.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0); } if (!fixEvent.relatedTarget && fixEvent.fromEvent) { fixEvent.relatedTarget = fixEvent.fromEvent === fixEvent.target ? fixEvent.toElement : fixEvent.fromElement; } // 参考: http://www.php.cn/ if (!fixEvent.which && fixEvent.keyCode) { fixEvent.which = fixEvent.keyCode; } } return fixEvent; } function _preventDefault(){ this.defaultPrevented = true; this.returnValue = false; this.modified = true; } function _stopPropagation(){ this.cancelBubble = true; this.modified = true; } function _stopImmediatePropagation(){ this.isStopImmediatePropagation = true; this.modified = true; }
전체 코드가 첨부되어 있습니다:
// 模拟冒泡事件 var sythenticBubble = function(target, type, evt){ var method = 'on' + type; var args = Array.prototype.slice.call(arguments, 2); // 保证使用emit触发dom事件时,event的有效性 if ('parentNode' in target) { var newEvent = args[0] = {}; for (var p in evt) { newEvent[p] = evt[p]; } newEvent.preventDefault = _preventDefault; newEvent.stopPropagation = _stopPropagation; newEvent.stopImmediatePropagation = _stopImmediatePropagation; newEvent.target = target; newEvent.type = type; } do{ if (target && target[method]) { target[method].apply(target, args); } }while(target && (target = target.parentNode) && target[method] && newEvent && newEvent.bubbles); } var emit = function(target, type, evt){ if (target.dispatchEvent && document.createEvent){ var newEvent = document.createEvent('HTMLEvents'); newEvent.initEvent(type, evt && !!evt.bubbles, evt && !!evt.cancelable); if (evt) { for (var p in evt){ if (!(p in newEvent)){ newEvent[p] = evt[p]; } } } target.dispatchEvent(newEvent); } /*else if (target.fireEvent) { target.fireEvent('on' + type);// 使用fireEvent在evt参数中设置bubbles:false无效,所以弃用 } */else { return sythenticBubble.apply(on, arguments); } }
뇌 지도:
BSD 라이선스에 따른 KityMinder Powered by f-cube, Source Bug |
위 내용은 자바스크립트 이벤트 메커니즘 호환 솔루션을 자세히 설명하는 코드와 그림의 내용입니다. 더 많은 관련 내용은 PHP 중국어 홈페이지(www.php.cn)를 참고해주세요!
핫 AI 도구

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

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

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

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

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

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

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

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

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

뜨거운 주제











요즘 많은 휴대폰에서 블루투스 5.3 버전을 지원한다고 하는데, 블루투스 5.3과 5.2의 차이점은 무엇인가요? 사실 블루투스 5의 후속 업데이트 버전이라 대부분의 성능과 기능에는 큰 차이가 없습니다. Bluetooth 5.3과 5.2의 차이점: 1. 데이터 속도 1과 5.3은 최대 2Mbps의 더 높은 데이터 속도를 지원할 수 있습니다. 2. 5.2는 최대 1Mbps까지만 도달할 수 있지만, 이는 5.3이 더 빠르고 안정적으로 데이터를 전송할 수 있다는 것을 의미합니다. 2. 암호화 제어 향상 2. Bluetooth 5.3은 암호화 키 길이 제어 옵션을 개선하고 보안을 강화하며 액세스 제어 및 기타 장치에 더 잘 연결할 수 있습니다. 3. 동시에 관리자 제어가 간편해지기 때문에 연결이 더욱 편리하고 빨라지는데, 5.2에서는 그렇지 않습니다.

i77700의 성능은 win11을 실행하기에 충분하지만 사용자는 i77700을 win11로 업그레이드할 수 없다는 것을 알게 됩니다. 이는 주로 Microsoft에서 부과한 제한 사항 때문이므로 이 제한 사항을 건너뛰는 한 설치할 수 있습니다. i77700은 win11로 업그레이드할 수 없습니다. 1. Microsoft에서는 CPU 버전을 제한하기 때문입니다. 2. Intel의 8세대 이상 버전만 win11로 직접 업그레이드할 수 있습니다. 3. 7세대인 i77700은 win11의 업그레이드 요구 사항을 충족할 수 없습니다. 4. 하지만 i77700은 성능면에서 win11을 완벽하게 원활하게 사용할 수 있습니다. 5. 따라서 이 사이트의 win11 직접 설치 시스템을 사용할 수 있습니다. 6. 다운로드가 완료되면 파일을 마우스 오른쪽 버튼으로 클릭하고 "로드"합니다. 7. 더블클릭하여 "원클릭"을 실행합니다.

Go 언어는 Linux 시스템에서 매우 우수한 호환성을 가지며 다양한 Linux 배포판에서 원활하게 실행될 수 있으며 다양한 아키텍처의 프로세서를 지원합니다. 이 기사에서는 Linux 시스템에서 Go 언어의 호환성을 소개하고 특정 코드 예제를 통해 Go 언어의 강력한 적용 가능성을 보여줍니다. 1. Go 언어 환경을 설치합니다. Linux 시스템에 Go 언어 환경을 설치하는 것은 매우 간단합니다. 해당 Go 바이너리 패키지를 다운로드하고 관련 환경 변수를 설정하기만 하면 됩니다. 다음은 Ubuntu 시스템에 Go 언어를 설치하는 단계입니다.

현대 기술의 지속적인 발전으로 무선 블루투스 헤드셋은 사람들의 일상 생활에 없어서는 안될 부분이 되었습니다. 무선 헤드폰의 등장으로 손이 자유로워져 음악, 통화, 기타 엔터테인먼트 활동을 더욱 자유롭게 즐길 수 있게 되었습니다. 하지만 비행기를 탈 때 휴대폰을 비행기 모드로 설정하라는 요청을 받는 경우가 많습니다. 문제는 비행기 모드에서 Bluetooth 헤드폰을 사용할 수 있느냐는 것입니다. 이번 글에서는 이 질문에 대해 살펴보겠습니다. 먼저 비행기 모드의 기능과 의미를 이해해 보겠습니다. 비행기 모드는 휴대폰의 특수 모드입니다.

win10 시스템의 소프트웨어는 완벽하게 최적화되어 있지만 최신 win11 사용자라면 누구나 이 시스템이 지원될 수 있는지 궁금할 테니, 다음은 win10을 지원하지 않는 win11 소프트웨어에 대해 자세히 소개합니다. 함께. win11은 win10 소프트웨어를 지원합니까? 1. Win10 시스템 소프트웨어와 Win7 시스템 응용 프로그램도 잘 호환됩니다. 2. Win11 시스템을 사용하는 전문가의 피드백에 따르면 현재 애플리케이션 비호환 문제는 없습니다. 3. 그러니 안심하고 과감하게 업그레이드할 수 있지만, 일반 사용자들은 Win11 정식 버전이 출시될 때까지 기다렸다가 업그레이드하는 것이 좋습니다. 4. Win11은 호환성이 좋을 뿐만 아니라 Windo도 있습니다.

JavaScript 튜토리얼: HTTP 상태 코드를 얻는 방법, 특정 코드 예제가 필요합니다. 서문: 웹 개발에서는 서버와의 데이터 상호 작용이 종종 포함됩니다. 서버와 통신할 때 반환된 HTTP 상태 코드를 가져와서 작업의 성공 여부를 확인하고 다양한 상태 코드에 따라 해당 처리를 수행해야 하는 경우가 많습니다. 이 기사에서는 JavaScript를 사용하여 HTTP 상태 코드를 얻는 방법과 몇 가지 실용적인 코드 예제를 제공합니다. XMLHttpRequest 사용

1. 프로그램을 마우스 오른쪽 버튼으로 클릭하고 열리는 속성 창에 [호환성] 탭이 없는지 확인합니다. 2. Win10 바탕화면에서 바탕화면 좌측 하단의 시작 버튼을 마우스 오른쪽 버튼으로 클릭하고 팝업 메뉴에서 [실행] 메뉴 항목을 선택합니다. 3. Win10 실행창이 열리며, 창에 gpedit.msc를 입력한 후 확인 버튼을 클릭하세요. 4. 로컬 그룹 정책 편집기 창이 열립니다. 창에서 [컴퓨터 구성/관리 템플릿/Windows 구성 요소] 메뉴 항목을 클릭하세요. 5. 열린 Windows 구성 요소 메뉴에서 [응용 프로그램 호환성] 메뉴 항목을 찾은 후 오른쪽 창에서 [프로그램 호환성 속성 제거 페이지] 설정 항목을 찾습니다. 6. 설정 항목을 마우스 오른쪽 버튼으로 클릭한 후 팝업 메뉴에서

PHP 함수 호환성 문제를 해결하기 위한 모범 사례: 버전이 지정된 함수 이름(예: array_map_recursive())을 사용하고 함수 별칭(예: functionarray_map($callback,$array){...})을 활용하여 함수 가용성을 확인합니다(예: : if (function_exists('array_map_recursive')){...}) 네임스페이스 사용(예: 네임스페이스MyNamespace{...})
