Toon posts:

[Javascript] IE Bug?

Pagina: 1
Acties:

Verwijderd

Topicstarter
Hoi,

Ik zit met het volgende probleem. Ben nu al een tijdje bezig met TinyAjax, maar hier stuit ik op het volgende probleempje..

TinyAjax heeft namelijk een 'bugje' waardoor in de XML &-tekens en +-tekens niet mee kunnen worden verzonden in een string, echter deze heb ik wel nodig (voor een bestelscript).

Nu heb ik zelf de volgende oplossing hiervoor gevonden, namelijk een stukje javascript geschreven dat voordat de value van een text veld door xml geparsed wordt, de +-tekens en de &-tekens vervangen worden door (!!#43!!) en (!!and!!).

Dit gebeurt met deze functie:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
function htmlEntities(string)
{
  newString = string;
  for (var i = 0; i < newString.length; i++) {
    if (newString[i] == '&') {
      newString = newString.replace('&','(!!and!!)');
    }
    if (newString[i] == '+') {
      newString = newString.replace('+','(!!#43!!)');
    }
  }
  return newString;
}


Nu is het alleen zo,
wanneer ik in FireFox of opera dit doe:
PHP:
1
<input type="text" name="test" value="+" onchange="alert(htmlEntities(this.value));">


Er netjes (!!#43!!) in de popup komt te staan, doe ik dit echter in IE6+, dan komt er gewoon een +je te staan.

Bovenstaande oplossing werkt dus in firefox prima (ook met tinyajax), maar niet in IE..
Het lijkt haast wel of IE gewoon over de htmlEntities functie heenleest, kan iemand mij vertellen waarom?

  • whoami
  • Registratie: December 2000
  • Laatst online: 00:19
Client side zut horen thuis in WEB

-> WEB

https://fgheysels.github.io/


  • moozzuzz
  • Registratie: Januari 2005
  • Niet online
Ben je zeker dat de + herkend wordt in de replace? (want zoniet blijft jouw functie de originele waarde teruggeven).

\edit: Even je code getest en er wordt idd geen '+' herkend in de replace.
HTML:
1
2
3
4
5
6
7
<html><head><script>
....
</script>
</head>
<body>
<input type="text" name="test" value="+" onchange="alert(htmlEntities(this.value));"> 
</body></html>


JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function htmlEntities(s) 
{ 
    alert('0: '+s);
    newString = s; 
    alert('1: '+newString+', length: '+newString.length);

    for (var i = 0; i < newString.length; i++) { 
        if (newString[i] == '&') { 
            alert('2a1: '+newString);  
            newString = newString.replace('&','(!!and!!)'); 
            alert('2a1: '+newString);  
        } 
        if (newString[i] == '+') { 
            alert('2b1: '+newString);  
            newString = newString.replace('+','(!!#43!!)'); 
            alert('2b2: '+newString);  
        } 
    } 
    alert('3: '+newString);  
    return newString; 
} 


\edit2: wellicht omdat newString niet als array beschouwd wordt, ik zou persoonlijk de for-lus vervangen door een regex à la:
JavaScript:
1
2
3
4
5
function htmlEntities(s) 
{ 
    // regex is not my thing, don't shoot ;-P
    return s.replace(/\+/g, "#blah#").replace(/\&/g, "#blah2#");
}

[ Voor 176% gewijzigd door moozzuzz op 14-07-2006 18:07 ]


Verwijderd

Topicstarter
moozzuzz schreef op vrijdag 14 juli 2006 @ 17:29:
Ben je zeker dat de + herkend wordt in de replace? (want zoniet blijft jouw functie de originele waarde teruggeven).

\edit: Even je code getest en er wordt idd geen '+' herkend in de replace.
HTML:
1
2
3
4
5
6
7
<html><head><script>
....
</script>
</head>
<body>
<input type="text" name="test" value="+" onchange="alert(htmlEntities(this.value));"> 
</body></html>


JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function htmlEntities(s) 
{ 
    alert('0: '+s);
    newString = s; 
    alert('1: '+newString+', length: '+newString.length);

    for (var i = 0; i < newString.length; i++) { 
        if (newString[i] == '&') { 
            alert('2a1: '+newString);  
            newString = newString.replace('&','(!!and!!)'); 
            alert('2a1: '+newString);  
        } 
        if (newString[i] == '+') { 
            alert('2b1: '+newString);  
            newString = newString.replace('+','(!!#43!!)'); 
            alert('2b2: '+newString);  
        } 
    } 
    alert('3: '+newString);  
    return newString; 
} 


\edit2: wellicht omdat newString niet als array beschouwd wordt, ik zou persoonlijk de for-lus vervangen door een regex à la:
JavaScript:
1
2
3
4
5
function htmlEntities(s) 
{ 
    // regex is not my thing, don't shoot ;-P
    return s.replace(/\+/g, "#blah#").replace(/\&/g, "#blah2#");
}
hm, stom dat hij het wel in firefox en opera doet dan :)
Maar ik ga eens even kloten met regex dan, heb er zelf ook nog weinig ervaring mee.. Dus we zullen zien :D

Thanks iig!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:30

crisp

Devver

Pixelated

replace is sowieso een regexp method, enkel als je daar een string aan voert wordt die eerst nog door de regexp-constructor heengehaald; dit:
JavaScript:
1
foo = foo.replace('+', '(!!and!!)');

is equivalent aan:
JavaScript:
1
foo = foo.replace(new RegExp('+'), '(!!and!!)');

Het enige 'probleem' is dan dat deze expressie niet 'global' is en dus enkel de eerste instance van het karakter zal vervangen; je hebt dus de global modifier nodig:
JavaScript:
1
2
3
foo = foo.replace(new RegExp('+', 'g'), '(!!and!!)');
// of als literal
foo = foo.replace(/+/g, '(!!and!!)');


maar persoonlijk zou ik het probleem bij de bron aanpakken in plaats van dergelijke ranzige workarounds; het lijkt me dat je een GET request doet en dat TinyAjax 'vergeet' te url-encoden?

Overigens is het feit dat je in IE van een string niet een enkel karakter kan opvragen door te doen alsof het een array van karakters is geen bug maar puur een tekortkoming; MS's JScript hangt immers nog een beetje op javascript 1.3 niveau (niet veel beter dan Netscape 4 dus :P) - het is sowieso niet volledig ECMA 262-compliant. Als je iets dergelijks nodig hebt zal je dus de charAt method moeten gebruiken...

[ Voor 22% gewijzigd door crisp op 15-07-2006 22:29 ]

Intentionally left blank


  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 23-12-2025

_Thanatos_

Ja, en kaal

crisp, je moet alleen die + nog ff escapen in je regex ;)

日本!🎌


  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:30

crisp

Devver

Pixelated

_Thanatos_ schreef op zondag 16 juli 2006 @ 14:04:
crisp, je moet alleen die + nog ff escapen in je regex ;)
mmmz, inderdaad - ik had eerlijk gezegd verwacht dat het in deze opzet niet zou hoeven aangezien het hier geen ambiguiteit oplevert, maar PCRE is soms nogal zeikerig :P

Intentionally left blank


Verwijderd

Topicstarter
crisp schreef op zaterdag 15 juli 2006 @ 22:16:
replace is sowieso een regexp method, enkel als je daar een string aan voert wordt die eerst nog door de regexp-constructor heengehaald; dit:
JavaScript:
1
foo = foo.replace('+', '(!!and!!)');

is equivalent aan:
JavaScript:
1
foo = foo.replace(new RegExp('+'), '(!!and!!)');

Het enige 'probleem' is dan dat deze expressie niet 'global' is en dus enkel de eerste instance van het karakter zal vervangen; je hebt dus de global modifier nodig:
JavaScript:
1
2
3
foo = foo.replace(new RegExp('+', 'g'), '(!!and!!)');
// of als literal
foo = foo.replace(/+/g, '(!!and!!)');


maar persoonlijk zou ik het probleem bij de bron aanpakken in plaats van dergelijke ranzige workarounds; het lijkt me dat je een GET request doet en dat TinyAjax 'vergeet' te url-encoden?

Overigens is het feit dat je in IE van een string niet een enkel karakter kan opvragen door te doen alsof het een array van karakters is geen bug maar puur een tekortkoming; MS's JScript hangt immers nog een beetje op javascript 1.3 niveau (niet veel beter dan Netscape 4 dus :P) - het is sowieso niet volledig ECMA 262-compliant. Als je iets dergelijks nodig hebt zal je dus de charAt method moeten gebruiken...
_Thanatos_ schreef op zondag 16 juli 2006 @ 14:04:
crisp, je moet alleen die + nog ff escapen in je regex ;)
Deze combo is idd een oplossing voor mijn probleem, thanks!
Ik doe btw geen GET request maar een POST, en in TinyAjax (Zonder de htmlEntities functie) ziet die post er dan als volgt uit:
PHP:
1
rs=checkField&rsargs[]=debiteur_telefoon_landnummer&rsargs[]=+31&rsargs[]=6&rsargs[]=6&rsargs[]=2&rsargs[]=Debiteur telefoon landnummer


Ik vraag me alleen af waarom hij dan problemen met de plus heeft, maar dan zou ik idd diep in de source van TinyAjax moeten gaan spitten, dat hij problemen heeft met een & teken lijkt mij vrij logisch gezien hij dan een nieuwe parameter verwacht.

Maar het probleem is iig (via een 'ranzige workaround' ;)) opgelost! :)
Pagina: 1