Contenido

Creando un querySelector() para IE tan rápido como el nativo

29 Ago

+ 2

Via Ajaxian descubro una solución para disponer de una versión rápida (casi como la nativa )  de querySelector() en Internet Explorer 4+. Muy similar a la propuesta por Dean Edwards en 2006.

/*@cc_on
 if (!document.querySelector)
 document.querySelector = function(selector) { 

 // Añadimos un nuevo tag <style />
 var head = document.documentElement.firstChild;
 var styleTag = document.createElement("STYLE");
 head.appendChild(styleTag); 

 // Creamos un array global
 document.__qsResult = []; 

 // Añadimos los elementos seleccionados mediante un SECE
 document.__qsResult.styleTag.styleSheet.cssText = selector + "{qs: expression(this.__qs?0:(function(t){document.__qsResult.push(t);t.__qs=0;})(this));}";

 // Recargamos la página. Sin esto el SECE no se ejecutará.
 window.scrollBy(0, 0); 

 // Limpiamos el nuevo elemento y devolvemos los resultados.
 head.removeChild(styleTag);
 return document.__qsResult;
 }
@*/

La mágia del script, que nos permite implementar una versión del Selectors API,  reside en los SECE (Single Execution CSS Expressions), pero ¿que son?

Single Execution CSS Expressions (SECEs)

En Internet Explorer (4.0+) tenemos una implementación que únicamente podremos usar en este navegador que nos permite ejecutar expression() en nuestros CSS.

 .post-body img { // Ejemplo Max-width para IE
   max-width:400px;
   width: expression(this.width > 400 ? 400: true);
 }

Ya lo llevamos usando mucho tiempo y lo hemos visto en varios ejemplos a lo largo de los últimos años.

background-color: expression( (new Date()).getHours()%2 ? "#B8D4FF" : "#F08A00" );

Incluso nos permite cambiar (solo en IE) el color del fondo de un elemento cada hora par (8,10,…)

Pero unas mentes inquietas llegaron a sacarle más partido a esta curiosa implementación, haciendo que la capa de estética interactue directamente con la capa de funcionalidad.

<script>
function setOnetimeBgcolor(elem) {
  elem.style.backgroundColor = <some calculation>;
}
</script>
<style>
P {
  background-color: expression(setOnetimeBgcolor(this));
}
</style>

Esto me hace pensar en algo asi 😀

<style>
/* Enviamos a la versión IE */
html {
 background-color: expression(location.href = 'index_ie_version.html';);
}
</style>

Aunque hará que nuestro CSS no valide según los estándares de la W3C.

Problemas

El propio John Resig contesta al artículo de Ajaxian y expone los problemas que podríamos encontrarnos con este sistema.

  • Las expresiones CSS de IE son conocidas por su excesiva sobrecarga
  • No hay una forma clara de abordar la gestión de errores. ¿Que sucede si se usa un selector no soportado?
  • // Subimos al inicio de la página. Sin esto el SECE no se ejecutará.

     window.scrollBy(0, 0); 

    Esto lo que hara no es subir al inicio de la pagina. Creo que has confundido las funciones scrollTo y scrollBy

    scrollTo hará scroll a la posición indicada, mientras que scrollBy hara scroll los pixeles indicados relativamente a la posición actual. Es decir, que scrollBy(0,0) no moverá el scroll, pero forzara al navegador a re-dibujar la pagina entera, y ejecutando el css.

Comentar

#

Me reservo el derecho de eliminar y/o modificar los comentarios que contengan lenguaje inapropiado, spam u otras conductas no apropiadas en una comunidad civilizada. Si tu comentario no aparece, puede ser que akismet lo haya capturado, cada día lo reviso y lo coloco en su lugar. Siento las molestias.