Arto_8000
Messages postés1044Date d'inscriptionlundi 7 mars 2005StatutMembreDernière intervention13 juillet 2010
-
20 mars 2010 à 17:44
jdmcreator
Messages postés647Date d'inscriptionsamedi 30 décembre 2000StatutMembreDernière intervention20 juillet 2012
-
25 mars 2010 à 23:56
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.
jdmcreator
Messages postés647Date d'inscriptionsamedi 30 décembre 2000StatutMembreDernière intervention20 juillet 20127 25 mars 2010 à 23:56
-_-
Une petite question, pourquoi n'utilise dont pas ma solution. Elle est encore plus optimisé et prend moins de place
---> 163 caractères pour moi et + de 5000 pour toi O_O
5000 caractères !!!! C'est 5, 218 KO !!!! C'est le cinquième de la taille de JQuery, qui fait des centaines de fonctionnalité de plus !!!
Désolé, mais je ne comprends pourquoi tu ne regardes pas ma solution, elle est cross-browser : testé avec Safari, IE, Firefox, Opéra et Chrome et surtout, mais SURTOUT, elle prend 33 fois moins d'espace !!! Désolé mon emportement, mais ça dépasse ma logique ^^ Quelqu'un pour me dire ce qui cloche dans la fonction ? Y a-t-il un bug (je peux essayer de régler) ? Ou alors la fonction est-elle trop simple ?
zen69
Messages postés584Date d'inscriptionjeudi 28 décembre 2006StatutMembreDernière intervention29 avril 20101 25 mars 2010 à 18:11
Bon finalement voici la fonction complète et révisé.
Quelques modifications depuis mon dernier commentaire....
J'ai enlever la clause insensitive de l'exp reg afin de ne pas mélanger par example É et é
J'ai complèté la liste des caractères.
J'ai ajouté un condition undefined aux entités qui commence avec un # puisqu'elles sont extraites de la variable entities.
J'ai aussi modifié la longueur des entitiés nommées comme À pour prendre l'entitée complète 4 étant trop court.
Encore une fois merci à Arto_8000 pour sa grande aide!!
zen69
Messages postés584Date d'inscriptionjeudi 28 décembre 2006StatutMembreDernière intervention29 avril 20101 25 mars 2010 à 16:48
Correction voici la fonction que j'utilise maintenant,
if (matches != null) {
for (i=0; i<matches.length; i++) {
var code = matches[i].substring(1,matches[i].length-1);
if (code.charAt(0) == "#") {
html = html.replace(matches[i], nameEntities[code.substr(1)]);
} else {
if (typeof nameEntities[code] != "undefined") {
html = html.replace(matches[i], nameEntities[code]);
}
}
}
}
return html;
}
je n'ai pas mis toutes les entités pour faire plus court...
Merci bcp Arto_8000
zen69
Messages postés584Date d'inscriptionjeudi 28 décembre 2006StatutMembreDernière intervention29 avril 20101 25 mars 2010 à 16:41
Arto_8000: Merci beaucoup pour ces précision sur le replace avec et sans regexp, je n'étais pas au fait du fonctionnement et des différences entre les deux, mis-à-part du fait qu'un s'applique sur une exp reg et l'autre sur un string...
Ouin escape je connais mais finalement je dois le combiné avec fromCharCode...
Petite précision : on devrait plutôt indiquer <script type="application/javascript"> selon les dernières nouvelles mais je n'ai pas encore eu la confirmation que tous les navigateurs le comprendront
Arto_8000
Messages postés1044Date d'inscriptionlundi 7 mars 2005StatutMembreDernière intervention13 juillet 20107 24 mars 2010 à 15:32
Il faut que tu comprennes d'abord qu'il y a une grosse différence entre un replace avec regexp et sans regexp. Un replace simple prend beaucoup moins de temps à s'exécuter qu'un regexp avec une expression régulière. Une expression régulière doit être compilé et après être exécuté. En plus, un replace avec une expression régulière ne s'arrête pas après la première occurrence. Un replace simple est beaucoup plus ciblé contrairement à un replace avec un regexp.
"Je ne sais pas s'il y a un équivalent à String.fromCharCode pour transformer en hex, mais d'ici à ce que je trouve, je ne changerai pas ma fonction."
zen69
Messages postés584Date d'inscriptionjeudi 28 décembre 2006StatutMembreDernière intervention29 avril 20101 24 mars 2010 à 14:59
Arto_8000: mais disons que j'ai 250 accents aiguë dans mon string. Il va faire le replace 250 fois non?
Si tel est le case, c'est plus optimisé selon l'utilisation qu'on en fait...?
De plus ma fonction retournais un chaîne hex... contrairement à ta fonction qui retourne les caractères décodés.
Je ne sais pas s'il y a un équivalent à String.fromCharCode pour transformer en hex, mais d'ici à ce que je trouve, je ne changerai pas ma fonction.
Arto_8000
Messages postés1044Date d'inscriptionlundi 7 mars 2005StatutMembreDernière intervention13 juillet 20107 23 mars 2010 à 22:19
"ta fonction est très loin d'être complète"
La seule chose qui manque c'est de compléter la liste des entités avec des noms et la seule raison pour laquelle je l'ai pas fait au complète c'est que de 1 ça prend énormément de place dans les commentaires et de deux n'importe qui peut compléter la liste à partir de liste facilement trouvable sur le web. Ce que j'ai voulu montré c'est l'algorithme le plus intéressant pour faire ce genre d'opération.
"cependant ta fonction elle effectue plusieurs opérations pour chaque match"
C'est très floue comme affirmation et pas tout à fait vrai. Comme tel il y a un seul replace (sans regexp) qui est fait par match.
BaFM
Messages postés64Date d'inscriptionmercredi 24 juillet 2002StatutMembreDernière intervention26 novembre 2009 23 mars 2010 à 20:06
Entre une solution lente et qui ne fait pas tous les cas et une solution qui nécessite quelques minutes de recherche pour être compatible tout navigateur. Je préfère la dernière.
Et il y a d'autres manières de faire passer sans problème d'encodage ces éléments.
zen69
Messages postés584Date d'inscriptionjeudi 28 décembre 2006StatutMembreDernière intervention29 avril 20101 23 mars 2010 à 19:22
BaFM : une autre technique est de lire de descriptif avant de posté.
J'utilise la fonction pour mes alert() et mes confirm(...), et le n'avigateur ne fait justement pas la conversion tout seul. Et dans ta pseudo solution tu évoques toi même qu'elle ne fonctionne pas partout!
zen69
Messages postés584Date d'inscriptionjeudi 28 décembre 2006StatutMembreDernière intervention29 avril 20101 23 mars 2010 à 18:50
Arto_8000: ta fonction est très loin d'être complète. Cependant je comprend bien que dans ton exemple il va faire le replace seulement à la mesure des matchs trouvé ce qui est bien, cependant ta fonction elle effectue plusieurs opérations pour chaque match.
Merci tout de même pour ta précision, je tenterai d'optimisé à l'aide de ce que tu as dis, quand j'aurai du temps, si le coeur m'en dit.
jdmcreator
Messages postés647Date d'inscriptionsamedi 30 décembre 2000StatutMembreDernière intervention20 juillet 20127 23 mars 2010 à 00:52
BaFM : Il peut y avoir des problèmes de compatibilité.
En effet, sous Firefox il faut utiliser element.contentText. J'ai aussi déjà entendu parler vaguement d'un element.style.content mais je n'en ai jamais vu d'utilisation
BaFM
Messages postés64Date d'inscriptionmercredi 24 juillet 2002StatutMembreDernière intervention26 novembre 2009 22 mars 2010 à 09:29
Une autre technique consite à utiliser le fait que le navigateur sait faire cette conversion tout seul. Créer un élément, définir son texte HTML (innerHTML), récupérer sont texte décoder (innerText).
Il peut y avoir des problèmes de compatibilité.
Arto_8000
Messages postés1044Date d'inscriptionlundi 7 mars 2005StatutMembreDernière intervention13 juillet 20107 20 mars 2010 à 17:44
Je doute très fortement que faire 340 replace avec des expressions régulières en javascript soit la meilleur solution pour faire cette tâche qui n'est pas si complexe. Surtout que le seul truc qui est à hardcoder c'est les équivalences pour les entités avec les noms. Oublie pas que les replaces avec les regexp parcourent toute la chaîne, donc ton script parcoure à tout coup 340 fois la même chaîne ce qui est évidemment lourd.
Un algorythme plus optimisé (et plus simple) devrait ressembler à quelque chose comme ceci :
25 mars 2010 à 23:56
Une petite question, pourquoi n'utilise dont pas ma solution. Elle est encore plus optimisé et prend moins de place
---> 163 caractères pour moi et + de 5000 pour toi O_O
5000 caractères !!!! C'est 5, 218 KO !!!! C'est le cinquième de la taille de JQuery, qui fait des centaines de fonctionnalité de plus !!!
Désolé, mais je ne comprends pourquoi tu ne regardes pas ma solution, elle est cross-browser : testé avec Safari, IE, Firefox, Opéra et Chrome et surtout, mais SURTOUT, elle prend 33 fois moins d'espace !!! Désolé mon emportement, mais ça dépasse ma logique ^^ Quelqu'un pour me dire ce qui cloche dans la fonction ? Y a-t-il un bug (je peux essayer de régler) ? Ou alors la fonction est-elle trop simple ?
Je reposte :
-----------
function convertToHex(ty){
tn=document.createElement("div");
tn.innerHTML=ty;
yn= tn.innerText || tn.textContent || tn.style.content;
return escape(yn);
}
/*Utilisation*/
alert(unescape(convertToHex("" + é")));
25 mars 2010 à 18:11
Quelques modifications depuis mon dernier commentaire....
J'ai enlever la clause insensitive de l'exp reg afin de ne pas mélanger par example É et é
J'ai complèté la liste des caractères.
J'ai ajouté un condition undefined aux entités qui commence avec un # puisqu'elles sont extraites de la variable entities.
J'ai aussi modifié la longueur des entitiés nommées comme À pour prendre l'entitée complète 4 étant trop court.
Encore une fois merci à Arto_8000 pour sa grande aide!!
25 mars 2010 à 16:48
function html_decode(html) {
var matches = html.match(/&(#[0-9]{1,3}|[a-z]{2,6});/gi);
var nameEntities = {
quot : "%22",
apos : "%27",
amp : "%26",
lt : "%3C",
gt : "%3E",
nbsp : "%A0",
agrave : "%E0",
224 : "%E0",
32 : "%A0"
}
if (matches != null) {
for (i=0; i<matches.length; i++) {
var code = matches[i].substring(1,matches[i].length-1);
if (code.charAt(0) == "#") {
html = html.replace(matches[i], nameEntities[code.substr(1)]);
} else {
if (typeof nameEntities[code] != "undefined") {
html = html.replace(matches[i], nameEntities[code]);
}
}
}
}
return html;
}
je n'ai pas mis toutes les entités pour faire plus court...
Merci bcp Arto_8000
25 mars 2010 à 16:41
Ouin escape je connais mais finalement je dois le combiné avec fromCharCode...
Voici donc ce que j'utilise maintenant
function html_decode(html) {
var matches = html.match(/&(#[0-9]{1,3}|[a-z]{2,6});/gi);
var nameEntities = {
quot : "%22",
apos : "%27",
amp : "%26",
lt : "%3C",
gt : "%3E",
nbsp : "%A0",
agrave : "%E0",
224 : "%E0",
}
if (matches != null) {
for (i=0; i<matches.length; i++) {
var code = matches[i].substring(1,matches[i].length-1);
if (code.charAt(0) == "#") {
html = html.replace(matches[i], escape(String.fromCharCode(code.substr(1))));
} else {
if (typeof nameEntities[code] != "undefined") {
html = html.replace(matches[i], nameEntities[code]);
}
}
}
}
return html;
}
25 mars 2010 à 00:05
<script type="text/javascript">
function convertToHex(ty){
tn=document.createElement("div");
tn.innerHTML=ty;
yn= tn.innerText || tn.textContent || tn.style.content;
return escape(yn);
}
alert(unescape(convertToHex("" + é")));
</script>
Petite précision : on devrait plutôt indiquer <script type="application/javascript"> selon les dernières nouvelles mais je n'ai pas encore eu la confirmation que tous les navigateurs le comprendront
24 mars 2010 à 15:32
"Je ne sais pas s'il y a un équivalent à String.fromCharCode pour transformer en hex, mais d'ici à ce que je trouve, je ne changerai pas ma fonction."
Cette fonction s'appelle escape.
https://developer.mozilla.org/fr/Guide_JavaScript_1.5/Fonctions_pr%C3%A9d%C3%A9finies/Les_fonctions_escape_et_unescape
24 mars 2010 à 14:59
Si tel est le case, c'est plus optimisé selon l'utilisation qu'on en fait...?
De plus ma fonction retournais un chaîne hex... contrairement à ta fonction qui retourne les caractères décodés.
Je ne sais pas s'il y a un équivalent à String.fromCharCode pour transformer en hex, mais d'ici à ce que je trouve, je ne changerai pas ma fonction.
23 mars 2010 à 22:19
La seule chose qui manque c'est de compléter la liste des entités avec des noms et la seule raison pour laquelle je l'ai pas fait au complète c'est que de 1 ça prend énormément de place dans les commentaires et de deux n'importe qui peut compléter la liste à partir de liste facilement trouvable sur le web. Ce que j'ai voulu montré c'est l'algorithme le plus intéressant pour faire ce genre d'opération.
"cependant ta fonction elle effectue plusieurs opérations pour chaque match"
C'est très floue comme affirmation et pas tout à fait vrai. Comme tel il y a un seul replace (sans regexp) qui est fait par match.
23 mars 2010 à 20:06
Et il y a d'autres manières de faire passer sans problème d'encodage ces éléments.
23 mars 2010 à 19:22
J'utilise la fonction pour mes alert() et mes confirm(...), et le n'avigateur ne fait justement pas la conversion tout seul. Et dans ta pseudo solution tu évoques toi même qu'elle ne fonctionne pas partout!
23 mars 2010 à 18:50
Merci tout de même pour ta précision, je tenterai d'optimisé à l'aide de ce que tu as dis, quand j'aurai du temps, si le coeur m'en dit.
23 mars 2010 à 00:52
En effet, sous Firefox il faut utiliser element.contentText. J'ai aussi déjà entendu parler vaguement d'un element.style.content mais je n'en ai jamais vu d'utilisation
22 mars 2010 à 09:29
Il peut y avoir des problèmes de compatibilité.
20 mars 2010 à 17:44
Un algorythme plus optimisé (et plus simple) devrait ressembler à quelque chose comme ceci :
function html_decode(html) {
var matches = html.match(/&(#[0-9]{1,3}|[a-z]{2,4});/gi);
var nameEntities = {
quot : """,
apos : "'",
amp : "&",
lt : "<",
gt : ">",
nbsp : " "
}
if (matches != null) {
for (i=0; i<matches.length; i++) {
var code = matches[i].substring(1,matches[i].length-1);
if (code.charAt(0) == "#") {
html = html.replace(matches[i], String.fromCharCode(code.substr(1)));
} else {
if (typeof nameEntities[code] != "undefined") {
html = html.replace(matches[i], nameEntities[code]);
}
}
}
}
return html;
}