Home >Web Front-end >JS Tutorial >javascript event model code_javascript skills

javascript event model code_javascript skills

WBOY
WBOYOriginal
2016-05-16 19:11:29930browse

This section discusses the topic of event processing in a little more depth. If you don’t quite understand concepts such as patterns, closures, and object-oriented, you might as well wait until you finish reading the relevant content and then come back to read it. I believe you will learn a lot. Harvest.

1 Event processing mode

In the field of programming, "event processing" is a mode. When an object changes state due to external influence, the state change is notified through messages. Give this object or a related object and let it perform the corresponding action. This is the basic principle of event processing. The object responsible for notifying state changes is called a "message", and the attribute that performs the response action is called an "event agent".
For example, the following is a simple event processing pattern application:

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

function randomSerials(len)
{
function randomSignal()
{
return Math.random() > 0.5 ? 1 : 0;
}
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;

buffer = new Array(obl );
time = 0;

return buf;
}

this.bufferSize = function()
{
return obl;
}

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(this, "signalchange",
{input:serials, time:time, buffer: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);

In the above example, the function dispatchEvent is responsible for dispatching events, and onsignalchange is the event proxy , in this differential system diff10, when the level of the input signal changes (from 0 to 1 or from 1 to 0), the corresponding event onsignalchange is triggered, and the current input signal, timing and current output buffer are passed as event parameters Enter the event handler.

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

is the event handler specified by the programmer, here we Prints out the input signal timing when the input level changes.

2 Definition of user event interface

In the previous example, we only defined a function dispatchEvent for dispatching events, but it can also be regarded as a complete user event interface. Now let’s review this function and figure out what it does:

function dispatchEvent(owner, eventName, eventArgs)
{
if(owner && owner["on" eventName] )
     setTimeout(function(){owner["on" eventName](eventArgs)}, 1); The object specifies the "owner" of this event, that is, who receives and is responsible for processing this event. In the above example, the owner is the Differ object itself, which is
dispatchEvent(this, "signalchange", {input:serials, time:time, buffer:buffer});
The passed in owner parameter is this, In fact, the event pattern allows other types to be the owners of event dispatch. Especially in some specific patterns, usually the initiator of the event and the receiver of the event may not be the same object. This can be seen in the observer pattern introduced in Section 4.
The second parameter is a string representing the event type, which determines the name of the event agent. According to the specification of the event model, the name of the event agent is "on" event type. For example, in the above example, the event type is signalchange. , the corresponding event agent is onsignalchange.
The third parameter is an event parameter object, which determines the parameters passed to the event receiver. In the above example, it passes the three attributes input, time and buffer, which respectively represent the current input when the event occurs. Sequence, timing, and output buffer values.
The content of the dispatchEvent function itself is very simple. It just ensures that the event agent of the receiver is called and the event parameters are correctly passed into the event agent. As for how the event proxy handles the event parameters, it doesn't care.

3 Event proxy and event registration

In the event processing mode, the process of specifying event processing functions for the event proxy is called event registration. In the above example, diff10.onsignalchange is an extremely simple event proxy, and its event registration process is also extremely simple - it is completed by direct assignment.
In fact, depending on the design, event agents can have more complex registration methods, such as addEventListener and removeEventListener of DOM-level-2. We can also implement similar event registration methods to support registering multiple events for one event agent. Event event handling method.In order to implement it, we improve the event interface and modify the above example as follows:

function EventManager(owner)
{
owner = owner || this;

this.dispatchEvent = function(eventType, eventArgs)
{
var events = owner["on" eventType];
if(events && typeof(events) == "function")
events = [events];
if(owner && events)
{
for(var i = 0; i {
setTimeout(
(function(i){return function(){events[i](eventArgs)}
  })(i), 1
  );
  }
 }
}

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

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

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

function randomSerials(len)
{
function randomSignal()
{
return Math.random() > 0.5 ? 1 : 0;
}
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); //apply EnventManager Component.

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

buffer = new Array(obl);
time = 0;

return buf;
}

this.bufferSize = function()
{
return obl;
}

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

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

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

var eventHandler2 = function(eventArgs){
alert(eventArgs.buffer);
}

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

diff10.removeEventListener("signalchange",eventHandler1);

In the above example, we created an EventManager type and defined three object methods for it. The dispatchEvent method is very similar to the previous example. It is used to dispatch events, while the other addEventListener and removeEventListener are used to register and unregister event processing functions.
In the Differ type, we apply EventManager type instances to the Differ prototype through EventManager.call(this); (the deep mechanism of this issue will be discussed in detail later). Then call this.dispatchEvent to dispatch the event.
When registering an event for the onsignalchange event proxy of the Differ instance, you will find that it is very similar to the standard DOM event model:
diff10.addEventListener("signalchange",eventHandler1);
diff10.addEventListener(" signalchange",eventHandler2);
diff10.removeEventListener("signalchange",eventHandler1);

After running this example, you will find an interesting thing, which is the event triggered by diff10.input(inputSerials); EventHandler1 and eventHandler2 were not executed, but only eventHandler2 was executed. The reason is:
diff10.removeEventListener("signalchange",eventHandler1);
is executed before the event is triggered. This is because the event mechanism is a "Asynchronous callback" mechanism, we will discuss synchronization and asynchronous issues later.

4 Standard mode: event dispatching and receiving

In the event processing mode, the dispatcher of the event is responsible for sending the message, and the receiver of the event is responsible for processing the message. In the previous example, they are done by the same object (Differ).
However, in fact, in the event processing mode, the sending and receiving of messages is not required to be completed by the same object. In some modes, they are different objects, the most common of which is "observer" mode, the example of the differential system is rewritten as the observer mode below:

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

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

function DifferObserver(differ)
{
this.differ = differ ;
differ.setObserver(this);
}

function Differ(obl)
{
var buffer = new Array(obl);
var time = 0;
var observer = 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)
{
observer = obs;
observer.readBuffer = function()
{
var buf = buffer;

buffer = new Array(obl);
time = 0 ;

return buf;
}
observer.bufferSize = function()
{
return obl; 🎜>
var inputSerials = randomSerials(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);

The event dispatcher in the above example is of type Differ, and the event receiver is of type DifferObserver. So the agent registered for the event is the property of DifferObserver. In the sent event parameters, we add an attribute sender, which refers to the actual sending object of the event

Original text: http://bbs.51js.com/thread -69808-1-1.html by Yueying

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn