2012-08-02 19 views
5

Duplicar posible:
In Javascript, can you extend the DOM?Cómo extender DOM elemento como una clase (sin jQuery)

Estoy tratando de agregar métodos y propiedades al elemento. No está listado como una clase global. Puedo extiendo cadena como esta:

String.prototype.dosomething = function { ... }; 

trato como esto (que es más grande, este es el básico):

function $id(str){ 
    this.element = document.getElementById(str); 
    return element; 
} 
var myElem = $id('myId'); // WORKS !!! 
$id.prototype.dosomethig = function (... }; 
var myValue = $id('myId').dosomething(); // DOESN'T WORK !!! 

Trato de otras maneras pero el punto es siempre la misma, cuando intenta extender la clase, no funciona. Hay alguna manera de evitar esto? Sé que jQuery hace esto, pero quiero hacer mi propio trabajo. Si pueden, puedo ... ¿no?

Editar: A continuación un código que ya están trabajando en Safari y Firefox ...

Element.prototype.pos = function(){ 
    var curleft = this.offsetLeft; 
    var curtop = this.offsetTop; 
    var scrleft = this.scrollLeft; 
    var scrtop = this.scrollTop; 
    var pElement = pElementScr = this.offsetParent 
    while(pElement){ 
     curleft += pElement.offsetLeft; 
     curtop += pElement.offsetTop; 
     pElement = pElement.offsetParent; 
    } 
    while(pElementScr){ 
     scrleft += pElementScr.scrollLeft; 
     scrtop += pElementScr.scrollTop; 
     pElementScr = pElementScr.offsetParent; 
    } 
    return {x:this.offsetLeft, y:this.offsetTop}; 
} 

Se da la posición de un div incluso interior de una gran cantidad de otros divs. Trataré de probar en IE8, después de resolver muchos otros problemas de mi biblioteca.

+2

Debe leer http://perfectionkills.com/whats-wrong-with-extending-the-dom/ –

+1

yo sepa, jQuery no hace esto. Proporcionan una envoltura, pero evitan tocar los prototipos DOM. – tucuxi

Respuesta

4

En Firefox, Chrome y IE8 + elementos heredan de Element.prototype por lo que debe hacer:

Element.prototype.doSomething = function() { 
    alert("hello"); 
}; 

La extensión de prototipos de acogida es muy frágil y no se recomienda, pero debe estar bien si sólo están jugando. La razón principal es que la especificación DOM no especifica implementaciones prototípicas, pero solo las interfaces, elem.appendChild() deberían funcionar, no tiene que estar en algún prototipo.


Este:

function $id(str) { 
    this.element = document.getElementById(str); 
    return element; 
} 

sólo funcionaba debido al comportamiento no deseado que this se refiere al objeto global cuando se invoca una función sin ningún contexto del objeto (Debe simplemente hacen generará un error en el simple vista de this, aunque el modo estricto algo lo arregla estableciéndolo en undefined). Está creando una variable global element (ya que las asignaciones de propiedades al objeto global se convierten en variables globales) y luego devuelve la variable global.

+0

¿Podría explicar por qué es frágil? –

+0

@ srini.venigalla Consulte el comentario de FelixKling a su pregunta – Esailija

+0

Estoy de acuerdo - esto es muy frágil y debe evitarse – tucuxi

0
$id('myId').dosomething() 

$ id ('myId') es un elemento.

No tiene una función llamada doSomething en 'Element', la tiene en $ id, que es una función. En realidad, ¿qué sucede cuando agrega una función a una función? ¿Es posible?

+0

No asigna una función a una función, la asigna a '$ id.prototype.dosomethig' y' $ id.prototype' es un objeto. Pero, por supuesto, dado que las funciones son objeto, pueden tener propiedades arbitrarias. –

+0

@Felix right .. $ id devuelve un elemento, le agregó una función, luego una instancia creada para 'myId', ¿por qué no obtiene la extensión? –

+0

Devuelve 'element' que en realidad debería arrojar un error porque no está definido. Él tiene que devolver 'this' de' $ id'. –

0

En primer lugar, extender DOM es a menudo (léase: siempre) una mala elección. Si desea escribir código rápido entre navegadores, no debe extender DOM u otros objetos nativos (Objeto, Cadena ...). La extensión de objetos nativos también puede causar problemas de compatibilidad con bibliotecas, etc.Si quieres saber más sobre el tema, me gustaría sugerir que eche un vistazo a este excelente entrada en el blog: http://perfectionkills.com/whats-wrong-with-extending-the-dom/

Si apoyando las versiones antiguas de IE (IE6 & & 7) no es importante para ti, entonces este es lo que quiere:

Element.prototype.doSomething = function() { 
    // Your code here 
}; 

En su ejemplo, el problema es que $ id devuelve un elemento. Su "doSomething" está adjuntado a la función $ id, no al elemento que devuelve.

Hacer esto funciona:

function $id(str){ 
    this.element = document.getElementById(str); 
    return this; 
} 
+0

Bueno. Esto resuelve casi todo SI funciona en IE8. No intento la compatibilidad con versiones anteriores. Es curioso que ninguna de mis referencias js enumera a Element como una clase. – Gustavo

1

En lugar de extender el objeto DOM, por qué no lo envuelve, algo así como jQuery hace.

var myLib = { 
    addWrapper: function (id) { 
     return new this.WrapperClass(document.getElementById(id)); 
    }, 
    WrapperClass: function (element) { 
     this.element = element; 
    } 
}; 
MyLib.WrapperClass.prototype.someMethod = function() { 
    alert(this.element); 
} 

var wrappedElement = myLib.addWrapper('someid'); 
wrappedElement.someMethod(); 
+0

Nunca trabajo de esa manera, lo intentaré. – Gustavo

Cuestiones relacionadas