2009-04-23 7 views
22

En Javascript, puede extender las clases existentes mediante el uso de su objeto prototipo:En Javascript, ¿puedes extender el DOM?

String.prototype.getFirstLetter = function() { 
    return this[0]; 
}; 

¿Es posible utilizar este método para extender los elementos DOM?

+6

Puedes. Pero probablemente no debería :) http://perfectionkills.com/whats-wrong-with-extending-the-dom/ – kangax

+1

En realidad, las cosas han cambiado en los últimos tres años: https://github.com/nbubna/mind -hacking/blob/gh-pages/extending-the-dom.md –

Respuesta

20

puede ampliar el DOM utilizando el prototipo del Elemento. Sin embargo, esto no funciona en IE7 y versiones anteriores. Necesitará extender el elemento específico, uno a la vez. La biblioteca Prototype hace esto. Recomiendo consultar el source para ver exactamente cómo se hace.

+0

Tenga en cuenta que esto solo debería ser necesario para IE6 e IE7, ya que IE8 es compatible con esto. Vea http://msdn.microsoft.com/en-us/library/dd282900(VS.85).aspx. –

+0

ah - naturalmente solo probé en FFx gracias por la propina. – nickf

+0

Sí, IE8 ha hecho grandes progresos con la manipulación de DOM, pero el soporte completo no está muy arriba de mi lista de prioridades ahora mismo – geowa4

18

Encontré la respuesta justo cuando estaba escribiendo la pregunta, pero pensé en publicar de todos modos para compartir la información.

El objeto que necesita ampliar es Element.prototype.

Element.prototype.getMyId = function() { 
    return this.id; 
}; 
1

Sí, puede, pero se recomienda encarecidamente que no lo haga.

Si invalida algo que otra biblioteca espera ser el original u otra biblioteca sobrescribió algo que usted esperaba ... ¡caos!

Es una buena práctica mantener su código en su propio espacio de nombre/alcance.

7

No debería extender nada directamente (con "cualquier cosa" me refiero a objetos DOM nativos) - eso solo conducirá a cosas malas. Además de volver a extender cada elemento nuevo (algo que tendrías que hacer para soportar IE) agrega una sobrecarga adicional.

por qué no tomar el enfoque jQuery y crear un contenedor/constructor y se extienden que en lugar:

var myDOM = (function(){ 
    var myDOM = function(elems){ 
      return new MyDOMConstruct(elems); 
     }, 
     MyDOMConstruct = function(elems) { 
      this.collection = elems[1] ? Array.prototype.slice.call(elems) : [elems]; 
      return this; 
     }; 
    myDOM.fn = MyDOMConstruct.prototype = { 
     forEach : function(fn) { 
      var elems = this.collection; 
      for (var i = 0, l = elems.length; i < l; i++) { 
       fn(elems[i], i); 
      } 
      return this; 
     }, 
     addStyles : function(styles) { 
      var elems = this.collection; 
      for (var i = 0, l = elems.length; i < l; i++) { 
       for (var prop in styles) { 
        elems[i].style[prop] = styles[prop]; 
       } 
      } 
      return this; 
     } 
    }; 
    return myDOM; 
})(); 

Entonces usted puede agregar sus propios métodos a través de myDOM.fn ... y se puede utilizar de esta manera:

myDOM(document.getElementsByTagName('*')).forEach(function(elem){ 
    myDOM(elem).addStyles({ 
     color: 'red', 
     backgroundColor : 'blue' 
    }); 
}); 
+11

"No debería extender nada directamente, eso solo conducirá a cosas malas". Te conducirá a cosas buenas si tienes una buena razón para hacerlo y escribe tu código correctamente. Además de los problemas de interoperabilidad, no hay razón para no extender Element.prototype; para otros objetos predeterminados, se puede obtener una gran cantidad de beneficios (consulte agregar métodos de formato a Date.prototype o escaparse a RegExp.prototype). Es una tontería renunciar a prácticas OO perfectamente útiles cuando están disponibles y son útiles. – eyelidlessness

+1

No estamos hablando del lenguaje JavaScript y los patrones de diseño ni nada por el estilo. Esto se trata de DOM: extender los objetos DOM nativos no es una buena idea; sin mencionar el hecho de que no funciona correctamente en todos los navegadores ... – James

+4

Además de la interoperabilidad, ¿por qué no es una buena idea? – eyelidlessness

Cuestiones relacionadas