jQueryRank Sculpting : modifier les balises en liens (ElementToA) (Maj v2.0)

Mathieu Chartier Programmation 9 commentaires

Le référencement est avant tout une histoire de contenus comme les grands moteurs aiment nous le rappeler mais les textes ne constituent pas les seuls critères de pertinence pour favoriser un meilleur positionnement dans les SERP (résultats de recherche).

La grande majorité des critères est interne au code source HTML mais il existe également d’autres facteurs « off site » (pour reprendre l’expression chère au maître Olivier Andrieu !) tels que le très connu PageRank de Google et son acolyte de Bing, le BrowseRank.

Le PageRank Sculpting * a été mis à mal par la mise à jour de l’algorithme de Google puisque le PageRank est désormais divisé par le nombre de liens présents dans la page, qu’ils portent ou non l’attribut rel="nofollow". Seulement, nous pouvons essayer d’optimiser le nombre de liens de nos pages sans cet attribut pour duper Google.

Nous allons voir deux techniques pour permettre de camoufler des liens, les rendre invisibles pour les robots mais fonctionnels pour les utilisateurs :

  • le premier code est très simple et permet d’optimiser un « montrer/cacher » en HTML ;
  • le second code est plus complexe et permet d’aller bien plus loin dans le camouflage des liens qui composent les pages web, je parle même de jQueryRank Sculpting pour le définir.

L’objectif des deux codes qui vont suivre est de limiter le nombre de liens visibles par les moteurs afin que la division du PageRank soit amoindrie, alors que les utilisateurs auront le même rendu que si de vrais liens étaient mis en place. Je laisse le suspense pour le moment…

J’ose rappeler un gros détail concernant les référenceurs… Il existe trois types d’actions :

  • White Hat SEO : codes et contenus optimisés de la manière la plus propre possible, en respectant les règles fixées par les moteurs au-delà de l’imaginaire ;
  • Black Hat SEO : optimisations abusives, frauduleuses et qui ne respectent pas les fondamentaux des moteurs de recherche ;
  • Grey Hat SEO : l’entre-deux, à savoir des optimisations poussées mais qui essaient de rester dans la limite du correct.

N.B. : le code du jQueryRank Sculpting a été conçu dans un objectif de Grey Hat SEO, c’est-à-dire que je l’estime intéressant et fonctionnel mais qu’il ne doit pas devenir un jouet au point de virer dans le Black Hat SEO, la frontière entre les deux étant très minces comme vous le verrez…

Première optimisation : cacher / montrer un élément HTML avec overflow

Cette technique n’a rien de révolutionnaire mais elle permet de nettoyer les codes qui permettent de cacher et montrer un élément HTML. En HTML 5, il existe les balises <summary> et <details> mais leur incompatibilité chronique nous oblige à passer par d’autres méthodes, et souvent, il s’agit d’avoir un lien qui ouvre un bloc lors d’un clic ou d’un survol avec la souris.

Notre objectif va être de nettoyer le code en retirant le lien afin d’éviter une perte inutile de PageRank alors qu’il s’agit uniquement d’un effet pour les utilisateurs.

Ce premier code est extrêmement simple et il suffit de bien connaître les langages HTML et CSS pour comprendre, d’autres webmasters ont d’ailleurs certainement déjà eu cette même idée, je n’ai pas la prétention de dire que j’en suis le seul et unique inventeur…

Habituellement, voilà à quoi ressemble un cacher/montrer (ici déclenché au clic avec un code javascript) :

<div id="SavoirPlus">
               <script>
    function cachermontrer(idperso) {
                   document.getElementById(idperso).style.display=document.getElementById(idperso).style.display=="none"?"block":"none";
    };
    </script>

<a href="#" onClick="cachermontrer('textecache');">Cliquez pour en savoir plus</a>
<p id="textecache" style="display:none;">Texte caché par défaut.</p>
</div>

Le problème est qu’il y a un lien utile uniquement pour les utilisateurs, alors nous pouvons trouver un meilleur moyen pour le retirer et pourtant obtenir le même effet. Le code suivant fonctionne uniquement en HTML et CSS mais avec du Javascript, nous pourrions aller plus loin…

Le code HTML est simple, il suffit de créer un bloc en <p> ou en <div> et d’intégrer une balise <span> contenant le texte à cliquer ou à survoler pour afficher le reste du contenu. En CSS, il suffit de limiter l’affichage du <span> dans un premier temps avec la propriété overflow puis d’appliquer un effet de survol pour afficher le texte restant. Ainsi, plus de lien surperflu pour un effet identique. Avec Javascript, vous pourriez obtenir le même résultat avec un déclenchement au clic de la souris…

Voici le code HTML :

<div id="SavoirPlus">
    <p><span class="rouge">Cliquez pour en savoir plus<br/></span>
    Texte caché par défaut.</p>
</div>

Voici le code CSS associé :

<style>
#SavoirPlus {border:2px solid #C03; border-radius:8px; padding:10px; margin:50px; width:220px;}
#SavoirPlus p {
               width:220px;
               height:20px;
               overflow:hidden;
               text-overflow:ellipsis; /* permet d'afficher des points de suspension si découpage du texte (au cas où...) */
               white-space:nowrap;
}
#SavoirPlus p:hover { /* effet de survol pour afficher le texte caché */
               height:auto;
               white-space:normal;
}
.rouge {color:#C03; display:block; margin-bottom:10px;}
</style>

Seconde optimisation : jQueryRank Sculpting – Cacher des liens dans le code source

Ce second code (ElementToA.js) est plus technique et permet de créer ce que j’ai osé appeler le jQueryRank Sculpting, sans prétention aucune… Une fois encore, je ne suis certainement pas le premier à avoir eu l’idée, bien que je ne l’aie pas trouvé ailleurs pour être honnête, et ce code peut encore être amélioré pour aller plus loin.

L’objectif est d’automatiser la modification de balises HTML portant une class précise en lien <a> lors d’un survol effectué par l’utilisateur. En d’autres termes, le robot des moteurs ne voit que des balises HTML classiques mais l’utilisateur peut cliquer sur des liens fonctionnels lorsqu’ils survolent les contenus portant la class « linktoggle » (elle porte ce nom dans mon code mais vous pouvez la changer bien entendu). Il suffit juste de régler l’affichage de la class « linktoggle » et des liens (class « newLink » par défaut) pour que ce soit homogène pour les utilisateurs.

Le code n’est pas insurmontable pour les experts de jQuery mais il a toutefois quelques subtilités, avec bien sûr comme première obligation l’insertion de la bibliothèque jQuery. J’avoue avoir essayé de le raccourcir au maximum en le rendant toujours aussi fonctionnel mais à chaque fois, je me suis retrouvé confronté à de petits bugs d’affichage gênants. Le code proposé fonctionne et c’est bien là l’essentiel, n’est-ce-pas ? :D

Le but du code est d’avoir un minimum d’efforts à fournir pour le rendre fonctionnel. Actuellement, il suffit d’insérer la class « linktoggle » sur les éléments que vous voulez transformer en lien ainsi qu’un attribut title contenant l’URL complète qui servira pour rendre le lien fonctionnel. J’ai volontairement laissé les utilisateurs gérer le « href » car certains pourraient décider d’utiliser le code avec des ancres de liens, des « mailto: » ou des « tel: » par exemple.

J’explique globalement le fonctionnement, bien que le code soit commenté, plusieurs étapes successives sont nécessaires pour que tout soit parfait, en suivant trois fonctions reliées :

  • La première fonction s’exécute pour récupérer les attributs existants dans la balise d’origine, le type d’élément utilisé (span, div, etc.) et pour lancer une première fois la transformation en lien. Un événement javascript (onmouseout) est rajouté pour récupérer les données issues des variables globales qui seront utilisées dans la fonction restoreSpan.
  • La fonction restoreSpan reconstruit à l’identique le balisage de départ, en ajoutant uniquement un événement javascript (onmouseover) qui transmet les données des variables globales de départ (type de balise + attributs) et exécute la fonction restoreA.
  • La fonction restoreA ressemble à la première car elle permet de recréer un <a> avec toutes les données mémorisées. Elle permet de boucler les actions…

N.B. : si tout n'est pas assez clair, n'hésitez pas à commenter ou à me contacter pour de plus amples explications...

Vous pouvez télécharger l’archive ElementToA (contenant un démo) ou recopier le code de la fonction ci-dessous (attention, non compatible avec jQuery 1.9 et supérieurs, il faut prendre cette version 3.0 sinon) :

Télécharger “jQueryRank Sculpting v2.0”jQueryRank-2.0.zip – Téléchargé 2367 fois – 39,23 Ko

<script src="jquery-1.7.2.min.js"></script>
<script>

source = '.linktoggle'; // Class (.nomClass) ou ID (#nomId)
attribut = 'title'; // (attribut qui réceptionne l'URL)
newclass = 'newlink'; // (class du lien après modification)
evttag = 'hover'; // déclencheur du script : survol (hover), clic (click) ou double-clic (dblclick)

jQuery(document).ready( function() {
    // Cryptage et décryptage des URL
    $.fn.wwwtostr = function(contenu) {
        string        = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_!$/*+&#?:.0123456789";
        stringNew    = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!+-_$/*&#?:.";
        var returnwww = strtr(contenu, string, stringNew);

        var tab = new Array();
        for (var i=0; i < returnwww.length; i++) {
            tab[i] = returnwww.substring(i,i+1);
        }
        tab.reverse();
        var result = tab.join("");
        return result;
    };
    $.fn.strtowww = function(contenu) {
        string        = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_!$/*+&#?:.0123456789";
        stringNew    = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!+-_$/*&#?:.";
        var returnwww = strtr(contenu, stringNew, string);
        var tab = new Array();
        for (var i=0; i < returnwww.length; i++) {
            tab[i] = returnwww.substring(i,i+1);
        }
        tab.reverse();
        var result = tab.join("");
        return result;
    };
    // Cryptage au démarrage
    $(source).attr(attribut, function() {
        var localUrl = jQuery(this).attr(attribut);
        if(localUrl !== undefined) {
            var wwwModif = jQuery(this).wwwtostr(localUrl);
            jQuery(this).attr({title: wwwModif});
        }
    });

    if(evttag == 'hover') {evenement='hover';evtjavascript='onmouseover';evtjavascript2='onmouseout';} else
    if(evttag == 'click') {evenement='click';evtjavascript='onclick';evtjavascript2='onmouseout';} else
    if(evttag == 'dblclick') {evenement='dblclick';evtjavascript='ondblclick';evtjavascript2='onmouseout';} else
    {evenement='hover';evtjavascript='onmouseover';evtjavascript2='onmouseout';}

    // Premier survol : on remplace le <span> survolé par un lien <a>
    // Cette initialisation évite d'appliquer les remplacements quand des <a> classiques sont en place (on se limite aux <span> ici)
    jQuery(source).live(evenement,function() {
        // on adapte la modification en <a> en fonction des éléments d'origine (<span>, <h2>, <div>...) qui portent la class ".linktoggle"
        ElmtToggle = jQuery(this).get(0).tagName.toLowerCase();

        // on récupère les attributs existants dans la balise d'origine (rel, title, class, id...)
        var arrayAttrs = [];
        for(var i=0, attrs=jQuery(this).get(0).attributes, nb=attrs.length; i < nb; i++) {
            arrayAttrs.push(attrs.item(i).nodeName+'="'+attrs.item(i).nodeValue+'"');
        }
        Attributs = arrayAttrs.join(" "); // on enregistre tous les attributs et leurs valeurs dans une chaine --> variable globale

        var TexteSpan = jQuery(this).text(); // on mémorise le texte contenu dans le lien
        var TexteTitle = jQuery(this).strtowww(jQuery(this).attr(attribut)); // on mémorise le texte contenu dans le lien

        // on utilise replaceWith() plutôt que html() car elle remplace totalement les balises, elles ne les ajoutent pas --> problèmes sinon !
        // on génère un appel vers une fonction qui va permettre de remettre le <span> quand il n'y a plus de survol
        jQuery(this).replaceWith('<a href="'+TexteTitle+'" '+evtjavascript2+'="jQuery(this).restoreSpan(ElmtToggle,Attributs);">'+TexteSpan+'<\/a>'); // on l'intègre dans des <a>
        return false;
    });

    // la fonction RestoreSpan remet le <span> initial en route (quand on quitte le survol du lien)
    // on doit appeler une fonction restoreA pour autoriser à nouveau la modification du <span> en <a>
    $.fn.restoreSpan = function(ElmtToggle,Attributs) {
        var TexteA = jQuery(this).text(); // on enregistre le texte contenu dans le lien
        var TexteHREF = jQuery(this).attr('href'); // on enregistre le texte contenu dans l'attribut href --> title du <span>

        jQuery(this).replaceWith('<'+ElmtToggle+' title="'+TexteHREF+'" '+evtjavascript+'="jQuery(this).restoreA(ElmtToggle,Attributs);" '+Attributs+'>'+TexteA+'<\/'+ElmtToggle+'>'); // on le remet dans des <span>
    };
    // la fonction RestoreA replace le <a> désiré en cas de nouveau survol du lien
    // on appelle à nouveau la fonction restoreSpan pour retourner à l'état de départ
    $.fn.restoreA = function(ElmtToggle,Attributs) {
        var TexteSpan = jQuery(this).text(); // on enregistre le texte contenu dans le lien
        var TexteTitle = jQuery(this).attr(attribut); // on enregistre le texte contenu dans l'attribut href --> title du <span>

        jQuery(this).replaceWith('<a href="'+TexteTitle+'" '+evtjavascript2+'="jQuery(this).restoreSpan(ElmtToggle,Attributs);">'+TexteSpan+'<\/a>'); // on l'intègre dans des <a>
    };
});
</script>

Le code ElementToA.js fonctionne partout dans la page web à partir du moment où les attributs title="URL_COMPLETE" et class="linktoggle" sont insérés dans le code, les utilisations peuvent donc être variées (menus, contenus, galeries d’images, etc.).

N.B. : je me défends des exploitations frauduleuses ou abusives de ce type de code. Je le fournis pour montrer que le code peut vraiment rendre service au référencement mais je n’en fais aucun usage abusif personnellement, je ne veux pas être tenu responsable d’éventuelles futures pénalités si cela venait à se produire un jour…

Rappels

Pour faire un rapide rappel, le PageRank et le BrowseRank analysent en profondeur le profil des liens entrants vers des pages web. Plus une page reçoit de liens entrants, mieux elle est considérée (ou « notée ») par les moteurs. Ce critère ne fait pas tout, je le rappelle, mais il fait partie de la liste des facteurs de valeur si je puis dire… Il faut noter que les liens internes à une page peuvent aussi transmettre du PageRank ou du BrowseRank mais dans une moindre mesure, les liens externes pointant vers les pages étant logiquement privilégiés.

Les moteurs ayant pensé à tout, ils avaient inventé un attribut HTML appelé rel="nofollow" pour permettre aux webmasters de ne pas transmettre de PageRank (et BrowseRank) aux liens portant cet attribut. Les petits malins de référenceurs ont alors pensé à une méthode appelée « PageRank Sculpting » visant à jouer avec ce dernier pour ne donner de la valeur qu’aux liens souhaités, qu’ils soient internes ou externes.

Google a réagi face à ces dérives et a implanté un système bête et méchant, mais imparable. Le robot compte le nombre de liens présents dans la page web (avec ou sans « nofollow ») et divise le PageRank par ce nombre. Par exemple, si vous avez 10 liens (dont 2 en « nofollow »), Google divise le PageRank par 10 mais ne transmet que 1/10 aux 8 liens qui ne portent pas l’attribut rel="nofollow".