Automatiser l'ouverture des liens hypertextes dans un nouvel onglet avec Javascript et l'attribut rel external

Introduction

Lors de la définition d'un lien hypertexte externe dans une page, plusieurs méthodes sont possibles afin que que le lien s'ouvre dans un nouvel onglet ou une nouvelle fenêtre du navigateur :

<a href="gimp-supprimer-couleur-arriere-plan-fond.html"
  target="_blank">GIMP 2.6, Supprimer une couleur de fond dans une image
</a>

<a href="gimp-supprimer-couleur-arriere-plan-fond.html"
  onclick="window.open(this.href); return false;">
      GIMP 2.6, Supprimer une couleur de fond dans une image>
</a>

La première méthode avec l'attribut target="_blank" est à bannir, il y a trop de contreverses avec les normes W3C. À l'époque d'HTML 4 strict et XHTML 1.1 strict, cet attribut était interdit. Avec HTML 5, il semble que cela soit à nouveau autorisé mais mieux vaut l'éviter.

La seconde méthode avec l'attribut onclick respecte toutes les normes mais vous êtes fainéant comme moi et vous souhaitez automatiser ce code pour tout ou partie des liens hypertextes d'une page.

Javascript peut s'occuper de tout avec une fonction générique. La présence de l'attribut rel=external suffit amplement.

<a href="gimp-supprimer-couleur-arriere-plan-fond.html"
  rel="external">GIMP 2.6, Supprimer une couleur de fond dans une image
</a>

Squelette HTML de la page et objectifs

Le squelette de la page est la suivante :

Squelette HTML
Figure 1 : Squelette de la page de démo

On désire ajouter dynamiquement le code javascript onclick="window.open(this.href); return false;" pour tous les liens présents dans la balise article et la balise section ayant l'id theme (<section id="theme">)

Chaque page incorpore une librairie javascript lib.js.

<head>
...
  <script type="text/javascript" src="lib.js"></script>
...
</head>

Les liens dans la section thème sont créés avec la fonction display_theme, fonction appelée après le chargement de la page. Tous les liens ont l'attribut rel="external"

box Theme
lib.js
display_theme = function() {
  v_section_theme = document.getElementById('theme');
  ...
  v_a = document.createElement("a");
  v_a.setAttribute("href","url");
  v_a.setAttribute("rel","external");
  v_a.appendChild(document.createTextNode("Titre du lien"));
  v_section_theme.appendChild(v_a);
  ...
};

if (window.addEventListener) {
  window.addEventListener("load",display_theme, false);
}

Tous les liens externes dans la balise article ont l'attribut rel="external".

<article>
...
  <a href="gimp-supprimer-couleur-arriere-plan-fond.html"
      rel="external">GIMP 2.6, Supprimer une couleur de fond dans une image
  </a>
...
</article>

La fonction rebuild_href

La fonction générique rebuild_href qui va traiter les liens hypertextes prend en paramètre un identifiant d'un élément HTML, le nom d'une balise ou d'une classe CSS :

rebuild_href('<tag>' | '<id>' | '<classe CSS>');

Exemples d'appels :

rebuild_href('article');
rebuild_href('theme');
rebuild_href = function(tagoridorclass) {

  var v_element= [];
  v_element[0] = document.getElementById(tagoridorclass);

  if (v_element[0] === null) { v_element = document.getElementsByTagName(tagoridorclass); }
  if (v_element === null)    { v_element = document.getElementsByClassName(tagoridorclass); }
  if (v_element === null) { return; }
  ...
  
};

On recherche d'abord si il s'agit d'un élément avec un id avec la méthode getElementById, si ce n'est pas le cas le ou les éléments avec une balise avec la méthode getElementsByTagName. Si il n'y a toujours pas d'éléments, la recherche d'éléments est réalisée sur la classe css avec la méthode getElementsByClassName. La fonction est quittée (return), si la recherche d'objets avec ces 3 méthodes n'a pas abouti.

La problèmatique ne se pose pour les balises, mais pour les id et les classes, les conflits de nom doivent être évités (id="download", class="download").

Une boucle démarre pour rechercher les liens hypertextes dans ces éléments avec la méthode getElementsByTagName('a') :

rebuild_href = function(tagoridorclass) {

  var v_element= [];
  v_element[0] = document.getElementById(tagoridorclass);

  if (v_element[0] === null) { v_element = document.getElementsByTagName(tagoridorclass); }
  if (v_element === null)    { v_element = document.getElementsByClassName(tagoridorclass); }
  if (v_element === null) { return; }

  for (i=0; i < v_element.length; i++) {
	  v_href = v_element[i].getElementsByTagName('a');

     if (v_href.length > 0) {
       ...
     }

  }

};

Si des liens sont trouvés (v_href.length > 0), l'attribut onclick="window.open(this.href); return false;" est appliqué pour chaque lien avec la méthode setAttribute à condition que l'attribut rel existe et contienne la propriété external :

rebuild_href = function(tagoridorclass) {

  var v_element= [];
  v_element[0] = document.getElementById(tagoridorclass);

  if (v_element[0] === null) { v_element = document.getElementsByTagName(tagoridorclass); }
  if (v_element === null)    { v_element = document.getElementsByClassName(tagoridorclass); }
  if (v_element === null) { return; }

  for (i=0; i < v_element.length; i++) {
	  v_href = v_element[i].getElementsByTagName('a');

     if (v_href.length > 0) {
        for (j=0; j < v_href.length; j++) {
           if (v_href[j].getAttribute('rel') !== null) {
             if (v_href[j].getAttribute('rel').indexOf('external') >= 0 ){ 				
                   v_href[j].setAttribute("onclick","window.open(this.href); return false;");
             }
           }
        }      
     }
  }
  
};

Et c'est terminé. Il ne reste plus qu'à appeler cette fonction rebuild_href en fin de traitement de la page et de l'arbre DOM sur les éléments HTML concernés (<section id="theme"> et <article> pour cet exemple).

lib.js
rebuild_href = function() {
  ...
};

display_theme = function() {
  v_section_theme = document.getElementById('theme');
  ...
  rebuild_href('theme');
};

process_post_load = function() {
  rebuild_href('article');
};

if (window.addEventListener) {
  window.addEventListener("load",display_theme, false);
  window.addEventListener("load",process_post_load, false);
}

Conclusion

Un exemple hypra basique pour industrialiser l'ouverture de liens hypertextes externes dans un nouvel onglet grâce à Javascript et l'attribut natif rel="external". Ainsi aucun lien hypertexte n'échappera à la règle

On peut aller encore plus loin en attribuant une classe CSS spéficique dans le traitement, mais les feuilles de style peuvent très bien à elles seules se charger de cet aspect. En voilà un exemple, le caractère » est ajouté à la fin du titre du lien si l'attribut rel contient la propriété external.

style.css
a[rel~="external"]::after { content: " »"; }

L'envoi d'événements Google Analytics pour les liens externes peut être introduit dans cette cinématique. Cela fera l'objet d'un autre article.