[JS/DOM] Opera te traag met opbouwen select?

Pagina: 1
Acties:

  • .Johnny
  • Registratie: September 2002
  • Laatst online: 19-03 12:22
Met opera (MSIE en FF werken prima) loop ik tegen een probleempje aan; wanneer ik een select met options aanmaak via de DOM en daarna de value van de select zet, werkt dit niet. Het lijkt alsof hij ondertussen nog bezig is de DOM tree te parsen, want als ik alert of een sleep doe, werkt het wel. zie dit voorbeeld (regel 18 zet de value van de select):
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>DOM TEST</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<script>
function test() {
    select=document.createElement('select');
    document.getElementById('start').appendChild(select);
    select.appendChild(createOption('test1','test1'));
    select.appendChild(createOption('test2','test2'));
    select.appendChild(createOption('test3','test3'));
    select.appendChild(createOption('test4','test4'));
    select.appendChild(createOption('test5','test5'));
    select.appendChild(createOption('test6','test6'));
    select.appendChild(createOption('test7','test7'));
    sleep(500);
    select.value='test7';
}
function createOption(value,name) {
    op=document.createElement('option');
    op.setAttribute('value',value);
    op.appendChild(document.createTextNode(name));
    return op;
}
function sleep(msec) {
    var d = new Date();
    var starttime = (d.getMilliseconds()+(d.getSeconds()*1000));
    while (true) {
        var dd = new Date();
        if ((dd.getMilliseconds()+(dd.getSeconds()*1000))>(starttime+msec))
            break;
    }
    return;
        
}
</script>
</head>

<body onload="test()">
<div id="start">
</div>
</body>
</html>

Wanneer je van dit voorbeeld de regel 17: sleep(500) uitcommentarieerd, werkt de value setting niet in opera. Iemand een idee waarom? deze sleep functie werkt nu wel, maar is niet helemaal foolproof. bovendien zou het op een trager systeem langer kunnen duren. Het is me ook niet gelukt om de status van de select uit te lezen om zo wachten tot het maken klaar is.

  • .Johnny
  • Registratie: September 2002
  • Laatst online: 19-03 12:22
for the record, deze sleep functie is wat netter. maar daar gaat t natuurlijk niet om.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function sleep(msec) {
    var d = new Date();
    if (msec>1000) {
        var cycles = Math.floor(msec/1000);
        for (var a=0;a<cycles;a++) {
            sleep(1000)
        }
        msec = msec-(1000*Math.floor(msec/1000));
    }
    var starttime = d.getMilliseconds();
    if (starttime+msec > 999)
        starttime = (starttime - 1000)
    while (true) {
        /* wait for it... */
        var dd = new Date();
        if (dd.getMilliseconds()>(starttime+msec))
            break;
    }
    return;
}

[ Voor 11% gewijzigd door .Johnny op 04-03-2005 20:25 ]


  • André
  • Registratie: Maart 2002
  • Laatst online: 06-05 11:13

André

Analytics dude

Die sleep functie is natuurlijk 100% ruk, je trekt er 100% CPU mee terwijl het helemaal niet nodig is. Voor dit soort dingen bestaat er een timeout functie is JS:

Verander:
code:
1
2
sleep(500);
select.value='test7';

In:
code:
1
setTimeout("select.value='test7'", 500);

En waarschijnlijk kun je 500 ook wel in 20 veranderen.

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 14:19

crisp

Devver

Pixelated

heeft het value attribuut van een select wel een setter officieel? Zou je niet beter de selectedIndex een waarde kunnen geven?

André: je vergeet even de scope met je timeout functie ;)

Als alternatief zou je eventueel nog gewoon met new Option() kunnen werken:

JavaScript:
1
2
3
select.options[select.options.length] = new Option(text, value);
//-- ...
select.selectedIndex = 6;


edit: tested, en de selectedIndex zetten ipv een value toekennen lost in ieder geval je probleem op ;)

[ Voor 70% gewijzigd door crisp op 04-03-2005 23:58 ]

Intentionally left blank


  • .Johnny
  • Registratie: September 2002
  • Laatst online: 19-03 12:22
ok, met selectedIndex werkt het inderdaad ook met Opera. Het is wel wat meer code, omdat ik eerst door de options moet loopen om te kijken welke index bij welke value hoort(itt tot dit simpele voorbeeldje weet ik in de ingewikkeldere applicatie niet welke options waar staan, vandaar)

Die sleep kon trouwens niet op 20, wellicht op 300 ofzo, maar bij mij had ik echt meer dan 200 nodig. absurd? inderdaad. troep? dat ook, maar ik was vooral het concept aan het aantonen. settimeout() heeft voor mij niet de gewenste functionaliteit. Naast het probleem van context krijg je natuurlijk lelijke dingen in bijvoorbeeld een methode voor een object die ik maak die select elementen opnieuw opbouwt en zo mogelijk op de oude waarde terug zet; die moet je dan in tweeen gaan hakken: het deel voor de setvalue en het gedeelte na de setvalue.

sowieso vroeg ik me vooral af: waarom? en dan pas na die tijd?


iedereen schijnt weg te lopen met de DOM ondersteuning van Opera, maar ik heb al wel meer ellende voorbij zien komen. neem bijvoorbeeld de methode Node.replaceChild(ch1,ch2). Wanneer ch1 en ch2 hetzelfde zijn, werkt dit maar buggy in Opera(plaatjes verdwijnen bijvoorbeeld). Dat lijkt me niet by design.

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 14:19

crisp

Devver

Pixelated

niemand loopt hier weg met de DOM ondersteuning van Opera, en zeker ik niet. Ik weet dat Opera op dat punt nogal buggy en slow is, maar gelukkig wordt het wel met elke release beter ;)

Intentionally left blank


  • .Johnny
  • Registratie: September 2002
  • Laatst online: 19-03 12:22
hmm, dan zal ik dat wel verkeerd onthouden hebben van een uitspraak van iemand. Of 't was iemand die er gewoon niet echt kaas van gegeten had. of ging die uitspraak nou over CSS? ik ben dat ff kwijt, maargoed, weer iets om te onthouden als je aan de DOM sleutelt.
voor de liefhebbers:
kwam er nog 1 tegen voor MSIE vanmiddag, met tables via createElement toevoegen; tot nu toe zag ik ze dan steeds niet, maar een insertRow methode:
code:
1
2
tbl = document.createElement('table');
var tr = tbl.insertRow(0);

zorgt ervoor dat de table met IE wel op je scherm floept. leuke hersenkraker als zelfs de innerHTML property alert-en gewoon de hele tabel-html toont, maar je op je scherm niks terug ziet.
Resizen van een MSIE window met allerlei via DOM toegevoegde elementen geeft ook leuke effecten trouwens. verdwijnen ze van je scherm. gewoon even childje appenden en weer weghalen onresize voorkomt je die ellende.
zo.

[ Voor 3% gewijzigd door .Johnny op 05-03-2005 02:52 ]


  • crisp
  • Registratie: Februari 2000
  • Laatst online: 14:19

crisp

Devver

Pixelated

Je kan prima via DOM tables bakken, als je maar wel rekening houdt met het tbody element ;)

insertRow e.d. zijn trouwens gewoon DOM level 1 methods, dus daar is ook niets mis mee.

[ Voor 34% gewijzigd door crisp op 05-03-2005 12:52 ]

Intentionally left blank


  • .Johnny
  • Registratie: September 2002
  • Laatst online: 19-03 12:22
ja, dat is wel zo, maar de specifieke functies zijn in terminis niet zo generiek. dus hoe dynamischer je code, hoe minder je zit te wachten op specifieke element generators.
Pagina: 1