Abrir Nueva Ventana en (X)HTML Strict II (mantener la usabilidad)

(Atención: Este post es una continuación de Abrir Nueva Ventana en (X)HTML Strict; aunque no es obligatorio que lo hayas leído, es recomendable para entender el contexto.)

Ya en el post anterior (Abrir Nueva Ventana en (X)HTML Strict) habíamos mostrado una forma de conseguir que nuestros vínculos se abriesen en una nueva ventana sin saltarnos el estándar de (X)HTML Strict, por medio del atributo rel y javascript. Sin embargo, tenemos un problema: ¿qué pasa si nuestro usuario tiene desabilitado javascript? Bueno, de eso se trata este update.

Nota: Esto está enmarcado en el proceso de realización del proyecto cesarfrick.com (ya pronto, ya pronto…), así que lo mostraré en este contexto, si tu necesidad difiere un poco de lo que aquí se muestra, debes hacer las adaptaciones pertinentes. También puedes decir que fue tu idea, no creo que haya sido el único loco en pensar en esto 😉

He aquí el código (esto va en un archivo externo, que yo he llamado external_links.js):

function openExternal(){
var anchors = document.getElementsByTagName('a');
for(var i = 0; i < anchors.length; i++){
var thisAnchor = anchors[i];
if(thisAnchor.getAttribute('href') && thisAnchor.getAttribute('rel') == 'external'){
var parent = thisAnchor.parentNode; //Referencia al contenedor del hipervínculo.
var a = document.createElement('a'); //Creamos un nuevo Hipervínculo.
var space = document.createTextNode(' ');
a.innerHTML = '(Abrir en una Nueva Ventana)'; //Colocamos el texto que aparecerá
a.href = thisAnchor.href;
a.title = thisAnchor.title;
a.target = '_blank';
parent.appendChild(space);
parent.appendChild(a);
}
}
}
window.onload = openExternal;

Ok, expliquemos esto paso a paso. Lo que hace este código no es que cada link con el atributo rel=”external” se abra en una ventana nueva, en este caso lo que haremos es crear un nuevo link, que será el que abra en una nueva ventana, al lado del que ya hemos creado en (X)HTML. ¿Cómo lo hace?

  1. Guarda en un Array todos los hipervínculos de nuestro HTML:
    var anchors = document.getElementsByTagName('a');

  2. Si el array tiene un hipervínculo y su atributo rel es external:
    if(thisAnchor.getAttribute('href') && thisAnchor.getAttribute('rel') == 'external'){

  3. Guarda en una variable el elemento que contiene el hipervínculo:
    var parent = thisAnchor.parentNode;

  4. Crea un hipervínculo nuevo (que será el que se abrirá en la nueva ventana) y también un espacio:
    var a = document.createElement('a');
    var space = document.createTextNode(' ');

  5. Le coloca el texto “Abrir en Nueva Ventana”:
    a.innerHTML = '(Abrir en una Nueva Ventana)'

  6. Le agrega la misma dirección (href) y el mismo título (title) que el hipervínculo que creamos en HTML:
    a.href = thisAnchor.href;
    a.title = thisAnchor.title;

  7. Le asignamos el atributo target y le damos el valor _blank (lo que hará que abra el vínculo en una nueva ventana/pestaña)
    a.target = '_blank';

  8. Añadimos el espacio y el vínculo al contenedor:
    parent.appendChild(space);
    parent.appendChild(a);

  9. Procesamos la función en cuanto se carga el HTML:
    window.onload = openExternal;

La diferencia entre esta técnica y la mostrada en Abrir Nueva Ventana en (X)HTML Strict es que, si el browser del usuario tiene javascript desactivado, no se mostrará este hipervínculo, por lo que no tendrá la confusión de tener un hipervínculo que no haga lo que dice (abrir en una nueva ventana). Simplemente navegará en la misma ventana sin darse cuenta de nada. Creo que esto es una mejora a nivel de usabilidad porque no obliga al usuario a tratar de entender por qué tiene dos vínculos que hacen exactamente lo mismo…

Nota II: En mis pruebas, no he tenido problemas con Firefox, Opera ni Safari (para Windows), pero en IE6 (tenía que ser) crea el vínculo pero no le asigna el atributo href. Si encuentro alguna forma de conseguirlo se los haré saber; si alguien la encuentra, le agradecería mucho que la compartiera 😉

Update: Pues, revisando los foros de Cristalab he dado con la solución por pura casualidad. Al parecer, IE6 no acepta la asignación directa de un valor al atributo href, así que con lo que me encontré fue con el método setAttribute, con esta sintaxis:

objeto.setAttribute('nombre_atributo', 'valor atributo');

Por lo tanto, cambiamos la línea:

a.href = thisAnchor.href

por:

a.setAttribute('href', thisAnchor.href);

¡Y listo, ya funciona para El Maligno (léase IE6 😉 )


Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s