Google Adsense - Ajout dynamique avec Javascript et la méthode createElement

Introduction

SQLPAC incorpore depuis novembre 2011 des annonces Google AdSense dans les articles. L'objectif de l'ajout de ces annonces ne consiste pas à faire fortune, ces annonces sont affichées pour les 2 raisons suivantes :

  • Amortir les frais d'hébergement annuels du site sqlpac.com et si les revenus le permettent, accéder à des offres d'hébergement techniquement plus élaborés.
  • Offrir des liens alternatifs vers des sites, les annonces Google AdSense étant généralement très pertinentes avec le contenu de l'article.

Un précédent article paru décembre 2010 présente l'ajout et la suppression d'éléments avec Javascript dans une page HTML avec l'objectif de supprimer l'appel de la méthode document.write incompatible avec la norme XHTML : Ajout et suppression d'éléments avec Javascript - Suppression de document.write.

Pour aller plus loin dans cet objectif de supprimer les méthodes document.write, cet article présente à présent comment incorporer dynamiquement Google AdSense avec Javascript grâce au tag <object> dans une page HTML déjà existante. Cette méthode est compatible avec Chrome, Firefox 4 & 5, Opera 11.5 et Safari 5, en revanche pour Internet Explorer 8, le navigateur qui donne toujours du fil à retordre, cette méthode fonctionne mais avec des défauts ergonomiques. Chaque solution n'est pas parfaite et a ses inconvénients : dans la solution proposée ici, des conséquences non négligeables dans Google Analytics sont à prendre en considération et décrites ici.

La problématique de Google AdSense et l'ajout dynamique avec Javascript

Exemple de code d'une bannière d'annonces Google AdSense

Le code source pour incorporer une bannière d'annonces Google AdSense est relativement simple, en voici un exemple pour une bannière verticale 120x240 pouvant contenir 2 annonces :

<script type="text/javascript">
            <!--
               google_ad_client = "xx-xxx-xxxxxxxxxxxxxxxxxxxx";
               /* Banniere Verticale 2 annonces */
               google_ad_slot = "4051880056";
               google_ad_width = 120;
               google_ad_height = 240;
            //-->            
</script>
<script type="text/javascript"
      src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>

Les variables google_ad% définissent les propriétés du compte Google AdSense et de l'annonce :

  • google_ad_client : identifiant du compte Google AdSense.
  • google_ad_slot : identifiant de l'annonce, identifiant généré lors de la création de l'annonce dans le compte Google AdSense.
  • google_ad_width : largeur de la bannière.
  • google_ad_height : hauteur de la bannière.

Le script http://pagead2.googlesyndication.com/pagead/show_ads.js réalise l'affichage de la bannière d'annonces.

Pourquoi l'ajout du script show_ads.js ne fonctionne pas avec les méthodes createElement("script") et appendChild ?

Tout naturellement, pour ajouter dynamiquement cette bannière d'annonces dans un bloc div existant et ayant l'identifiant adsense (<div id="adsense"> </div>), les méthodes Javascript createElement("script") et appendChild viennent à l'esprit :

/** Ne fonctionne pas */
google_ad_client = "xx-xxx-xxxxxxxxxxxxxxxxxxxx";
google_ad_slot = "4051880056";
google_ad_width = 120;
google_ad_height = 240;

v_div_adsense = document.getElementById("adsense");
v_src_adsense = document.createElement("script");
v_src_adsense.setAttribute("src","http://pagead2.googlesyndication.com/pagead/show_ads.js");
v_div_adsense.appendChild(v_src_adsense);

Cette méthode est sans effet car Google Adsense utilise la méthode document.write en mode sérialisé pour afficher la bannière d'annonces dans des blocs iframe :

show_ads.js
...
 document.write("<span id="+a+"></span>");
 ...

Google AdSense est incompatible avec la norme XHTML/DOM, norme dans laquelle la fonction document.write est inactive.

Solution pour ajouter dynamiquement Google AdSense avec Javascript

Contexte

Pour contourner ce point bloquant lorsqu'il faut insérer les annonces AdSense dynamiquement dans une page html déjà existante :

  • Une page statique ads.html ne contenant que le code Javascript des annonces AdSense est spécifiquement créée.
  • Le contenu de la page ads.html est incorporé dynamiquement avec Javascript dans la page principale grâce à la balise <object>.

Dans l'exemple concret proposé dans cet article, les annonces doivent être insérées dynamiquement dans la balise <div id="div-toc-right"> de la page article.htm. Un schéma valant bien mieux qu'un long discours :

schema ajout adsense dynamique

Préparation d'une page HTML ads.html pour les annonces Google AdSense

Une page ads.html est créée dans le sous répertoire ./ads. Le corps de la page ads.html, certifiée HTML 4.01 strict, contient simplement le code Javascript des annonces Google AdSense :

./ads/ads.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
     <head>
        <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
        <link href="adsense.css" rel="stylesheet" type="text/css">
        <title>Annonces Google</title>
     </head>  
<body>
           <script type="text/javascript">
            <!--
               google_ad_client = "xx-xxx-xxxxxxxxxxxxxxxxx";
               /* Banniere Verticale 2 annonces */
               google_ad_slot = "4051880056";
               google_ad_width = 120;
               google_ad_height = 240;            //-->
            </script>
            <script type="text/javascript"
                    src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
            </script>
</body>    
</html>

La feuille de style adsense.css appelée dans la page ads.html est très importante : les propriétés définies dans la feuille de style adsense.css empêchent surtout l'affichage automatique des barres de défilement (scrollbars).

adsense.css
html {
  border: none;
  overflow: hidden;
}

body {
  margin: 0;
  padding: 0;
  border: none;
  overflow: hidden;
}
  • La propriété overflow:hidden fixe le contenu. Aucun ascenceur ou scrollbar ne sera affiché si le contenu de la page ads.html dépasse la largeur et la hauteur définies.
  • Les bordures sont éliminées avec la propriété border:none;
  • Les marges et espacements sont définies à 0 pour le corps de la page ads.html (margin: 0; padding: 0;).

Incorporation dynamique de la page HTML des annonces Google AdSense grâce à la balise <object>

La page ads.html créée précédemment peut être incorporée dans la page article.htm grâce à la balise <object> :

...
<div id="div-toc-right">
  <div id="adsense">
    <object data="./ads/ads.html" type="text/html" id="objadsense"></object>
  </div>
</div>
  • L'attribut data indique la localisation de la page ads.html.
  • L'attribut type="text/html" spécifie qu'il s'agit d'un contenu de type html. La balise <object> peut embarquer en effet d'autres types de contenu (flash etc...).

L'ajout dynamique avec les méthodes Javascript createElement et appendChild de cette balise <object> ne pose alors aucun problème et ne perturbe en rien l'écriture du contenu des annonces avec document.write dans la sous page ads.html :

v_div_tocright = document.getElementById("tocright");

v_div_adsense = document.createElement("div");
v_div_adsense.setAttribute("id","adsense");

var v_objetAdsense=document.createElement("object");
v_objetAdsense.setAttribute("data","./ads/ads.html");
v_objetAdsense.setAttribute("type","text/html");
v_objetAdsense.setAttribute("id","objadsense");
v_div_adsense.appendChild(v_objetAdsense);

v_div_tocright.appendChild(v_div_adsense);

Les styles CSS et le cas Internet Explorer 8

Le bloc div incluant les annonces AdSense (<div id="adsense">) est dimensionné grâce aux feuilles de style CSS associées à la page article.htm. Pour une bannière 120x240, la largeur et la hauteur sont définies à 120 et 240 :

#adsense {
  padding   : 0px;
  margin    : 0px;
  width     : 120px;
  height    : 240px;
  float     : right;
}

Une telle définition est parfaite pour Chrome, FireFox, Opera 11 ou Safari 5.

Malheureusement le navigateur Microsoft Internet Explorer version 8 présente une nouvelle fois des exceptions : pour cette version de navigateur, les bordures ne peuvent pas être supprimées d'une part et la hauteur et la largeur doivent être très légèrement augmentées de quelques pixels d'autre part pour éviter les rognures dûes aux bordures sur le texte des annonces.

#adsense {
  padding   : 0px;
  margin    : 0px;
  width     : 124px;
  height    : 244px;
  float     : right;
}

Les tests n'ont pas été réalisés sur la version 9 de Microsoft Internet Explorer pour savoir si les bordures deviennent invisibles.

Ces défauts ergonomiques avec MS Internet Explorer sont acceptés dans le contexte de cet article : en effet sur les 40 600 visites du site sqlpac.com depuis le début de l'année 2011, FireFox et Chrome représentent 65% des visites contre 31% pour Microsoft Internet Explorer.

Google AdSense et Google Analytics avec cette méthode, le grand dilemme !

Google Analytics est capable d'aggréger les statistiques des impressions des pages et revenus Google AdSense. Cette fonctionnalité est paramétrée en 1 clic dans l'outil Google Analytics dans la page de modification des paramètres du site :

Paramétrage Google AdSense dans Google Analytics

Cette option permet de centraliser les informations dans Google Analytics sans devoir ouvrir le tableau de bord du compte Google AdSense, et surtout Google Analytics affiche les revenus AdSense par page, ce qui n'est pas possible dans le tableau de bord Google AdSense.

L'application de la méthode décrite ici avec la balise object, telle quelle, ne permet plus à Google Analytics de traquer les impressions de pages et revenus AdSense, les annonces AdSense étant délocalisées dans une page statique ads.html non analysée par Google Analytics.

Dès le premier jour de la mise en place de cette méthode, les tableaux de bord de Google Analytics et Google AdSense vont être radicalement différents :

Google Analytics - 17/08/2011 Google AdSense - 17/08/2011
212 Impressions de page AdSense
218 Impressions d'ensemble AdSense
Pages vues   Clics 477       2

Dans l'exemple ci-dessus, les impressions détectées par Google Analytics correspondent aux pages pour lesquelles les annonces AdSense ne sont pas incorporées dynamiquement avec Javascript et createElement. Ce sont les pages http://www.sqlpac.com/articles/%. 50% des impressions de page AdSense ne sont plus détectées.

Pour contourner ce point, Google Analytics doit également détecter la page statique ads.html, ainsi les statistiques des impressions et revenus AdSense sont recouvrées. Le script fc_googleanalytics.js ici prend en charge le "tracking" de la page courante ads.html :

./ads/ads.html
...
<head>
       ...
       <script type="text/javascript" src="../js/fc_googleanalytics.js"></script>
       ...
</head>  
 ...

Pour plus d'informations sur les statistiques avec Google Analytics : Google Analytics - Migration en mode javascript asynchrone

Malheureusement, car il y a un "mais" très important, avec ce contournement, il n'est plus possible d'avoir le détail des revenus par pages :

Avec la méthode document.write classique :

Page Revenus AdSense Annonces AdSense
ayant
enregistré des clics
Impressions de
pages AdSense
.../oracle-export-import-datapump-10g.htm 0,57 $US 2 2
.../unix-awk.htm 0,51 $US 2 2

Avec ce contournement, il n'y aura plus qu'une statistique globale de revenus sur la page ads.html sans détail possible :

Page Revenus AdSense Annonces AdSense
ayant
enregistré des clics
Impressions de
pages AdSense
/referentiel/docs/ads/ads.html 1,57 $US 2 119

Le dilemme naît ici : 2 solutions à choisir en fonction de ses besoins

  • conserver les statistiques des revenus par page dans Google Analytics mais en utilisant la méthode document.write qui ne respecte pas les normes W3C DOM/XHTML et qui ne permet pas un positionnement dynamique aisé des annonces AdSense, y compris avec des feuilles de style.
  • ou bien utiliser la solution proposée ici, solution qui respecte les règles du W3C DOM/XHTML et facilite le positionnement des annonces AdSense dans des blocs DIV, mais en revanche avec perte des statistiques des revenus par page. Google Analytics ne présentera plus qu'une statistique globale de revenus pour la page ads.html, sans détail possible, avec cette alternative.

Conclusion

Cette méthode d'incorporation dynamique des annonces AdSense dans une balise object est très pratique pour éviter de retoucher le code HTML d'une page existante ainsi que positionner aisément les annonces AdSense à l'aide des feuilles de style dans cette même page, cependant 2 inconvénients à retenir :

  • Microsoft Internet Explorer 8 présente des défauts ergonomiques désagréables (bordures sur la balise object).
  • Quelques conséquences fâcheuses, à débattre en fonction de ses propres besoins, sur les statististiques Google Analytics avec Google AdSense : le détail des revenus par page n'est plus possible, uniquement une statistique globale.