More elegant event triggers compatible with _javascript tips

Source: Internet
Author: User
All kinds of problems

Do the low-level interface compatibility, nothing more than using if, to determine the client support which interface problem. The most famous example is the event:
Copy Code code as follows:

var addevent = function (e, what, how) {
if (E.addeventlistener) E.addeventlistener (what, how, False)
else if (e.attachevent) e.attachevent (' on ' + What, how)
}

Here you consider two things you might encounter when you bind an event to an element-the standard and the interface of the consortium DOM and the interfaces that DHTML provides. Of course, this example is still rough, but enough to explain the problem.

The original approach was to invoke a live judgment at the compatibility layer and enter the appropriate if branch. Obviously, this method of "on-site judgment" is not efficient. Later on, people used this approach:
Copy Code code as follows:

if (MSIE) {
addevent = function (e, what, how) {
E.attachevent (' on ' + What, how);
}
} else {
addevent = function (e, what, how) {
E.addeventlistener (what, how);
}
}

The addevent is bound to different code after one judgment, thus eliminating the branch judgment at run time.

Unfortunately, this is not a small problem. First of all, "adopt attachevent" and "Client is MSIE" binding together is a very outdated idea. What if Microsoft's conscience finds out someday? This is happening now.--IE9 explicitly supports the DOM interface, and even DOM3 supports it. As a result, the "Conscience Discovery" Act destroys many front-end libraries, and they must be forced to modify the code (as IE8 did). And this does not take into account "unknown clients"--as far as I know, Google's release of Chrome has resulted in many class libraries rewriting code.
Feature detection

What the hell is that supposed to do? Feature detection minimizes the hassle of a "new client"--a set of code that is defined during class library initialization to detect client-owned attributes and bind the class library code with this set of instrumentation values:
Copy Code code as follows:

var Supportsaddeventlistener =!! (Checkerelement.addeventlistener);
if (Supportsaddeventlistener) {
addevent = function (e, what, how) {
E.addeventlistener (what, how);
}
else if (supportsattachevent) {
addevent = function (e, what, how) {
E.attachevent (' on ' + What, how);
}
}

Attribute detection is essentially decoupling the "use of a client" and "Support for an attribute"--Let the IF branch be judged directly against "attribute availability" (interface consistency), thereby eliminating the "good deed" caused by the client manufacturer's "conscience discovery". In fact, this is also in line with the historical trend of the election-when the standard interface gradually become popular, the client gradually "token consistent", why not make a consistent layer of compatibility interface?
Fall

Let's look at the code again. Typically, a code that uses feature detection for compatibility is often the case:
Copy Code code as follows:

if (new_interface_detected) {
comp = function () {uses_new_interface};
else if (old_interface_detected) {
comp = function () {uses_old_interface};
} else {
throw new Error (' unadaptable! ')
}

In other words, the process is:

If the client supports a new interface, bind the compatibility layer to the new interface
Otherwise, if the client supports the old interface/inconsistent interface, bind the compatibility layer to the old interface
Otherwise, if you can, give the wrong feedback.

That is, the compatibility layer program is "off" from the sky, if the client supports the "Advanced" feature (new interface, standard interface) to "catch"-the compatibility layer has a home, otherwise continue down--oh, the old interface to catch, use the old interface; If no one catches it, then----pop--fell to the ground, And with the last breath shout: "You use the client too small, I take you have no way!" ”

What does it look like?

In fact, if you understand the mechanism of JavaScript object systems, you can analogy: this is not a prototype! The prototype system uses the drop-looking for a member, if it is defined in the object, to return it, or go up the prototype chain (yes, this time it is up), so repeat, until it is true that even the prototype chain is at the end of the undefined.

Do what you say! This is also the case with Addevent. First, we define an empty drive, which contains nothing:

var nulldriver = {}

Then, you create an object and point the prototype chain to it. In the ECMA V5 era, we can use object.create, unfortunately, now there are more than N old client (otherwise do what compatible AH), so their own craft functions:
Copy Code code as follows:

var derive = Object.create? Object.create:function () {
var T = function () {};
return function (obj) {
T.prototype = obj;
return new T
}
}()

This usage may seem strange to you, but it does not work as well as it is slow--it can reach half the object.create. We're going to use this derive to get started:
Copy Code code as follows:

var dhtmldriver = derive (Nulldriver);
var dhtmldriverbugfix = derive (Dhtmldriver);

The bugfix here is a special driver for some "bugs" and special situations. Here you can ignore it. Okay, what's addevent in DHTML?
Copy Code code as follows:

if (supportsattachevent) {
Dhtmldriver.addevent = function (e, what, how) {
E.attachevent (' on ' + What, how)
}
}

And then what? At the forefront of the prototype chain should be the standard driver of the world's standards, write it!
Copy Code code as follows:

var w3cdriver = derive (Dhtmldriverbugfix);
var w3cdriverbugfix = derive (W3cdriver);

if (Supportsaddeventlistener) {
W3cdriver.addevent = function (e, what, how) {
E.addeventlistener (What, how)
}
}

Finally, we put something up to make the last call interface. (Because W3cdriverbugfix is too ugly ...) )

var driver = derive (W3cdriverbugfix);

And then call it well. Look, this makes the scary branch judgments simple and effective, But fallback: in support of AddEventListener, addevent is equivalent to calling W3cdriver.addevent, and dropping to the bottom on clients that do not support addeventlistener, such as invoking Dhtmldriver.add Event. In addition, it is also easy to perform bugfix-you can hook up in a dedicated "bugfix" layer, and the original layer is unaffected.
Wait, inherit so many layers

Is it going to be slow? Sure, the deep prototype chain will be slow, but I have a way. Remember what happens when you write to an object's properties?
Copy Code code as follows:

var ego = function (x) {return x}
For (var all in driver) {
if (! (each in nulldriver)) {
Driver[each] = ego (Driver[each])
}
}

Yes, the original high in the prototype chain above the method will "wow" a bit fell to the bottom! This time not to go up the prototype chain, directly from the bottom of the property can be obtained. The reason for using the ego function here is to prevent some browsers from "tuning out" the code here.
Summarize

While this is compatible, the essence of it is in linguistic features--using prototypes to inherit, and we can do this frustrating operation gracefully. Yes, the beauty of the framework should not be just in appearance, but inside--even the most annoying interior--to be elegant.

The technology here can be found in the dess.
From: typeof.net

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.