2011-11-25 10 views
9

Sorprendentemente, this Apple page tiene Element.prototype igual a undefined, así que no puedo usar este awesome snippet of code.¿Por qué no se define Element.prototype?

¿Hay alguna razón para hacer esto?

+3

'Element.prototype === undefined' es una comparación. Esto no hace nada. – Tomalak

+1

No estoy seguro de por qué este es el caso, pero podría simplemente usar HTMLElement en lugar de Element en ese fragmento. – pradeek

+0

Puede encontrar [este artículo] (http://perfectionkills.com/whats-wrong-with-extendiendo-el-dom/) de interés. – smendola

Respuesta

8

Apple está usando el marco coherente JS que tiene esta block of code:

// Trick picked up from Prototype to get around IE8's fixed Element & Event 
(function() { 
    var element = this.Element; 
    this.Element = {}; 
    Object.extend(this.Element, element || {}); 
}).call(window); 

window.Element es originalmente una función, pero está siendo sustituido y ampliado con un objeto regular. Solo las funciones tienen propiedades .prototype.

Solución:

La cadena de prototipos para cualquier elemento HTML parece ser:

  • tipo de elemento específico (HTMLBodyElement, HTMLDivElement, etc ...)
  • HTMLElement
  • Elemento
  • Nodo
  • objeto

Usted debe ser capaz de adjuntar el código hace referencia al prototipo a cualquiera de los objetos llamativos de la cadena y conseguir el estilo de un elemento HTML. No recomendaría esto en el código de producción ya que la modificación de objetos como ese generalmente es considered harmful, pero si solo está tratando de exportar un estilo desde otro sitio web, debería funcionar bastante bien.

Object.prototype.exportStyles = (function() { //Works if you use it on an element, the code will protect you from yourself if you try to use it on regular objects. 
HTMLElement.prototype.exportStyles = (function() { //Safer because it is farther down the inheritance line, affecting fewer objects. 
                 //Avoiding name collisions and other surprises. 
0

Parece que han sobrescrito el valor predeterminado de Elemento y le asignaron el valor de una instancia de objeto, que de forma predeterminada no tiene la propiedad de prototipo. Pruebe lo siguiente en la consola:

var a = {}; 
console.log(typeof a.prototype === 'undefined'); 

function abc() {} 
Element = abc; 
var b = new Element(); 
console.log(typeof b.prototype === 'undefined'); 

No hay una razón universal para anular las funciones integradas, por lo que supongo que es probablemente porque pensaban que tendría más sentido semántico (como parece el Elemento objeto se utiliza para la manipulación DOM) y no tienen la posibilidad de entrar en conflicto con bibliotecas externas, por lo que generalmente se desaconseja.

1

Además de lo que Dennis explicó así, la solución más fácil de evitar el cambio de los objetos incorporados (que la gente parece que les encanta a hacer una y otra vez, como hizo Apple en su sitio y Luc1245 hizo en el post mencionado)

Una alternativa no intrusiva es ejecutar algo como:

function exportStyles = (function (/* what Luc1245 posted */; 

exportStyles.apply(/* this */ theElement, /* args */ []); 
+0

Debe agregar una respuesta como esa a la pregunta vinculada. –

Cuestiones relacionadas