El proyecto Vice-versa
Cada navegador tiene alguna característica deseable: puede ser su rendimiento, puede ser algo que "aún no se ha estandarizado", puede ser una característica preparada para ECMAScript 5. El proyecto Vice-versa pretende traer lo bueno de cada navegador a un único archivo JavaScript ligero y que valga para todos los navegadores.
Filosofía
Array.forEach(document.all, function(node, i, all){ // proyecto vice-versa });Como un Ninja JavaScript tengo que tratar diariamente con centenares de problemas diferentes a causa de "esta o aquella" implementación por parte de un navegador. La web está llena de librerías pero a menudo lo que necesitamos hacer requiere usar el navegador "tal cual" y estas librerías puede ayudar o simplemente pueden hacer más lentas las aplicaciones a causa de sobrecargas innecesarias sobre tareas simples o comunes. Estudiando el DOM, que es caótico, a menudo "viajo" entre los sitios de MDC y de MSDN para resolver un problema específico que puede causar muchos dolores de cabeza a causa de "alguna" implementación del estándar W3C que alguien ha olvidado realizar. Al mismo tiempo, teniendo en cuenta que el navegador más usado es el que tiene el motor de JavaScript más lento, siempre intento encontrar soluciones que puedan completar una tarea sin afectar al rendimiento. En la mayoría de los casos, he notado que, ya que otros navegadores son más rápidos y más potentes, tiene sentido traer funcionalidades no estándar a esos navegadores en lugar de implementar, cuando sea posible, una funcionalidad omitida en Internet Explorer. Como ejemplo básico, para convertir un documento XML en una cadena, nos gustaría usar una instancia de XMLSerializer, pero ¿qué problema hay con el atajo del atributo
xml
de Microsoft?// al estilo de otros navegadores (estándar) var xmls = new XMLSerializer; var string = xmls.serializeToString(myXMLDocument); // al estilo de Internet Explorer (no estándar) var string = myXMLDocument.xml;Es más,
document.evaluate
es una característica muy buena, pero la llamada más común a esta función es la siguiente:var xpresult = document.evaluate(XPathSelector, myXMLDocument, null, 0 /* as ANY_TYPE */, null); // En internet explorer hay una función ligeramente diferente: selectNodes var xpresult = myXMLDocument.selectNodes(XPathSelector);La diferencia principal es el número de caracteres necesarios para llamar al método estándar en lugar de el de IE, aunque el resultado es exactamente el mismo durante las iteraciones (donde IE usa
nextNode
, el resto usa iterateNext
). De nuevo, si estamos en Internet Explorer podemos confiar en la propiedad más fea que hayamos visto nunca desde la primera implementación de JScript sonbre el DOM: document.all
. Ahora, ¿por qué demonios nos encanta la "miniaturización" de YUICompressor más gzip
pero preferimos una sintaxis sin sentido como document.getElementsByTagName("*")
en lugar de document.all
?La lista podría seguir con
execScript
para evaluar código en el ámbito global (relacionado con tiempo de ejecución y con Ajax) y con Object.defineProperty, pero al mismo tiempo tenemos carencias con Array.prototype
desde hace una eternidad, algo relativamente aburrido ya que el prototipo del constructor global debe permanecer "intocable" por razones de compatibilidad ... Ya es hora de comprender que nadie hace un bucle for in
sobre listas o colecciones, así que Array.prototype
ha de ser estandarizado, no hay "puede ser" o "quizá", especialmente ahora que se ha implementado como estándar en ECMAScript 5. Como resumen, estos son conceptos dentro del proyecto vice-versa: especialmente si estos comportamientos pudieran enlentecer el rendimiento general de las aplicaciones, o si estos comportamientos no son estándares.Características vice-versa provenientes de Internet Explorer
Object.defineProperty
(IE 8 o superior)
document.all
, como atajo adocument.getElementsByTagName("*")
document.createElement
con soporte html para cada navegador (a veces simplifica las cosas p.e.document.createElement('<em class="test"></em>')
)
HTMLElement.attachEvent
ydetachEvent
- objeto global
window.event
poblado viaattachEvent
con las propiedadescancelBubble
yreturnValue
HTMLElement.outerHTML
conset
yget
(la forma más simple de leer un elemento del DOM como una cadena)
HTMLElement.innerText
conset
yget
(la forma más rápida en IE de insertar un nodo de texto)
HTMLElement.outerText
conset
yget
(la forma más rápida en IE de reemplazar un nodo genérico por uno de texto)
execScript
para evaluar en un ámbito global cualquier tipo de cadena (sin soporte a un segundo argumento)
- XPath
selectNodes
ynextNode
via documentos XML
- propiedad
xml
, sóloget
, para recuperar una cadena de un XMLDocument/XMLNode
insertAdjacentElement
,insertAdjacentHTML
, yinsertAdjacentText
, la forma más rápida de poner algo antes de un nodo, comofirstChild
, comolastOne
, o tras el mismo nodo
Características vice-versa principalmente para Internet Explorer
Array.slice
, para trocear todo sobre una colección genérica (compatible con DOM)
Array.forEach
, para recorrer una colección genérica viacallback
(compatible con DOM)
Array.prototype
, actualizado a la última revisión de Mozilla/FireFox (sin la especificación completa, versión enfocada en rendimiento)
XMLHttpRequest
, para el antiguo IE6 (desfasado, será eliminado tan pronto como se pueda, pero debemos esperar primero hasta el final de este navegador)
setInterval
ysetTimeout
con argumentos extra como los demás
Características vice-versa de ECMAScript 5
Object.getPrototypeOf
, para recuperar el prototipo heredado por un objeto genérico
Object.keys
, compatible (incluyendotoString
), para recuperar un Array de claves a partir de un objeto
Object.create
, compatible (incluyendotoString
), para crear una nueva instancia a partir de otro objeto
Array.isArray
, para conocer si un objeto genérico es un Array
String.prototype.trim
, una implementación rápida de recorte para cada cadena
Function.prototype.bind
, un método para asegurar el ámbitothis
en una llamada a función
Características extra en vice-versa
document.query
, librería esencial de selectores para obtenere resultados genéricos mediante consultas comunes de tipo dolar (función $)
Object.forIn
, para recorrer una instancia genérica sin considerar al prototipo heredado y sin olvidar las propiedades predefinidas (toString
,valueOf
, etc)
Metas de vice-versa
Pronto llegarán más funcionalidades, esperando mantener por debajo de 10KB de tamaño total minificado y comprimido (actualmente está en 4KB). Esta es sólo una implementación parcial de mi idea original. Las librerías de terceras partes serán bienvenidas, y los colaboradores de otros equipos de librerías serán más que bienvenidos. La idea principal es crear un híbrido completo del escenario JavaScript haciendo que los rendimientos sean similares en cada navegador y ofreciendo una estructura de bajo nivel para construir librerías complejas, aplicaciones, ... respetando donde sea posible a Internet Explorer, y trayendo sus características dentro de otros navegadores rápidos y potentes. ¿Estoy loco?
No hay comentarios:
Publicar un comentario