11548 sujets

JavaScript, DOM et API Web HTML5

Bonsoir,

je reviens vers vous avec un nouveau problème. Du moins, cette fois j'ai une solution, mais pas très élégante, et je voulais savoir si quelqu'un avait une meilleure idée.

Voici donc le soucis:

j'ai une chaine de caractères et une position dans cette chaine. J'ai besoin à partir de cette position, de trouver la position du premier caractère parmis un certains nombre (par ex "(", ")" ou ",") dans le sens de la lecture mais aussi dans le sens inverse.

Pour ce faire, je peux bien sur par exemple tester chaque caractère avec indexOff, vérifier ceux qui apparaissent (car ce n'est pas forcément le cas), puis parmis tous ceux qui apparaissent, tester le plus petit écart avec ma position initiale. Et refaire la meme chose pour l'autre sens. Mais cette solution engendre beaucoup de tests qui augmentent de facon exponentiel à chaque fois que je vais vouloir ajouter un de ces caractères "spéciaux". De plus ce n'est pas très optimiser.

Je me demandais alors (mais je n'ai pas réussi à le faire marcher ni meme à savoir si c'est possible) s'il était possible avec par ex indexOff de lui filer en paramètre non pas un caractère à retrouver, mais une liste des caractères, soit sous la forme d'un tableau, soit à l'aide d'une expression régulière ?

toute autre idée plus élégante que la mienne sera la bien venue !

merci par avance

NiHaoMa
Il faut utiliser les expressions régulières.
Supposons d'abord que tu recherches les caractères dans le morceau de chaîne qui se trouve après la position du curseur.
Tu construits d'abord une expression régulière avec comme pattern :
"(.*?)([tes caractères]{1}.*)" ;
Tu récupères la sous chaîne "souschaine" correspondant au groupe 1 ($1) ;
Enfin souschaine.length te donne la position du premier de tes caractères depuis ta position dans ta chaîne de départ.
Pour le sens inverse de lecture, tu peux soit retourner ta chaîne et procéder de même, soit lui appliquer une regex avec comme pattern :
"(.*[tes caractères]{1})([^tes caractères])" et là tu récupères le groupe 2 évdemment.
Modifié par mathmax (31 Jan 2007 - 20:48)
encore toi !!! Smiley smile

bon, je penses avoir compris ce que tu veux dire, mais j'ai un peu de mal à savoir comment le mettre en place par le code (désolé, je suis pas un pro en JS)...puis-je abuser un peu et te demander un p'tit bout de code pour illustrer ta solution ?

merci beaucoup de toute ton aide de la journée ! Smiley smile

NiHaoMa
ok, on repart de l'exemple précédent alors. Smiley cligne
Je considère que les caractères de choix sont "a" et "b", mais tu peux en spécifier d'autres...
Ce qui nous donne :


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Document sans nom</title>
<script>
function GetCursorPosition(myField) {
    //IE support
    if (document.selection) 
    {
        var tbx = document.getElementById("textbox").getAttribute("value");
        sel = document.selection.createRange();
        rst = document.getElementById("result");
        var pos = sel.getBookmark().charCodeAt(2) - 2;
        var droite = tbx.substring(pos, tbx.length);
        var gauche = tbx.substring(0, pos);
        var regdroite=new RegExp("(.*?)([ab]{1}.*)", "g");
        var schainedroite = droite.replace(regdroite,"$1");
        var reggauche=new RegExp("(.*[ab]{1})([^ab]*)", "g");
        var schainegauche = gauche.replace(reggauche,"$2");
        window.status = "position du premier caractère à gauche du curseur : "+ (gauche.match(reggauche) ? schainegauche.length : -1)
                     + " ; position du premier caractère à droite du curseur : "+ (droite.match(regdroite) ? schainedroite.length : -1);
    }
}


</script>
</head>

<body>
<form name="Form1">
    <input style="width:400px" value="zzzz a zzzz b zzz a zzz b zzz" onclick="GetCursorPosition(document.Form1.textbox)" id="textbox" type="text" />
    <p id="result"></p>
</form>
</body>
</html>


ps : on retourne -1, si aucun des caractères spécifiés ne se trouve à gauche (resp. à droite) du curseur.

Exécute ça sous IE pour la position du curseur. Je ne me suis pas amusé à récupérer la position du curseur sous FF. Le reste du code doit marcher sur les navigateurs standards.
re,

ca à l'air très bien, et crois bien que j'apprécie l'effort que tu fais pour moi, malheureusement en copiant/collant ton code et en le lancant sous IE 6 SP2, il ne fonctionne pas, il y à tjs écrit -1 pour le premier caractère à droite ou à gauche dans la StatusBar, et ceux, quelque soit là ou je clic.

désolé de t'embéter encore...

NiHaoMa
précision qui peut avoir son importance:
lorsque j'affiche ta réponse sur le forum, sous IE, j'ai une image qui ne s'affiche pas au milieur des 2 expression régulière...quand j'affiche sous FF, je vois ceci:

var regdroite=new RegExp("(.*?)( ab {1}.*)", "g");

et

var reggauche=new RegExp("(.* ab {1})([^ab]*)", "g");

est-ce bon ?
ça marche bien chez moi sous IE 7 et IE 6. Tu es sûr que la position du curseur est reconnue ? Essai de la remplacer par une valeur au milieu de la chaîne pour voir.
en essayant de trouver le problème (si t'en est que j'en sois capable), j'ai remarquer qu'en modifiant les expression regulière ainsi:

var regdroite=new RegExp("(.*?)( Smiley ab {1}.*)", "g");
et
var reggauche=new RegExp("(.* Smiley ab {1})([^ab]*)", "g");
(j'ai juste ajouter des crochet autour de ab dans chacunes d'elles)

j'ai cette fois des valeurs qui s'affichent, par contre, il semblerait qu'elle ne prennent pas en compte les espaces, par exemple avec la chaine suivante:
zzzz a zzzz
si je clic après le 2eme z du 2eme groupe, j'obtient pour droite: -1 (normal) et pour gauche 2, ce qui est effectviement le nombre de caractères entre le a et la position, mais sans compter les espaces
a écrit :

s'il était possible avec par ex indexOff de lui filer
en paramètre non pas un caractère à retrouver, mais une liste des caractères, soit sous la forme d'un tableau, soit à l'aide d'une expression régulière

La fonction que tu cherches s'appelle search. Elle a le même fonctionnement qu'indexOf, sauf qu'elle prend une regexp en paramètre plutôt qu'une chaîne.
Il n'y a par contre pas d'équivalent pour lastIndexOf, le plus simple étant de renverser la chaîne avec le code chaineRenversee = chaine.split("").reverse().join(""); ou alors avec une boucle.
mince c'est vrai que les crochets on sauté dans le code que je t'ai donné. Il faut évidemment en mettre. Les expressions régulières sont donc bien :
RegExp("(.*?)( Smiley ab {1}.*)", "g") et
RegExp("(.* Smiley ab {1})([^ab]*)", "g")

a écrit :
il semblerait qu'elle ne prennent pas en compte les espaces


Ca c'est parceque justement tu dois laisser une espace entre les crochet Smiley cligne
Modifié par mathmax (31 Jan 2007 - 22:02)
je suis désolé, mais je ne dois vraiment pas etre doué (encore moins que je le pensais lol), mais meme en mettant des espaces il y à toujours se décalage correspondant au nombre d'espaces en le curseur et la lettre "trouvée". De plus, si je ne met pas du tout d'espace dans la chaine (ce qui sera le cas dans l'utilisation future), ca reste à -1 pour les 2 tout le temps...

je dois probablement avoir fais une betises quelque part...pour plus de surreté, crois tu que tu pourais m'envoyer ton code directement sur ma messagerie stp ? (adsofts@gmail.com)
merci encore !!
bon décidément j'ai la poisse. Ce code ne semble pas marcher en ligne. Je te propose de le télécharger et de l'exécuter en local.
Je pense que c'est la position du curseur qui doit poser problème en ligne. Si c'est le cas, reprend ton code de l'autre post et tout devrait rentrer dans l'ordre... j'espère.
Ca marche chez toi en ligne ?
Modifié par mathmax (31 Jan 2007 - 22:13)
Salut c encore moi ! ca faisait longtemps n'est-ce pas ?? lol

juste une petite question au cas ou, meme si là je suis presque certain que ce n'est pas possible en JS...

y'a t-il moyen de récupérer la taille en pixel d'une chaine (donc en tenant compte de la 'family', 'size' et 'style' des différents caractères) ?

j'ai beau chercher sur le net anglo/francophone, je ne trouve rien...j'imagine que c'est probablement parceque ce n'est pas possible, mais vu que tu semble plutot à l'aise avec JS, je tente ma chance quand meme Smiley cligne

merci par avance (encore ! lol)

NiHaoMa