Les Codes Sources de MaX3315 - tous droits réservés
og@votre-web.com

Emulation d'ellipsis sous Firefox - V1.0

Ou comment tronquer automatiquement un contenu trop long pour un conteneur?

Description

Ce script va mesurer la largeur des chaines de caractère qui se trouve dans certains élement possédant une feuille de style bien déterminé. Puis si il s'avère que cette chaîne est tronqué car le conteneur est pas assez large alors on supperpose sur la zone de troncage un div contenant trois petit points. Cette opération ne s'effectue que sous Firefox puisque sous IE une feuille de style permet de tronquer une chaine automatiquement en mettant trois petits points via la valeur ellipsis, d'où le nom d emon script.

Un contenu tronquer c'est certes plus beau mais plus très utile, c'est pourquoi j'ai compléter ce script par la gestion du survol de la chaîne tronquer afin d'afficher la chaîne complète à ce moment dans une sorte de 'bulle' venant ce caler juste au-dessus de l'emplacement original.

Une démonstration est à votre disposition un peu plus bas. (Accès directe via l'icône Icône de démonstration ).

Grâce à ce script vous n'aurez plus a vous souciez de l'aspect de vos colonnes de tableau quelque soit la longueur de leur contenu tout en gardant une parfaite visibilité de celui-ci.

Ce script est totalement fonctionnel mais j'ai en tête quelque amélioration notamment concernant la gestion des couleurs des troncatures (grâce à mon script getVisibleBackgroundColor()). Je souhaite également avoir une réflexion sur la compatibilité de ce script avec les impressions papiers, je dois avouez à ce sujet que je n'est encore réalisé aucun test.

Spécification et speudo-code [?]

Très prochainement

Code source

Figure 1: Code source

var isIE=null;
var testEllipsisElt=null;
var longVersionEllipsis=null;
var ellipsisMotif='...'; //le contenu de l'élement à vous d'y mettre tous l'html que vous souhaitez, img, etc...
var ellipsisTimeoutDuration=2000; //en miliseconde, dureee d'affichage de la version complete
var className='ellipsisDiv'; // class css filtrant les tag a traiter.
var tagName='DIV'; //identification des elemetns a traiter
var ellipsisSuffixe='_ellipsispt'; //id suffixe for ellipsis element.
var ellipsisZIndex=5000; //beaucoup pour etre certain d'eter audessus.
//tag a prendre en compte dans le calcule de l'offset vertical et horizontal
var goodTagForOffset=Array('DIV','P','H1','H2','H3','H4','H5','H6','PRE','TD','TABLE'); //p'etre a complete en fonction de votre besoin

/***********************************************/
//function f_replaceEllipsis(className,tagName)
// param : className: non de la classe css filtrant les elements à traiter
// param : type de tag à traiter
// description :
// cette function va regarder si il y a eu overflow
// pour tous les elements repondant au critere tagName.className
/***********************************************/
function f_replaceEllipsis(className,tagName,overFunctionName)
{
var listTab=document.getElementsByTagName(tagName);
//pour toutes les cellules du test
for(i=0 ; i<listTab.length ; i++)
{
var obj=listTab[i]; //document.getElementById('div'+i);
if(obj.className==className)
{
var pt=null;
if(!isIE) // IE implemente cela directement en css avec la commande style="text-overflow:ellipsis;"
{
pt=document.getElementById(obj.id+ellipsisSuffixe); //div contenant les signes de depassement (par defaut '...');
}
//Largeur affiché de l'élément
var ll=obj.offsetWidth;
//on remplit notre element de test avec le contenu dont il faut mesurer la longueur totale
testEllipsisElt.innerHTML=obj.innerHTML;
//on mesure sa largeur
var L_test=testEllipsisElt.offsetWidth;
//on test si le contenu depasse la largeur du conteneur
//en realité on compare la longeur reelle affiche avec la longeur mesurée
// dans l'element de test sans contraite d'overflow
if(ll<L_test) // il y a depassement
{
if(!isIE) //inutile avec IE
{
if(pt==null) //si il n'existe pas d'element '...' dans le dom pour l'element courrament en cours de traitement
{
ptmp=document.createElement("div"); //creation de l'ement '...'
ptmp.id=obj.id+ellipsisSuffixe; //on lui attribut un id construit a partir de l'id de l'elt en cours de mesure
ptmp.innerHTML=ellipsisMotif;
//mise en place des CSS sur l'element
ptmp.style.position='absolute'; //obligatoire !!
ptmp.style.zIndex=ellipsisZIndex;
ptmp.style.whiteSpace='nowrap'; //fortement conseillé
ptmp.style.backgroundColor='#FFFFFF';
//on ajoute cet element au DOM
document.body.appendChild(ptmp);
pt=document.getElementById(obj.id+ellipsisSuffixe);
}
//on c'est que pt existe maintenant
}

//on va recupere la position exacte de l'element mesure sur la page
//on utilise pour cela la propriete offsetTop qui donne la position par rapport au parent
// c'est pour cela que l'on additionne dans une boucle tout les offsetTop et offsetLeft des parent...
var tt=obj.offsetTop;
var lle=obj.offsetLeft;
var objTmp=obj.parentNode;
var jj=0; //anti boucle infine
while(objTmp!=document.body && jj<1000) //on limite à 1000 niveau d'imbrication
{
//seul certain element sont a prendre en compte
//(les tr, row, thead, etc... ne sont pas a prendre en compte)
if(goodTagForOffset.inArray(objTmp.nodeName))
{
tt+=objTmp.offsetTop;
lle+=objTmp.offsetLeft;
}
objTmp=objTmp.parentNode;
jj++;
}
//voila (lle,tt) forme les coordonnées de obj par rapport a la page...
//NB, faut p'etre encore prendre en compte le scrolling mais je ne pense pas)
if(!isIE)
{
//on place l'ellipsis
pt.style.top=tt+'px';
pt.style.left=lle+ll-pt.offsetWidth+'px';
pt.style.display='block';
pt.style.visibility='visible';
}

//Mise en place des eventhandler pour le survole
// cf doc ici : http://nexgenmedia.net/evang/iemozguide/
if(isIE)
{ //cf doc ici : http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/attachevent.asp
obj.attachEvent('onmouseover',ellipsis_onMouseOver);
}
else
{ //cf doc ici : http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html#Events-Event
obj.addEventListener('mouseover',ellipsis_onMouseOver,false); //action sans le prefix on
}
}
else
{
if(pt!=null && !isIE)
{
document.body.removeChild(pt); //on supprime l'ellipsis pour cet element, il n'en a plus besoin
}
//on detache les eventHandler de cet element puisqu'il 'rentre' dans son conteneur
if(isIE)
{
obj.detachEvent('onmouseover',ellipsis_onMouseOver);
}
else
{
obj.removeEventListener('mouseover',ellipsis_onMouseOver,false); //action sans le prefix on
}
}
}
}
return;
}

function ellipsis_onMouseOver(aEvent)
{
var myEvent = aEvent ? aEvent : window.event; //recuperation de l'evenement selon le navigateur
//on recupere cible de l'evenemet
var target= myEvent.target ? myEvent.target : myEvent.srcElement;
//on recupere sa position
var _top=target.offsetTop;
var _left=target.offsetLeft;
var objTmp=target.parentNode;
var jj=0; //anti boucle infine
while(objTmp!=document.body && jj<1000) //on limite à 1000 niveau d'imbrication
{
//seul certain element sont a prendre en compte
//(les tr, row, thead, etc... ne sont pas a prendre en compte)
if(goodTagForOffset.inArray(objTmp.nodeName))
{
_top+=objTmp.offsetTop;
_left+=objTmp.offsetLeft;
}
objTmp=objTmp.parentNode;
jj++;
}
longVersionEllipsis.innerHTML=target.innerHTML;
longVersionEllipsis.style.visibility='visible';
longVersionEllipsis.style.zIndex=ellipsisZIndex+1;
longVersionEllipsis.style.left=_left;
longVersionEllipsis.style.top=_top;
return;
}

Code source expliqué en détails

Je pense que que le code source est déjà assez commenté. Mais si un certains nombre de gens veulent plus de détails sur certains passage veuillez me le faire savoir.

Démonstration en ligne

Voici un exemple en ligne.

Téléchargement

Voici la source et l'exemple en téléchargement

Conclusion

J'ai développé ce script dans le but de recréer un comportement bien connu des utilisateurs d'environements graphique tel que windows. Avec le temps j'espère toutefois que ce comportement de tronquage via des petits points soit pleinement intégré aux spécifications de CSS. Quand à la gestion du survole de la sourie je pense pas que l'on puisse s'attendre à voir cela en natif dans les navigateurs avant quelques années... sinon à quoi on servirai encore nous autres développeurs!

Validation

Ce script a été testé et validé sous IE6 et Firefox en environement Windows XP.