>웹 프론트엔드 >JS 튜토리얼 >javascript 이벤트 모델 code_javascript 기술

javascript 이벤트 모델 code_javascript 기술

WBOY
WBOY원래의
2016-05-16 19:11:29919검색

이 섹션에서는 이벤트 처리 주제에 대해 좀 더 깊이 설명합니다. 패턴, 클로저, 객체 지향과 같은 개념을 잘 이해하지 못한다면 관련 내용을 다 읽을 때까지 기다렸다가 다시 돌아오는 것이 좋습니다. 읽어보시면 많은 것을 배우실 수 있을 거라 믿습니다.

1 이벤트 처리 모드

프로그래밍 분야에서 "이벤트 처리"는 외부 영향으로 객체의 상태가 변경될 때 이를 메시지로 알려주는 모드입니다. 객체 또는 관련 객체를 지정하고 해당 작업을 수행하도록 하는 것이 이벤트 처리의 기본 원칙입니다. 상태 변경을 알리는 역할을 하는 객체를 "메시지"라고 하며, 응답 작업을 수행하는 속성을 "이벤트 에이전트"라고 합니다.
예를 들어 다음은 간단한 이벤트 처리 패턴 애플리케이션입니다.

function dispatchEvent(owner, eventType, eventArgs)
{
if(owner && owner["on" eventType])
setTimeout(function(){owner["on" eventType](eventArgs)}, 1)
}

functionrandomSerials(len)
{
functionrandomSignal()
{
return Math.random() > 0.5 ?
}
var ret = []
for(var i = 0; i {
ret.push(randomSignal());
}
return ret
}

function Differ(obl)
{
var buffer = new Array(obl);
var time = 0;

this.readBuffer = function()
{
var buf = buffer; obl );

return buf;

this.bufferSize = function()
{
return
}

this.input = function(serials)
{
for(var i = 1; i {
var signal = Math.abs( 연재물 [i] - 연재물[i - 1])
buffer[time % obl] = signal;
if(signal) dispatchEvent(this, "signalchange",
{input:serials , 시간:시간, 버퍼:buffer.slice(0)});
}
}
}

var inputSerials = randomSerials(20)
alert(inputSerials);
var diff10 = new Differ(20);
diff10.input(inputSerials);
alert(diff10.readBuffer())

diff10.onsignalchange = function(eventArgs)
{
Alert(eventArgs.time);
}

diff10.input(inputSerials);

위의 예에서 함수 dispatchEvent는 이벤트 전달을 담당합니다. onsignalchange는 이벤트 프록시입니다. 이 차동 시스템 diff10에서 입력 신호의 레벨이 변경되면(0에서 1 또는 1에서 0으로) 해당 이벤트 onsignalchange가 트리거되고 현재 입력 신호, 타이밍 및 현재 출력 버퍼 이벤트 매개변수로 전달됩니다. 이벤트 핸들러를 입력합니다.

diff10.onsignalchange = function(eventArgs)
{
Alert(eventArgs.time);
}

는 프로그래머가 지정한 이벤트 핸들러입니다. 여기서는 다음을 인쇄합니다. 입력 레벨이 변경되면 입력 신호 타이밍을 출력합니다.

2 사용자 이벤트 인터페이스 정의

앞의 예에서는 이벤트 전달을 위한 함수 dispatchEvent만 정의했지만, 이제 이를 완전한 사용자 이벤트 인터페이스로 간주할 수도 있습니다. 함수를 사용하여 그 기능을 알아보세요.

function dispatchEvent(owner, eventName, eventArgs)
{
if(owner && owner["on" eventName] )
     setTimeout(function() {owner["on" eventName](eventArgs)}, 1); 개체는 이 이벤트의 "소유자", 즉 이 이벤트를 수신하고 처리하는 사람을 지정합니다. 위의 예에서 소유자는 Differ 개체 자체입니다.
dispatchEvent(this, "signalchange", {input:serials, time:time, buffer:buffer})
전달된 소유자 매개 변수는 다음과 같습니다. 실제로 이벤트 패턴을 사용하면 다른 유형이 이벤트 전달의 소유자가 될 수 있습니다. 특히 일부 특정 패턴에서는 일반적으로 이벤트 시작자와 이벤트 수신자가 동일한 객체가 아닐 수 있습니다. 이는 섹션 4에 소개된 관찰자 패턴에서 볼 수 있습니다.
두 번째 매개변수는 이벤트 유형을 나타내는 문자열로, 이벤트 모델의 사양에 따라 이벤트 에이전트 이름은 "on" 이벤트 유형입니다. 위의 예에서 이벤트 유형은 signalchange이고 해당 이벤트 에이전트는 onsignalchange입니다.
세 번째 매개변수는 이벤트 수신자에게 전달되는 매개변수를 결정하는 이벤트 매개변수 객체입니다. 위의 예에서는 이벤트 발생 시 현재 입력을 각각 나타내는 세 가지 속성인 input을 전달합니다. , 타이밍 및 출력 버퍼 값.
dispatchEvent 함수 자체의 내용은 매우 간단합니다. 단지 수신자의 이벤트 에이전트가 호출되고 이벤트 매개변수가 이벤트 에이전트에 올바르게 전달되는지 확인하는 것뿐입니다. 이벤트 프록시가 이벤트 매개변수를 처리하는 방법은 중요하지 않습니다.

3 이벤트 프록시 및 이벤트 등록

이벤트 처리 모드에서 이벤트 프록시에 대한 이벤트 처리 기능을 지정하는 과정을 이벤트 등록이라고 합니다. 위의 예에서 diff10.onsignalchange는 매우 간단한 이벤트 프록시이며 이벤트 등록 프로세스도 매우 간단합니다. 직접 할당으로 완료됩니다.
실제로 디자인에 따라 이벤트 에이전트는 DOM-level-2의 addEventListener 및 RemoveEventListener와 같은 더 복잡한 등록 방법을 가질 수도 있습니다. 또한 하나의 이벤트 에이전트에 대해 여러 이벤트 등록을 지원하기 위해 유사한 이벤트 등록 방법을 구현할 수도 있습니다. 이벤트 이벤트 처리 방법.이를 구현하기 위해 이벤트 인터페이스를 개선하고 위의 예를 다음과 같이 수정합니다.

function EventManager(owner)
{
owner = owner || this; this.dispatchEvent = function(eventType, eventArgs)
{
var events = owner["on" eventType]
if(events && typeof(events) == "function")
events = [이벤트];
if(소유자 && 이벤트)
{
for(var i = 0; i {
setTimeout( (function( i){return function(){events[i](eventArgs)}
  })(i), 1
  )
  }
 }
}

.addEventListener = 함수(eventType, 클로저)
{
if(owner["on" eventType] == null)
{
owner["on" eventType] = []; }
var events = owner["on" eventType];
if(events && typeof(events) == "function")
events =
events.push(closure) ;
}

this.removeEventListener = function(eventType, closure)
{
var events = owner["on" eventType]
if(events && typeof(events) == "함수")
events = [events];

for(var i = 0; i {
if(events[i] = = 클로저)
events.splice(i, 1); }
}
}

functionrandomSerials(len)
{
functionrandomSignal()
{
return Math.random() > 0.5 ?
}
var ret = []
for(var i = 0; i {
ret.push(randomSignal());
} return ret
}

function Differ(obl)
{
var buffer = new Array(obl) ;
var time = 0;

EventManager.call(this); //EnventManager 구성 요소 적용

this.readBuffer = function()
🎜> var buf = 버퍼;

버퍼 = new Array(obl);
시간 = 0;

return buf; = function()
{
return obl;
}

this.input = function(serials)
{
for(var i = 1; i {
var signal = Math.abs(serials[i] - serials[i - 1])
buffer[time % obl] =
if(signal)
this .dispatchEvent("signalchange",
{input:serials, time:time, buffer:buffer.slice(0)})
} }
}

var inputSerials(20);
alert(inputSerials);
var diff10 = new Differ(20)
diff10.input(inputSerials)
alert(diff10.readBuffer() );

var eventHandler1 = function(eventArgs){
경고(eventArgs.time);
}

var eventHandler2 = function(eventArgs){
경고(eventArgs) .buffer);

diff10.addEventListener("signalchange",eventHandler1);
diff10.addEventListener("signalchange",eventHandler2)
diff10.input(inputSerials); 🎜>
diff10.removeEventListener("signalchange",eventHandler1);

위의 예에서는 EventManager 유형을 생성하고 이에 대한 세 가지 개체 메서드를 정의했습니다. dispatchEvent 메서드는 이전 예제와 매우 유사합니다. . 이벤트를 전달하는 데 사용되는 반면, 다른 addEventListener 및 RemoveEventListener는 이벤트 처리 기능을 등록 및 등록 취소하는 데 사용됩니다.
Differ 유형에서는 EventManager.call(this)을 통해 EventManager 유형 인스턴스를 Differ 프로토타입에 적용합니다(이 문제의 심층 메커니즘은 나중에 자세히 설명합니다). 그런 다음 this.dispatchEvent를 호출하여 이벤트를 전달합니다.
Differ 인스턴스의 onsignalchange 이벤트 프록시에 대한 이벤트를 등록하면 표준 DOM 이벤트 모델과 매우 유사하다는 것을 알 수 있습니다.
diff10.addEventListener("signalchange",eventHandler1)
diff10 .addEventListener(" signalchange",eventHandler2);
diff10.removeEventListener("signalchange",eventHandler1);

이 예제를 실행하면 diff10에 의해 트리거되는 이벤트라는 흥미로운 사실을 발견할 수 있습니다. input(inputSerials); EventHandler1 및 eventHandler2가 실행되지 않았으나 eventHandler2만 실행되었습니다. 이유는 다음과 같습니다.
diff10.removeEventListener("signalchange",eventHandler1); 이벤트 메커니즘은 "비동기 콜백" 메커니즘이므로 나중에 동기화 및 비동기 문제에 대해 논의하겠습니다.

4 표준 모드: 이벤트 발송 및 수신

이벤트 처리 모드에서는 이벤트 발송자가 메시지 전송을 담당하고, 이벤트 수신자가 메시지 처리를 담당합니다. . 이전 예에서는 동일한 개체(Differ)에 의해 수행되었습니다.
그러나 실제로 이벤트 처리 모드에서는 메시지 전송 및 수신이 동일한 개체에 의해 완료될 필요가 없습니다. 일부 모드에서는 서로 다른 개체이며, 그 중 가장 일반적인 것은 "관찰자" 모드입니다. , 차동 시스템의 예는 아래 관찰자 모드로 다시 작성되었습니다.

function dispatchEvent(owner, eventType, eventArgs)
{
if(owner && owner["on" eventType])
setTimeout(function(){owner["on" eventType](eventArgs)}, 1)
}

functionrandomSerials(len)
{
functionrandomSignal()
{
return Math.random() > 0.5 ? 1 : 0;
}
var ret = []
for(var i = 0; i { ret.push(randomSignal());
}
return ret
}

function DifferObserver(differ)
{
this.differ = Different ;
Difference.setObserver(this);

function Differ(obl)
{
var buffer = new Array(obl)
var time = 0 ;
var 관찰자 = null;

this.input = function(serials)
{
for(var i = 1; i {
var signal = Math.abs(serials[i] - serials[i - 1]); buffer[time % obl] = signal;
if(signal)
dispatchEvent(observer, "signalchange) " , {sender:this, input:serials, time:time, buffer:buffer.slice(0)});
}
}

this.setObserver = function(obs)
{
관찰자 = obs;
관찰자.readBuffer = function()
{
var buf = buffer;

buffer = new Array(obl); 0 ;

return buf;
}
관찰자.bufferSize = function()
{
return obl; var inputSerials(20); >alert(inputSerials);
var diff10 = new Differ(20);
diff10.input(inputSerials);
var diffObs = new DifferObserver(diff10)
alert(diffObs.readBuffer() );

diffObs.onsignalchange = function(eventArgs)
{
if(diff10 == eventArgs.sender)
Alert(eventArgs.time)

diff10.input(inputSerials);

위 예제의 이벤트 발송자는 Differ 유형이고 이벤트 수신자는 DifferObserver 유형입니다. 따라서 이벤트에 등록된 에이전트는 In의 속성입니다. 전송된 이벤트 매개변수에 이벤트의 실제 전송 개체를 참조하는 sender 속성을 추가합니다.

원본 텍스트: http://bbs.51js.com/thread -69808-1-1.html by 유잉

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.