2010-04-26 2 views
4

Как создать чистый JavaScript (без использования каких-либо библиотек) плагин, который выглядит как:JavaScript Создание плагин

document.getElementById('id').myPlugin(); 

Как JQuery?

+0

стоит отметить, что синтаксис вы предложили не совсем * как JQuery * и по очень веским причинам некоторые из них fredrik разработали на –

ответ

2

Вы можете создать свою собственную оболочку (похожую на jQuery), и это позволит вам обойти все обсуждаемые проблемы с расширением DOM напрямую.

myWrapper = (function(){ 

    function NodeList(elems) { 

     this.length = 0; 
     this.merge(this, elems.nodeType ? [elems] : elems); 

    } 

    function myWrapper(elems) { 
     return new NodeList(elems); 
    } 

    myWrapper.NodeList = NodeList; 

    NodeList.prototype = { 
     merge: function(first, second) { 

      var i = first.length, j = 0; 

      for (var l = second.length; j < l; ++j) { 
       first[i++] = second[j]; 
      } 

      first.length = i; 

      return first; 

     }, 
     each: function(fn) { 

      for (var i = -1, l = this.length; ++i < l;) { 
       fn.call(this[i], this[i], i, l, this); 
      } 

      return this; 

     } 
    }; 

    return myWrapper; 

})(); 

И вы можете добавить свои собственные методы, например, так:

myWrapper.NodeList.prototype.myPlugin = function() { 
    return this.each(function(){ 
     // Do something with 'this' (the element) 
    }); 
}; 

Использование:

myWrapper(document.getElementById('id')).myPlugin(); 
0

Зачем использовать этот формат? Я думаю,

myPlugin(document.getElementById('id')) 

, вероятно, было бы яснее любому, кто поддерживает код. Я не большой поклонник monkey patching.

1

Я согласен с spender. Вы действительно не должны возиться со стандартными элементами JavaScript. Лучше сделать для него обертку (то есть $, как использует jQuery). Если вы хотите сделать стенографию для получения элементов, сделайте метод-обертку и продолжите это. Это упростит работу кода. Поскольку, если вы изменяете стандартную функциональность в JavaScript, это может помешать стандартным поведением. Это может привести к некоторой действительно сложной отладке. Лучше сделать функцию обертки, делать с ней все, что вам нравится.

Но, несмотря на это, если вы хотите возиться со стандартным поведением, вы всегда можете привязать новые методы к стандартным объектам с использованием прототипов. Например:

Object.prototype.myMethod = function() {} 
3

Я смущенно говорю, что вы не можете. В конце концов, Prototype.js сделал.

Для того, чтобы позвонить по телефону getElementById('id').someNewMethod(), вам нужно будет «продлить» прототип объекта getElementById, который является Element. В некоторых браузерах вы действительно можете сделать это:

Element.prototype.someNewMethod= function() { 
    alert('hello from a '+this.tagName); 
}; 

document.body.someNewMethod(); // hello from a BODY 

Однако это весьма сомнительно. Прототипирование на собственные объекты JavaScript, такие как Object или String, потенциально опасно, что с именами сталкивается между браузерами и библиотеками, но Element и все другие объекты DOM могут быть объектами «хоста», которые не позволяют прототипировать.

Даже если объекты DOM реализуется с полным собственным интерфейсом JavaScript, никакая спецификации говорит, что Element должен выставить прототип/конструктор-функцию при window собственности/глобальной переменной вызываемой Element.

В действительности это работает в Firefox, Webkit и Opera и IE начиная с версии 8 и выше. Однако это нестандартно, не все браузеры делают все те же интерфейсы доступными под всеми одинаковыми именами, и он не будет работать в IE6, IE7 или многих более мелких браузерах (например, мобильных браузерах).

Prototype имел резерв для этих браузеров: он попытался бы увеличить каждый экземпляр Element с новыми членами, когда он впервые увидел каждый элемент. Но у этого были чрезвычайно грязные побочные эффекты, и многие считают их ошибкой; Prototype 2.0 won't try to extend DOM interfaces.

Возможно, в будущем кто-то свяжет это и сделает его надежной частью среды браузера. Но сегодня это не так, поэтому вам следует продолжать использовать другие, clunkier методы, такие как функции обертки.

+0

Хороший ответ. Но просто из любопытства не следует подделывать его, используя какой-то настоящий изворотливый код javascript. Сначала сохранить исходный getElements и перезаписать его? Реальное страшное решение, но должно работать. :) – fredrik

+1

Да, вы могли бы: по сути, обернуть всю DOM в свою собственную реализацию. Проблема в том, что (а) она будет медленной, и (б) многие DOM полагаются на свойства, а не на методы: например. 'document.body.firstChild' вообще не вызывает никаких вызовов. Вы не могли определить свои собственные getter/seters в JavaScript до ECMAScript Fifth Edition, поэтому вы не можете иметь динамические свойства, которые работают с кросс-браузером и даже * с * свойствами, которые вы не можете эмулировать NodeList/array-like very well , – bobince

+1

Таким образом, либо вам нужно будет заполнить все связанные 'firstChild' и' nextSibling' и 'parentNode' и каждое другое свойство для всей DOM во время запуска и при каждой модификации документа (eek !), или вам нужно изменить интерфейс, например. требуя от пользователей писать 'document.getBody(). getFirstChild()'. Но если вы меняете интерфейс, вы все равно теряете преимущество родной DOM, поэтому вы можете просто придумать свой собственный интерфейс (например, jQuery и др.). – bobince

Смежные вопросы