DOM-shim for all browsers including IE <8
Good day dear harazhiteli.
Many javascript programmers have come across some unsupported DOM JS API functions in some browsers (we will not point with a finger). Surely, many are familiar with the wonderful libraries es5-shim and DOM-shim for solving compatibility problems between different browsers, and DOM-shim also "pulls" the browser to the DOM4 level.
In this article, I will tell you how to make DOM-shim in IE6 and IE7 in order to forget about the existence of these browsers forever.
There is nothing to tell. IE earlier than version 9 does not support a lot of the standard DOM API:
And if IE8 can be “tightened up" by implementing the necessary functionality using DOM-shim , then IE6 and IE7, unfortunately, are not supported by this library (as of 11.24.2011 issues / 29 ) due to the fact that IE <8 does not have Node. prototype.
Actually, the solution is quite obvious and I used it in my projects a year ago, when I just started to study javascript - behavior: url (.htc) [ Introduction to DHTML Behaviors ]. But then I had to abandon this decision, because it really, really slowed down the page loading - I had to wait 30 seconds, after the page loaded for a relatively small page.
After some time, I accidentally stumbled upon information on how to speed up page loading with behavior using behavior every 100 times - it turns out you just need to add lightweight = true and everything will work quite quickly.
Now to make DOM-shim for IE <8 will not be difficult, which I did.
First, we need the original es5-shim and DOM-shim , take them and redo them, fix bugs and improve the emulation of Object.defineProperty :
Instead of just throwing an exception ERR_ACCESSORS_NOT_SUPPORTED, we will check for a special flag and if it is, save the getter and setter under special names.
Because in IE <8 there is no Node.prototype (which is passed to Object.defineProperty), create a special object into which our getters and setters will accumulate:
We will transmit it as usual, just add the “ielt8” flag to the description :
Now we collect all the getters of our shim library into one object. All that remains is to “hang” it on all the elements on the page.
Create the dom-shim.ielt8.htc file:
and add it to all the elements on the page:
And that's all. Now we have Node.classList even in IE6!
The following properties are added similarly:
1. I correct attributes, for this I save the original attributes in a special container at the beginning of the htc script:
So, in IE6, the implementation of behavior is different from IE7: in IE7, the original overrides in the
Therefore, for IE6 we make a separate file.
2. Do not attach behavior to all elements ("*") since in IE <8, it is hung on some unsupported element and an error occurs. To fix it, you just need to specify all the html tags in style:
Link to the library: github.com/termi/ES5-DOM-SHIM
I want to note that my library for DOM-shim is very different from DOM-shim due to the fact that I have been developing it for the last 8 months without knowing anything about DOM-shim ( and even about github :)) A
working example can be downloaded here: github.com/termi/Microdata-JS (download, go to examples / microdataTemplater, open templaterTest.html)
Offer to add what happened in DOM-shim : github.com / Raynos / DOM-shim / issues / 29
update 11/27/2011:
.htc files must be on the same domain as the .html file. For example, for the example.org/index.html file, the .htc file should be on example.org, and for the test.example.org/index.html file on test.example.org. This restriction significantly complicates the use of the library - you can’t just put the .htc file on a static server and forget about it. Be sure to make sure that you have all the necessary .htc files on the same domain as the site.
Same-domain limitation
update 12/19/2011:
Same-domain limitation solution via nginx proxy
Many javascript programmers have come across some unsupported DOM JS API functions in some browsers (we will not point with a finger). Surely, many are familiar with the wonderful libraries es5-shim and DOM-shim for solving compatibility problems between different browsers, and DOM-shim also "pulls" the browser to the DOM4 level.
In this article, I will tell you how to make DOM-shim in IE6 and IE7 in order to forget about the existence of these browsers forever.
Problem
There is nothing to tell. IE earlier than version 9 does not support a lot of the standard DOM API:
- addEventListener
- removeEventListener
- dispachEvent
- classList
- etc.
And if IE8 can be “tightened up" by implementing the necessary functionality using DOM-shim , then IE6 and IE7, unfortunately, are not supported by this library (as of 11.24.2011 issues / 29 ) due to the fact that IE <8 does not have Node. prototype.
Decision
Actually, the solution is quite obvious and I used it in my projects a year ago, when I just started to study javascript - behavior: url (.htc) [ Introduction to DHTML Behaviors ]. But then I had to abandon this decision, because it really, really slowed down the page loading - I had to wait 30 seconds, after the page loaded for a relatively small page.
After some time, I accidentally stumbled upon information on how to speed up page loading with behavior using behavior every 100 times - it turns out you just need to add lightweight = true and everything will work quite quickly.
Now to make DOM-shim for IE <8 will not be difficult, which I did.
Let's get started
First, we need the original es5-shim and DOM-shim , take them and redo them, fix bugs and improve the emulation of Object.defineProperty :
<...>
if (!object.__defineGetter__) {
if(descriptor["ielt8"]) {
object["get" + property] = descriptor["get"];
object["set" + property] = descriptor["set"];
}
elsethrownewTypeError(ERR_ACCESSORS_NOT_SUPPORTED);
<...>
Instead of just throwing an exception ERR_ACCESSORS_NOT_SUPPORTED, we will check for a special flag and if it is, save the getter and setter under special names.
Because in IE <8 there is no Node.prototype (which is passed to Object.defineProperty), create a special object into which our getters and setters will accumulate:
var elementProto = window.HTMLElement && window.HTMLElement.prototype ||
/*ie8*/window.Element && window.Element.prototype ||
/*ielt8*/(window["_ielt8_Element_proto"] = {});
We will transmit it as usual, just add the “ielt8” flag to the description :
Object.defineProperty(elementProto, "classList", {"get" : ..., "ielt8" : true}
Now we collect all the getters of our shim library into one object. All that remains is to “hang” it on all the elements on the page.
Create the dom-shim.ielt8.htc file:
<PUBLIC:COMPONENT lightWeight="true">
<PUBLIC:PROPERTYNAME="classList"GET="getClassList" /><SCRIPT>
getClassList = window._ielt8_Element_proto.getclassList
</SCRIPT></PUBLIC:COMPONENT>
and add it to all the elements on the page:
* {
behavior: url(dom-shim.ielt8.htc)
}
And that's all. Now we have Node.classList even in IE6!
The following properties are added similarly:
- addEventListener
- removeEventListener
- dispatchEvent
- attributes (fixed)
- children (fixed)
- firstElementChild
- lastElementChild
- nextElementSibling
- previousElementSibling
- childElementCount
- querySelectorAll
- querySelector
- insertAfter (non-standard)
- getElementsByClassName
- compareDocumentPosition
- DOCUMENT_POSITION_DISCONNECTED
- DOCUMENT_POSITION_PRECEDING
- DOCUMENT_POSITION_FOLLOWING
- DOCUMENT_POSITION_CONTAINS
- DOCUMENT_POSITION_CONTAINED_BY
Little things
1. I correct attributes, for this I save the original attributes in a special container at the beginning of the htc script:
if(!this._)this._={};
//Save original attributes propertythis._.__ielt8_attributes__=this.attributes;
So, in IE6, the implementation of behavior is different from IE7: in IE7, the original overrides in the
<PUBLIC:PROPERTY NAME="attributes" GET="getAttributes" />
properties are available in the script , and in IE6, they are not available - the getAttributes getter is called immediately. Therefore, for IE6 we make a separate file.
2. Do not attach behavior to all elements ("*") since in IE <8, it is hung on some unsupported element and an error occurs. To fix it, you just need to specify all the html tags in style:
<style>
html,body,div,span,object,iframe,h1,<...все html теги...>,textarea,input,select {
behavior: url(dom-shim.ielt8.htc)
}
</style>
Total
Link to the library: github.com/termi/ES5-DOM-SHIM
I want to note that my library for DOM-shim is very different from DOM-shim due to the fact that I have been developing it for the last 8 months without knowing anything about DOM-shim ( and even about github :)) A
working example can be downloaded here: github.com/termi/Microdata-JS (download, go to examples / microdataTemplater, open templaterTest.html)
Offer to add what happened in DOM-shim : github.com / Raynos / DOM-shim / issues / 29
update 11/27/2011:
Limitations
.htc files must be on the same domain as the .html file. For example, for the example.org/index.html file, the .htc file should be on example.org, and for the test.example.org/index.html file on test.example.org. This restriction significantly complicates the use of the library - you can’t just put the .htc file on a static server and forget about it. Be sure to make sure that you have all the necessary .htc files on the same domain as the site.
Same-domain limitation
update 12/19/2011:
Same-domain limitation solution via nginx proxy