Pull to refresh

Эмуляция DOM.prototype в ИЕ (lte 7)

Reading time3 min
Views1.6K
Как всем известно, в нашем «дорогом» ИЕ версий ниже 8, нету поддержки Element.prototype (а также HTMLElement, Node).


Для начала мы просто создадим функцию Element, и через прототайп добавим нужную нам функцию:
Element = function () {};
Element.prototype.pSib = function() {
  var node = this;
  while (node = node.previousSibling) {
    if (node.nodeType != 3) return node;
  }
  return null;
}
Данная функция ищет previousSibling для элемента, пропуская текстовые ноды!

Создадим паблик метод с помощью behavior:
<PUBLIC:COMPONENT>
  <PUBLIC:METHOD NAME="pSib"
      INTERNALNAME="_pSib" />
  <script type="text/javascript">
    var el = new Element;
    _pSib = el.pSib;
  </script>
</PUBLIC:COMPONENT>

Сохраняем в test.htc и через кондишинал коментс, добавляем в браузер:
<!--[if lte IE 7]>
  <style type="text/css">
    * { behavior: url(test.htc); }
  </style>
<![endif]-->


Дальше мы расширяем createElement, и присваиваем те методы, что мы объявили в бихейворе, каждому элементу:
var __IEcreateElement = document.createElement;
document.createElement = function (tagName) {
  var element = __IEcreateElement(tagName);
  var interface = new Element;
  for (method in interface)
    element[method] = interface[method];
  return element;
}


Исходный код будет таков:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
 <title>IE.prototype</title>
 <meta http-equiv="content-type" content="text/html; charset=windows-1251" />

  <!--[if lte IE 7]>
   <script type="text/javascript">
      Element = function () {};
      var __IEcreateElement = document.createElement;
      document.createElement = function (tagName) {
        var element = __IEcreateElement(tagName);
        var interface = new Element;
        for (method in interface)
          element[method] = interface[method];
        return element;
      }  
   </script>
   <style type="text/css">
     * { behavior: url(test.htc); }
   </style>
  <![endif]--> 
 
 <script type="text/javascript">
    function addLoadEvent(func) {
     var oldonload = window.onload;
     if (typeof window.onload != 'function') { window.onload = func;}
     else {window.onload = function() { if (oldonload) {oldonload();}func();}}
    }   
    
    Element.prototype.pSib = function() {
      var node = this;
      while (node = node.previousSibling) {
        if (node.nodeType != 3) return node;
      }
      return null;
    }
    
    addLoadEvent(function() {
      alert(document.getElementById('testinput').pSib().id);
    });
 </script>
</head>
<body>
  <label for="text" id="testlabel">Enter text</label>
  <input name="text" type="text" id="testinput">
</body>
</html>

* This source code was highlighted with Source Code Highlighter.
addLoadEvent запускает код, после 100% загрузки страницы.

Не забываем, что Element.prototype работает нормально в других браузерах, потому его не нужно выносить в кондишинал коментс ;)

Смотрим простое демо

Tags:
Hubs:
Total votes 9: ↑7 and ↓2+5
Comments18

Articles