Taille "réelle" d'une chaîne de caractères

Taille "réelle" d'une chaîne de caractères - HTML/CSS - Programmation

Marsh Posté le 21-05-2008 à 11:02:25    

Bonjour,
 
Je souhaiterais faire un input text dont la taille s'adapte à la longueur du contenu.
Pour l'instant je fais "input.size  = input.value.length * 1.1" : Ca marche pas trop mal mais ma police n'étant pas à taille fixe, ça s'adapte plus ou moins bien.
 
Existe-t-il une méthode qui permet de connaitre la taille réelle de la chaine affichée ?  
 
Merci.

Reply

Marsh Posté le 21-05-2008 à 11:02:25   

Reply

Marsh Posté le 22-05-2008 à 15:09:20    

Vraiment pas ?

Reply

Marsh Posté le 22-05-2008 à 16:54:45    

Bob2024 a écrit :

Bonjour,

 

Je souhaiterais faire un input text dont la taille s'adapte à la longueur du contenu.
Pour l'instant je fais "input.size  = input.value.length * 1.1" : Ca marche pas trop mal mais ma police n'étant pas à taille fixe, ça s'adapte plus ou moins bien.

 

Existe-t-il une méthode qui permet de connaitre la taille réelle de la chaine affichée ?

 

Merci.


input.style.width = (input.value.length*1.05) + 'ex';

 


je te rappelle que le size est une valeur entiere, donc ca ne marchera pas vraiment bien en attaquant le size, mais en attaquant le width et en utiliser le ex comme unité, car risque de mieux marcher
\o/


Message édité par gatsu35 le 22-05-2008 à 16:55:35
Reply

Marsh Posté le 23-05-2008 à 00:38:48    

Bien vu, j'essaye ça demain. En revanche un x est toujours plus grand qu'un i ... Je verrais bien. Merci en tout cas, je ne connaissais pas cette unité.

Reply

Marsh Posté le 23-05-2008 à 10:22:56    

S'il faut vraiment quelque chose de précis (de sorte par exemple de pouvoir s'en sortir pas très mal dans des situations où il y a cinquante "m" comme là où il y a cinquante "i" à la suite), la seule solution que je vois, c'est de faire la même chose qu'en programmation ordinaire pour le GUI de Windows : d'avoir une liste des largeurs de chaque lettre, puis d'additionner les largeurs de toutes les lettres au sein d'une chaine de caractères, puis d'y ajouter les largeurs occupées par les espaces entre les lettres.
En revanche, si avec l'API de Windows, c'est possible d'avoir les largeurs directement, ce n'est pas vraiment possible avec JavaScript. La solution, c'est donc (via une boucle) d'afficher des <span> avec chaque lettre, puis de mesurer leur largeur (toujours via la boucle) et enregistrer les résultats pour pouvoir les utiliser ensuite dans un site.
 
Et finalement, les problèmes habituels qui se posent : premièrement, le client n'a pas forcement la police des caractères qu'il faut. Deuxièmement, on ne peut définir une taille fixe aux caractères, donc la largeur de la zone du texte ne peut non plus être en pixels.
Plus grave enfin, le client peut très bien changer la taille du texte une fois la page chargée (et il peut vouloir le faire à chaque fois, par exemple lorsque le texte de la page est excessivement grand ou petit) ; s'il le fait, ça risque de faire moche au niveau de la largeur du texte...

Reply

Marsh Posté le 23-05-2008 à 14:32:18    

Ok. Je ne vais pas faire ça en fait... Mais merci pour l'info. Et puis, pas de regrets d'être passé à coté d'un truc simple.

Reply

Marsh Posté le 23-05-2008 à 16:22:24    

Hmm, ça ne serait pas encore plus "simple" de faire un div en overflow: hidden, position: absolute, padding: 0, margin: 0, tu mets ton texte la dedans, avec le même style de police que ta zone de texte, et zou tu récupère la largeur de la chaine via tonDiv.clientWidth (Ça devrait fonctionner même avec IE6 et des versions anté-dilluviennes de Safari).
 
Perso, je trouve que ça fait encore trop méthode goret, mais bon c'est toi qui voit ...

Reply

Marsh Posté le 23-05-2008 à 17:27:00    

tpierron a écrit :

Hmm, ça ne serait pas encore plus "simple" de faire un div en overflow: hidden, position: absolute, padding: 0, margin: 0, tu mets ton texte la dedans, avec le même style de police que ta zone de texte, et zou tu récupère la largeur de la chaine via tonDiv.clientWidth (Ça devrait fonctionner même avec IE6 et des versions anté-dilluviennes de Safari).


Yo ! Mais c'est trop pas bête du tout, ce truc !  :bounce:
 
Bravo.

Reply

Marsh Posté le 23-05-2008 à 18:02:14    

C'était trop beau, je ne sais pas pourquoi mais madiv.clientWidth me répond systématiquement 0. Je ne comprends pas pourquoi.

Reply

Marsh Posté le 23-05-2008 à 18:11:30    

Vous pouvez donner l'HTML/JS de la page ?

Reply

Marsh Posté le 23-05-2008 à 18:11:30   

Reply

Marsh Posté le 23-05-2008 à 20:14:20    

C'est moi que tu vouvoies ?
Si oui, bin, pas avant lundi... Ca me dirais bien que ça marche au poil, ça ferait vraiment classe.

Reply

Marsh Posté le 23-05-2008 à 20:17:35    

Bob2024 a écrit :

C'est moi que tu vouvoies ?


Oui. Faut pas ?  :D  
 
Evidemment, parce que sans le code source sous les yeux, on risque pas de pouvoir t'aider sur une erreur qui vient justement du code...

Reply

Marsh Posté le 24-05-2008 à 06:53:17    

Bob2024 a écrit :

C'était trop beau, je ne sais pas pourquoi mais madiv.clientWidth me répond systématiquement 0. Je ne comprends pas pourquoi.


 
Si tu as mis un display:none sur le div en question il fera toujours 0 de haut :D
tu utilises un SPAN plutot qu'un div, (cela permettra de le mettre même dans un <p> et donc de le placer au même endroit que le input).
Ensuite tu lui mets les proporiétés : position:absolute; left:0; top:0; width:0; height:0; visibility:hidden; white-space:nowrap (pour pas que le texte revienne à la ligne),  
et aussi le meme font-family. et un font-size de 100% (onest jamais sur de rien dixit la CSS déclare aussi des font-sizes qui changent pour les span.
 
 
et tu essayes de récupérer son scrollWidth

Reply

Marsh Posté le 24-05-2008 à 13:24:23    

gatsu35 a écrit :

Si tu as mis un display:none sur le div en question il fera toujours 0 de haut :D
tu utilises un SPAN plutot qu'un div, (cela permettra de le mettre même dans un <p> et donc de le placer au même endroit que le input).
Ensuite tu lui mets les proporiétés : position:absolute; left:0; top:0; width:0; height:0; visibility:hidden; white-space:nowrap (pour pas que le texte revienne à la ligne),  
et aussi le meme font-family. et un font-size de 100% (onest jamais sur de rien dixit la CSS déclare aussi des font-sizes qui changent pour les span.
et tu essayes de récupérer son scrollWidth


Personne ne parlant d'un display:none. Et puis je ne vois pas ce qui change entre un <span> et un <div>, ni à quoi ça sert de le placer dans un même endroit que la zone dont il faut changer la largeur.
Quant à font-family et font-size, je suis d'accord que c'est mieux de les définir pour les deux éléments.
 
 
Un chouyatique exemple avec un <div>. J'ai pas mis de white-space:nowrap ; il faut le mettre, bien sûr.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>Untitled</title>
  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
  <style type="text/css">
  body{font-family:Verdana,Sans-Serif;font-size:80%;padding:0;margin:5%;}
  #Etalon{visible:hidden;position:absolute;top:-50px;}
  #TrucVisible{border:solid 1px #000;margin:20px;}
  </style>
  <script type="text/javascript">
function addEvent(obj, evType, fn) {
  // Code from http://onlinetools.org/articles/unobtrusivejavascript/chapter4.html
  if (obj.addEventListener) {  
    obj.addEventListener(evType, fn, true);  
    return true;
  }
  else if (obj.attachEvent) {  
    var r = obj.attachEvent("on" + evType, fn);  
    return r;  
  }
  else {  
    return false;  
  }  
}
 
addEvent(window, 'load', OnLoad);
 
function OnLoad() {
  objEtalon = document.getElementById('Etalon');
  objTruc = document.getElementById('TrucVisible');
  if (objEtalon && objTruc)
  {
    Largeur = objEtalon.clientWidth;
    objDebug = document.getElementById('DebugOutput');
    if (objDebug) objDebug.innerHTML = 'La largeur du texte est de ' + Largeur + ' pixels';
    objTruc.style.width = (Largeur) + 'px';
  }
}
  </script>
</head>
<body>
  <div id="Etalon">Hello World!</div>
  <h2>Détermination de la largeur metrique d'un texte</h2>
  <div id="TrucVisible">Hello World!</div>
  <div id="DebugOutput"></div>
</body>
</html>

Reply

Marsh Posté le 24-05-2008 à 13:44:18    

MainMa a écrit :


Personne ne parlant d'un display:none. Et puis je ne vois pas ce qui change entre un <span> et un <div>,


Parce que c'est pour mettre au même endroit que l'input. ET si l'input est dans un <p>
si on met un <div> dans un <p>, le <p> se refermera juste avant le div (comportement du navigateur et dans la norme html on ne peut mettre que des éléments inlines dans un <p> )
et cela pourrait cause des pb au niveau HTML.

MainMa a écrit :


ni à quoi ça sert de le placer dans un même endroit que la zone dont il faut changer la largeur.
Quant à font-family et font-size, je suis d'accord que c'est mieux de les définir pour les deux éléments.


Justement si je met le <span> au même niveau que le <input> c'est pour prendre en considération le fait que l'utilisateur pourrait déclarer des font-size en em, et si tu essayes de récupérer le font-size en em sur l'input, selon le navigateur tu récupèreras un font-size en px (firefox), ou en em (Internet explorer)


Message édité par gatsu35 le 24-05-2008 à 13:44:49
Reply

Marsh Posté le 24-05-2008 à 13:47:48    

D'accord. Je vois.

Reply

Marsh Posté le 24-05-2008 à 20:26:23    

MERCI !!
J'ai fais ça rapidement avec ton code :

Code :
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3. <head>
  4.   <title>Untitled</title>
  5.   <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
  6.   <style type="text/css">
  7.   body{font-family:Verdana,Sans-Serif;font-size:80%;padding:0;margin:5%;}
  8.   #Etalon{visibility:hidden;position:absolute;top:-50px;white-space:nowrap;}
  9.   </style>
  10.   <script type="text/javascript">
  11. function addEvent(obj, evType, fn) {
  12.   // Code from http://onlinetools.org/articles/un [...] pter4.html
  13.   if (obj.addEventListener) { 
  14.     obj.addEventListener(evType, fn, true); 
  15.     return true;
  16.   }
  17.   else if (obj.attachEvent) { 
  18.     var r = obj.attachEvent("on" + evType, fn); 
  19.     return r; 
  20.   }
  21.   else
  22.     return false
  23.   } 
  24. }
  25. addEvent(window, 'load', OnLoad);
  26. function OnLoad() {
  27.   objTruc = document.getElementById('TrucVisible');
  28.   adapteTaille(objTruc)
  29. }
  30. function adapteTaille(obj)
  31. {
  32. objEtalon = document.getElementById('Etalon');
  33.    objTruc = obj;
  34.    objEtalon.innerHTML = objTruc.value;
  35.   if (objEtalon && objTruc)
  36.   {
  37.     Largeur = objEtalon.clientWidth;
  38.     objDebug = document.getElementById('DebugOutput');
  39.     if (objDebug) objDebug.innerHTML = 'La largeur du texte est de ' + Largeur + ' pixels';
  40.     objTruc.style.width = (Largeur) + 'px';
  41.   }
  42. }
  43.   </script>
  44. </head>
  45. <body>
  46.   <div id="Etalon"></div>
  47.   <h2>Détermination de la largeur metrique d'un texte</h2>
  48.   <div id="DebugOutput"></div>
  49.   <input type="texte" id="TrucVisible" value="Hello World!" onKeyPress="adapteTaille(this)"/>
  50. </body>
  51. </html>
 

Reste deux soucis :
1. J'ai testé sous IE7 et FF or, au boulot, c'est IE6 forcé et ce code ressemble beaucoup à ce que j'avais fait ... On verra bien.
2. Les espaces foutent un peu le bordel.

 

En tout cas merci les gars, z'êtes bien sympa ;)

 

Edit : pont 2 résolue par un "objEtalon.innerHTML = objTruc.value.replace(/ /g,'&nbsp;');", bien sûr.


Message édité par Bob2024 le 24-05-2008 à 20:53:13
Reply

Marsh Posté le 24-05-2008 à 23:25:03    

ppour la ligne ou tu remplaces l'espace par un espace insécable, je trouve cette ligne inutile à partir du moment ou tu utilises un white-space:nowrap dans les styles de objEtalon

Reply

Marsh Posté le 25-05-2008 à 11:29:14    

C'est pas le saut de ligne qui me gênait, mais l'espace en bout de chaine (au moment de la frappe de l'espace, ça n'élargit pas le div étalon donc ça décale...) ou la répétition d'espaces (cas vraisemblablement inutile mais ça ressemble à un bug).

 

Edit : Le code qui marche finalement :

Citation :


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>Untitled</title>
  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
  <style type="text/css">
  body{font-family:Verdana,Sans-Serif;font-size:80%;padding:0;margin:5%;}
  #Etalon{position:absolute;top:-50px;white-space:nowrap;font-family:Verdana,Sans-Serif;font-size:80%;}
  #TrucVisible{font-family:Verdana,Sans-Serif;font-size:80%;}
  </style>
  <script type="text/javascript">
function addEvent(obj, evType, fn) {
  // Code from http://onlinetools.org/articles/un [...] pter4.html
  if (obj.addEventListener) {  
    obj.addEventListener(evType, fn, true);  
    return true;
  }
  else if (obj.attachEvent) {  
    var r = obj.attachEvent("on" + evType, fn);  
    return r;  
  }
  else {  
    return false;  
  }  
}
 
addEvent(window, 'load', OnLoad);
 
function OnLoad() {
  objTruc = document.getElementById('TrucVisible');
  adapteTaille(objTruc)
}

 

function adapteTaille(obj)
{
 objEtalon = document.getElementById('Etalon');
   objTruc = obj;
   objEtalon.innerHTML = objTruc.value.replace(/ /g,'&nbsp;');
   
  if (objEtalon && objTruc)
  {
    Largeur = objEtalon.clientWidth;
    objDebug = document.getElementById('DebugOutput');
    if (objDebug) objDebug.innerHTML = 'La largeur du texte est de ' + Largeur + ' pixels';
    Largeur += 15;
    objTruc.style.width = (Largeur) + 'px';
  }
}

 

 </script>
</head>
<body>
  <div id="Etalon"></div>
  <h2>Détermination de la largeur metrique d'un texte</h2>
  <div id="DebugOutput"></div>
  <input type="texte" id="TrucVisible" value="Hello World!" onKeyPress="adapteTaille(this)" onKeyUp="adapteTaille(this)"/>
</body>
</html>

 

La répétition de la police pour tout le monde : bin, je sais pas pourquoi mais ça ne voulait pas marcher sans donc voilà.
Le visibility:hidden semble interdire la prise en compte de la police donc : simple décalage en dehors de la fenêtre.
l'ajout de l'évènement onKeyUp c'est pas très classe en effet mais voilà : j'ai besoin du onKeyPress pour prendre en compte la répétition automatique or au onKeyPress la dernière frappe n'est pas encore dans le value donc onKeyUp en plus epissétou. (de toute façon c'est le client qui trinque donc je m'en tape un peu).

 

Voilà voilà, merci à tous.

 

Edit : Bin voilà, ça marche au poil sous IE6... Je devais être bourré vendredi...
Encore merci.


Message édité par Bob2024 le 26-05-2008 à 10:57:15
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed