jQuery와 같은 더 많은 프레임 워크를 사용하는 쓰기를 사용하면 필연적으로 원시 JS에서 능숙 할 가능성이 적습니다.
Xiaocai는 실제로이 블로그를 쓰고 싶지 않지만 매우 기초적인 것 같습니다. 그러나 그녀는 인터넷에서 Native JS 이벤트의 구속력과 해체를 설명 할 수 없다는 것을보고 인기있는 과학을 만들기로 결정했습니다.
우선, Xiaocai는 많이 알지 못하고 내 아이디어를 여러분과 공유하십시오.
DOM0 이벤트 모델
이벤트 모델은 지속적으로 발전하고 있으며 초기 이벤트 모델을 DOM0 레벨이라고합니다.
모든 브라우저에서 지원되는 DOM0 이벤트 모델.
DOM 객체에 이벤트 이름을 직접 등록하는 것은 다음과 같은 DOM0 쓰기 방법입니다.
코드 사본은 다음과 같습니다.
document.getElementById ( "test"). onclick = function (e) {};
그것은 OnClick 이벤트를 등록하는 것을 의미합니다. 물론, 그것은이 글과 같은 의미를 가지고 있습니다.
코드 사본은 다음과 같습니다.
document.getElementById ( "test") [ "onMousEmove"] = function (e) {};
이것은 아무것도 아닙니다. JS 객체 속성에 액세스하는 두 가지 방법 일뿐입니다. []의 형태는 주로 속성 이름이 법적 식별자가 아니라는 문제를 해결하기위한 것입니다. 예를 들어, Object.123은 오류를보고해야하지만 Object [ "123"]는이 문제를 피합니다. 동시에, []의 쓰기는 문자열을 사용하여 속성 이름을 나타내는 js를 살아 있으며, 이는 런타임에 이벤트를 동적으로 바인딩 할 수 있습니다.
시점으로 돌아가서 이벤트가 트리거되면 이벤트 객체를 나타 내기 위해 매개 변수 e가 기본적으로 전달됩니다. E를 통해 클릭의 좌표, 이벤트를 구체적으로 트리거 한 DOM 요소 등과 같은 많은 유용한 정보를 얻을 수 있습니다.
DOM0 이벤트를 기반으로 동일한 DOM 노드의 경우 하나만 등록 할 수 있으며 나중에 등록 된 동일한 이벤트는 이전에 등록 된 이벤트를 무시합니다. 예를 들어:
코드 사본은 다음과 같습니다.
var btn = document.getElementById ( "테스트");
btn.onmouseMove = function (e) {
경고 ( "OK");
};
btn [ "onmouseMove"] = function (e) {
경고 ( "ok1");
};
결과는 OK1을 출력합니다.
다음에 이것에 대해 이야기합시다. 이벤트가 트리거되면 이벤트가 트리거되는 DOM 객체를 나타냅니다. 예를 들어:
코드 사본은 다음과 같습니다.
var btn = document.getElementById ( "테스트");
btn.onmouseMove = function (e) {
경고 (this.id);
};
결과는 테스트를 출력합니다. 이벤트는 ID 테스트와 함께 DOM 노드에 등록되므로 이벤트가 트리거되면이 DOM 노드를 나타냅니다. 이 행사는이 DOM 노드에 의해 호출된다는 것을 이해할 수 있습니다.
따라서 이벤트를 취소하는 것은 매우 간단합니다. 예를 들어 이벤트를 다시 등록하고 값을 NULL로 설정하면됩니다.
코드 사본은 다음과 같습니다.
var btn = document.getElementById ( "테스트");
btn.onclick = function (e) {
경고 ( "OK");
};
btn.onclick = null;
원칙은 마지막으로 등록 된 이벤트가 이전 이벤트를 덮어 써야한다는 것입니다. 마지막으로 등록 된 이벤트를 NULL로 설정하면 이벤트를 풀립니다.
이 문제는 아직 끝나지 않았으며 DOM0 이벤트 모델에는 HTML에 직접 작성된 이벤트도 포함됩니다. 예를 들어:
코드 사본은 다음과 같습니다.
<div id = "test"onclick = "exec ();" > </div>
이러한 방식으로 등록 된 이벤트는 범위 원칙에 따라 이벤트를 따르며 하나만 등록 할 수 있으며 마지막이라는 이벤트는 적용됩니다.
차이점은 이러한 방식으로 등록 된 이벤트가 함수를 동적으로 호출하는 것과 동일하므로 (다소 평가 수단) 이벤트 객체가 전달되지 않습니다. 동시에, 이것은 더 이상 이벤트를 트리거하는 DOM 객체가 아닙니다.
DOM2 이벤트 모델
DOM0과 비교하여 Shouca는 다음 두 가지 점을 이해합니다.
dom2는 동일한 DOM 요소로 여러 동일한 이벤트의 등록을 지원합니다.
dom2는 캡처 및 버블 링의 개념을 추가했습니다.
DOM2 이벤트는 AddeventListener 및 RemoveEventListener에 의해 관리됩니다. 물론 이것은 표준입니다.
그러나 IE8과 다음 브라우저는 해당 첨부 및 분리 기반을 생성했습니다. Xiaocai는 의도하지 않기 때문에이 기사는 논의하지 않을 것입니다.
AddeventListener는 물론 등록 이벤트입니다. "이벤트 이름", "이벤트 콜백"및 "Capture/Bubble"의 세 가지 매개 변수가 있습니다. 예를 들어:
코드 사본은 다음과 같습니다.
var btn = document.getElementById ( "테스트");
btn.addeventListener ( "클릭", function (e) {
경고 ( "OK");
}, 거짓);
말할 것도없이, 이벤트 이름은 그리 많지 않습니다. DOM0과 비교하여 이전 ON이 제거되었습니다.
이벤트 콜백도 이해하기 쉽습니다. 이벤트가 트리거되면 알려야합니다! DOM0과 같이 다시 호출 할 때 이벤트 매개 변수가 기본적으로 전달됩니다. 동시에, 이것은 이벤트를 트리거하는 DOM 노드를 나타냅니다.
마지막 매개 변수는 부울 유형, true는 캡처 이벤트를 나타내고, 거품 이벤트를 나타냅니다. 실제로 이해하기 쉽습니다. 먼저 다이어그램을 만들어 봅시다 :
요소가 이벤트를 트리거하는 경우, 가장 먼저 알림은 창과 문서이며 실제로 이벤트를 트리거하는 요소 (대상 요소)까지 순서대로 진행한다는 것을 의미합니다. 이 과정은 캡처됩니다. 다음으로, 이벤트는 대상 요소에서 기포 된 다음 창 객체가 될 때까지 순서대로 종료됩니다. 이 과정은 거품입니다.
왜 이런 식으로 디자인합니까? 이것은 심오한 역사적 기원 때문인 것 같습니다. Xiaocai는 그것에 대해 많이 알지 못하므로 말도 안되는 말을하지 않을 것입니다.
이것으로부터 우리는 캡처 이벤트가 버블 이벤트 전에 트리거되는 것을 볼 수 있습니다.
그러한 HTML 구조가 있다고 가정합니다.
코드 사본은 다음과 같습니다.
<div id = "test">
<div id = "testinner"> </div>
</div>
그런 다음 OUTER DIV에 두 번의 클릭 이벤트, 즉 캡처 이벤트 및 버블 링 이벤트에 등록합니다. 코드는 다음과 같습니다.
코드 사본은 다음과 같습니다.
var btn = document.getElementById ( "테스트");
// 이벤트를 잡습니다
btn.addeventListener ( "클릭", function (e) {
경고 ( "ok1");
}, 진실);
// 버블 링 이벤트
btn.addeventListener ( "클릭", function (e) {
경고 ( "OK");
}, 거짓);
마지막으로, 내부 div를 클릭하고 먼저 OK1을 팝업 한 다음 OK를 나타냅니다. 위의 회로도와 결합하여, 외부 div는 그림의 신체와 동일하며 내부 div는 그림의 하단 div와 동일하여 캡처 이벤트가 먼저 실행되고 버블 이벤트가 실행됨을 증명합니다.
내부 DIV 클릭을 강조하는 이유는 무엇입니까? 실제로 이벤트를 트리거하는 DOM 요소는 내부 층에서 이루어져야하며 외부 레이어 DOM 요소는 회로도에서 볼 수있는 이벤트 및 버블 이벤트를 시뮬레이션하고 캡처 할 수있는 기회가 있습니다.
실제로 이벤트를 트리거하는 DOM 요소에 캡처 이벤트와 버블 링 이벤트를 등록하면 어떻게됩니까?
HTML 구조는 위와 동일하며 JS 코드는 다음과 같습니다.
코드 사본은 다음과 같습니다.
var btninner = document.getElementById ( "TestInner");
// 버블 링 이벤트
btninner.addeventListener ( "Click", function (e) {
경고 ( "OK");
}, 거짓);
// 이벤트를 잡습니다
btninner.addeventListener ( "Click", function (e) {
경고 ( "ok1");
}, 진실);
물론 내부 DIV를 클릭하면 결과가 먼저 나타나면 OK1이 나타납니다. 이론적으로 캡처 이벤트는 먼저 트리거되어야합니다. 즉, OK1이 먼저 팝업되지만 여기에 특별합니다. 실제로 이벤트를 트리거하는 DOM 요소에 이벤트를 등록하기 때문에 그림에 DIV에 등록하는 것과 같습니다. 그림에서 실제로 이벤트를 트리거하는 DOM 요소가 캡처 이벤트의 종말점이자 버블 이벤트의 시작점이므로 여기에서 이벤트 간에는 차이가 없습니다. 먼저 등록하는 어느 것이 먼저, 어느 것을 실행합니다. 이 예에서는 버블 이벤트가 먼저 등록되므로 먼저 실행됩니다.
이 원칙은 같은 종류의 여러 사건에 적용됩니다. 예를 들어, 3 개의 버블 이벤트가 한 번에 등록되면 실행 순서는 등록 순서, 첫 번째 등록 및 첫 번째 실행 순서입니다. 예를 들어:
코드 사본은 다음과 같습니다.
var btninner = document.getElementById ( "TestInner");
btninner.addeventListener ( "Click", function (e) {
경고 ( "OK");
}, 거짓);
btninner.addeventListener ( "Click", function (e) {
경고 ( "ok1");
}, 거짓);
btninner.addeventListener ( "Click", function (e) {
경고 ( "ok2");
}, 거짓);
결과는 물론 Ok1 및 Ok2 팝업입니다.
이벤트 모델을 더 이해하기 위해 또 다른 시나리오가 있습니다. 외부 div와 내부 div가 캡처 이벤트를 동시에 등록하는 경우 내부 div를 클릭하면 외부 div 이벤트가 먼저 트리거되어야합니다. 코드는 다음과 같습니다.
코드 사본은 다음과 같습니다.
var btn = document.getElementById ( "테스트");
var btninner = document.getElementById ( "TestInner");
btninner.addeventListener ( "Click", function (e) {
경고 ( "OK");
}, 진실);
btn.addeventListener ( "클릭", function (e) {
경고 ( "ok1");
}, 진실);
결과적으로 OK1이 먼저 나타납니다.
외부 div와 내부 div가 모두 등록 된 버블 이벤트 인 경우, 내부 div를 클릭 할 때 내부 div 이벤트를 먼저 실행해야하며 원리는 동일합니다.
신중한 독자들은 Div Nesting의 경우 내부 DIV를 클릭하면 OUTER DIV도 이벤트를 트리거하여 문제가되는 것 같습니다!
클릭은 분명히 내부 DIV이지만 Outer Div 이벤트도 트리거되어 실제로 문제입니다.
실제로 이벤트가 트리거되면 이벤트 객체가 기본적으로 전달됩니다. 앞에서 언급 했듯이이 이벤트 객체에 대한 방법이 있습니다 : stoppropagation. 이 방법을 통해 거품을 방지하여 외부 디바리가 이벤트를받지 못하게 할 수 있습니다. 코드는 다음과 같습니다.
코드 사본은 다음과 같습니다.
var btn = document.getElementById ( "테스트");
var btninner = document.getElementById ( "TestInner");
btn.addeventListener ( "클릭", function (e) {
경고 ( "ok1");
}, 거짓);
btninner.addeventListener ( "Click", function (e) {
// 거품을 멈 춥니 다
E.StopPropagation ();
경고 ( "OK");
}, 거짓);
마지막으로, 나는 사건을 해결하는 방법에 대해 이야기해야합니다. Unevent Syntax : Btn.removeeventListener ( "이벤트 이름", "이벤트 콜백", "Capture/Bubble");
이것은 자세히 설명 된 바와 같이 바인딩 이벤트의 매개 변수와 동일합니다.
・ 이벤트 이름은 이벤트를 취소하는 것을 의미합니다.
・ 이벤트 콜백은 함수이며 이벤트를 등록하는 함수와 동일해야합니다.
・ 이벤트 유형, 부울 값, 이벤트가 등록 될 때 유형과 일치해야합니다.
다시 말해, 이름, 콜백 및 타이핑은 취소 할 이벤트를 함께 결정하면 필수적입니다. 예를 들어:
코드 사본은 다음과 같습니다.
var btn = document.getElementById ( "테스트");
// 콜백을 변수에 저장합니다
var fn = function (e) {
경고 ( "OK");
};
//제본
btn.addeventListener ( "클릭", fn, false);
//제거
btn.removeeventListener ( "클릭", fn, false);
등록 된 이벤트를 취소하려면 콜백 함수를 저장해야합니다. 그렇지 않으면 취소 할 수 없습니다.
혼합 DOM0 및 DOM2
상황은 이미 매우 지저분하며, 이것은 혼합 된 용도로 사람들을 살게합니다. . .
두려워하지 말고 혼합 방식으로 사용하는 것은 문제가되지 않습니다. DOM0 모델과 DOM2 모델은 각각 자신의 규칙을 따르며 서로 영향을 미치지 않습니다.
전반적으로, 먼저 등록되어 먼저 실행되면 아무것도 없습니다.
추신
이 시점에서 Native JS 이벤트는 거의 완료되었습니다. Xiaocai는 이것을 알고 있습니다. 독자는 다른 지식 포인트를 추가 할 수 있습니다.
실제 응용 프로그램에서 실제 전문가는 많은 이벤트를 어리석게 등록하지 않습니다. 일반적으로 말하면, 가장 바깥 쪽 DOM 요소에 이벤트를 등록한 다음 캡처 및 버블 메커니즘을 사용하여 실제로 이벤트를 트리거하는 DOM 요소를 찾아 이벤트를 트리거하는 DOM 요소가 제공 한 정보를 기반으로 콜백을 호출해야합니다.
다시 말해, 전문가들은 브라우저에 의존하지 않고 이벤트를 관리하여 이벤트를 관리하여 효율성을 향상시키고 호환성을 보장 할 수 있습니다. 이것이 jQuery가하는 일이 아닌가?
자, 튜토리얼은 여기서 끝납니다. 독자들에게 도움이되기를 바랍니다!