Toon posts:

IE className wijziging verloopt traag

Pagina: 1
Acties:

Verwijderd

Topicstarter
Hallo,

Ik ben bezig met een RPG, net zoals Mobstar een misdaad RPG. Ik zit alleen
met één probleem. Zie allereerst: http://www.nextavenue.com/mobville/
Je ziet daar links in het midden de plattegrond van de wereld. Witte hokjes
kan je selecteren, de border wordt dan dotted. Zoals je kan zien gaat dat
erg traag.
Het enige wat de code doet is: onclick=> verander de stylesheet... en dat
moet maar liefst 2 seconde duren :s
De opbouw van de plattegrond is een tabel met heel veel cellen en rijen...
Zou het sneller gaan als ik DIV-jes zou gebruiken. Of gaat het sowiezo traag
omdat ik zoveel ID's gebruik?

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 08:20

crisp

Devver

Pixelated

Lookups kosten tijd; beter kan je referenties naar elementen bijhouden in een globale array oid. Daarnaast kost een class-swap ook meer tijd dan het direct wijzigen van style-properties.

Intentionally left blank


  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
woei het duurt op mijn ouwe barrel nog een stuk langer dan 2 secs. het ligt iig niet aan het setten van je className. Ik heb zo het idee dat je bij elke klik de "hele wereld" afgaat om te kijken of er op elk afzonderlijk elementje geklikt is. dat is niet bepaald efficient. In plaats van een gebeurtenis te defineren als "er is geklikt, laten we eens gaan kijken waar dan wel", kun je beter elk element geschikt maken voor het afhandelen van kliks, onafhankelijk van de andere elementen. Kijk bijvoorbeeld eens naar Element.attachEvent en Event.srcElement (IE).

Verwijderd

Topicstarter
De functie die de map maakt, maakt dus een tabel met cellen:
Elke cell krijgt een CSS attribuut:

onClick=\"selectItem(this, '" + c + "', '" + o["class"] + "');\"

als je op een TD klikt, dan wordt selectItem uitgevoerd. De code daarvan is:

code:
1
2
3
4
5
6
7
8
9
10
11
12
var oPrevItem = "";
var sPrevClass = "";
function selectItem(o, iType, sClass) {
  if (oPrevItem != "") {
    oPrevItem.runtimeStyle.cssText = "";
    oPrevItem.className = sPrevClass;
  }

  oPrevItem = o;
  sPrevClass = o.className;
  o.runtimeStyle.border = "2px dotted #000000";
}


Ik zie niet echt wat hier de vertragende factor is...
Crisp, jij als autoriteit op dit gebied kan me vast vertelen wat er aan
de hand is :D

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 08:20

crisp

Devver

Pixelated

Genoil schreef op 07 februari 2004 @ 18:30:
woei het duurt op mijn ouwe barrel nog een stuk langer dan 2 secs. het ligt iig niet aan het setten van je className. Ik heb zo het idee dat je bij elke klik de "hele wereld" afgaat om te kijken of er op elk afzonderlijk elementje geklikt is. dat is niet bepaald efficient. In plaats van een gebeurtenis te defineren als "er is geklikt, laten we eens gaan kijken waar dan wel", kun je beter elk element geschikt maken voor het afhandelen van kliks, onafhankelijk van de andere elementen. Kijk bijvoorbeeld eens naar Element.attachEvent en Event.srcElement (IE).
Ik raad iedereen met klem af om het IE-event model te gebruiken; die is zo brak als maar kan, en door de event-bubbling is het ook erg lastig om te achterhalen welk element er nou initieel verantwoordelijk is voor de trigger.
Ik gebruik zelf nog altijd element.onclick= (DOM1) voor eventhandling...

Intentionally left blank


Verwijderd

Topicstarter
jij zou mij dus aanraden, om niet HTML te genereren en die
neer te pleuren. Maar nieuwe elementen creëren en daar de
eigenschappen van aanpassen?

  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
crisp schreef op 07 februari 2004 @ 18:33:
[...]

Ik raad iedereen met klem af om het IE-event model te gebruiken; die is zo brak als maar kan, en door de event-bubbling is het ook erg lastig om te achterhalen welk element er nou initieel verantwoordelijk is voor de trigger.
Ik gebruik zelf nog altijd element.onclick= (DOM1) voor eventhandling...
ssssh ik ook :P , maar attachEvent dekt eventsgewijs beter de lading dan "on<event>"

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 08:20

crisp

Devver

Pixelated

Verwijderd schreef op 07 februari 2004 @ 18:33:
De functie die de map maakt, maakt dus een tabel met cellen:
Elke cell krijgt een CSS attribuut:

onClick=\"selectItem(this, '" + c + "', '" + o["class"] + "');\"

als je op een TD klikt, dan wordt selectItem uitgevoerd. De code daarvan is:

code:
1
2
3
4
5
6
7
8
9
10
11
12
var oPrevItem = "";
var sPrevClass = "";
function selectItem(o, iType, sClass) {
  if (oPrevItem != "") {
    oPrevItem.runtimeStyle.cssText = "";
    oPrevItem.className = sPrevClass;
  }

  oPrevItem = o;
  sPrevClass = o.className;
  o.runtimeStyle.border = "2px dotted #000000";
}


Ik zie niet echt wat hier de vertragende factor is...
Crisp, jij als autoriteit op dit gebied kan me vast vertelen wat er aan
de hand is :D
waarom kies je ueberhaupt voor IE-only properties als runtimeSyle? is het swappen van de class niet genoeg? Of direct de border-style aan te passen?

Intentionally left blank


Verwijderd

Topicstarter
Om concreet te zijn: Hoe kan ik zo'n map creëeren met CSS
die snel aan te passen is. Wat moet ik wel doen en wat niet?

Verwijderd

Topicstarter
Naja, ietwat lastig uit te leggen. Maar het komt erop neer dat je
ook de gebouwen die al van jou zijn kan highliten, die krijgen dan
een andere kleur. Toen ik gewoon met .style.border... ging werken
ging de boel fout...

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 08:20

crisp

Devver

Pixelated

Genoil schreef op 07 februari 2004 @ 18:35:
[...]


ssssh ik ook :P , maar attachEvent dekt eventsgewijs beter de lading dan "on"
attachEvent is bagger, en als je liever volgens DOM2 werkt dan zou je addEventListener moeten gebruiken en IE-support moeten droppen :P

Intentionally left blank


Verwijderd

Topicstarter
Als ik het nou eens met gepositioneerde DIV-jes probeer en die
met de functies: createElement en appendChild invoeg, zou het dan
wat sneller gaan?

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 08:20

crisp

Devver

Pixelated

Verwijderd schreef op 07 februari 2004 @ 18:38:
Naja, ietwat lastig uit te leggen. Maar het komt erop neer dat je
ook de gebouwen die al van jou zijn kan highliten, die krijgen dan
een andere kleur. Toen ik gewoon met .style.border... ging werken
ging de boel fout...
waarom kan je niet alleen met de class-swap weg dan? Verder zou ik het zo doen:
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
var oPrevItem = null;
var sPrevClass = '';
function selectItem(o, iType, sClass) {
  if (oPrevItem != null) {
    oPrevItem.className = sPrevClass;
  }

  oPrevItem = o;
  sPrevClass = o.className;
  o.className = sClass;
}

De classname moet dan natuurlijk al de border bevatten.

alleen doe je niets met iType :?
Verwijderd schreef op 07 februari 2004 @ 18:39:
Als ik het nou eens met gepositioneerde DIV-jes probeer en die
met de functies: createElement en appendChild invoeg, zou het dan
wat sneller gaan?
Ik denk dat dat weinig uitmaakt...

[ Voor 17% gewijzigd door crisp op 07-02-2004 18:45 ]

Intentionally left blank


Verwijderd

Topicstarter
idd, iType beetje overbodig... :D

Ik rommel nog wel wat aan...

  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
aangezien ik me te pletter verveel(de) heb ik maar heel ff een testje gemaakt:
HTML:
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
<html>
    <head>
        <style>
            table {
                width:500px;
                height:500px;
            }
            
            td {
                width: 50px;
                height: 50px;
                border: 1px solid #000;
                cursor:pointer;
            }
            
            .d {
                background-color:#FFF;
            }
            
            .h {
                background-color:#F00;
            }
        </style>
        <script type="text/javascript">
            
            var oo = null;
            var oc = null;
            
            function init() {
                aCells = document.getElementsByTagName("td");
                for(i = 0; i < aCells.length; i++) {
                    aCells[i].onclick = highlight;
                    aCells[i].className = "d";
                }
            }
            
            function highlight(e) {
                if(!e) e = window.event;
                if(e.srcElement) o = e.srcElement;
                else o = e.target;
                
                if(oo && oc) oo.className = oc; 
                
                oo = o;
                oc = o.className;               
                o.className = "h";
            }
        </script>
    </head>
    <body onload="init()">
        <table>
            <tr>
                <td>&nbsp;</td>
                <td>&nbsp;</td>
                <td>&nbsp;</td>
                <td>&nbsp;</td>
                <td>&nbsp;</td>
                <td>&nbsp;</td>
                <td>&nbsp;</td>
                <td>&nbsp;</td>
                <td>&nbsp;</td>
                <td>&nbsp;</td>
            </tr>
<!-- insert nog 9 rijen hier -->
        </table>
    </body>
</html>


loopt gewoon vlotjes hier

[ Voor 34% gewijzigd door Genoil op 07-02-2004 19:10 ]


Verwijderd

Topicstarter
Dank u heel erug

  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
in de edit ff wat typefoutjes gecorrigeerd. maar wat ik dus niet snap is dat dit ongeveer hetzelfde is als je eigen methode. lijkt eropt dat iets anders gewoon heel veel tijd kost.

Verwijderd

Ik had hier begin 2002 al melding over gemaakt met wat voorbeeldcode :)
[rml][ css] class zorgt voor gigantische hoge overhead[/rml]

  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
Gordijnstok heeft idd gelijk, mijn voorbeeldcode schaalt idd niet zo lekker :P. Met een tabel van 100 * 100 cellen is de vertraging enorm. Hiermee echter niet:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<script type="text/javascript">
            
            var oo = null;
            
            function init() {
                aCells = document.getElementsByTagName("td");

                for(i = 0; i < aCells.length; i++) {
                    aCells[i].onclick = highlight;
                }
            }
            
            function highlight(e) {
                if(!e) e = window.event;
                if(e.srcElement) o = e.srcElement;
                else o = e.target;
                
                if(oo) oo.style.backgroundColor = "#FFF"; 
                
                oo = o;                                     
                o.style.backgroundColor = "#F00";   
            }
        </script>

Verwijderd

Topicstarter
Allemaal bedankt voor jullie reacties!
Het is me eindelijk gelukt. Idd had Gordijnstok gelijk. className wijzigingen
kosten veel tijd.

Ik dacht, laat ik jullie het resultaat eens zien:
http://www.nextavenue.com/mobville/

Herkennen jullie er de plattegrond van een stad in? :)

Dank nog...

  • SchizoDuckie
  • Registratie: April 2001
  • Laatst online: 18-02-2025

SchizoDuckie

Kwaak

Verwijderd schreef op 08 februari 2004 @ 18:59:
Herkennen jullie er de plattegrond van een stad in? :)
Is het een DigDug Level? :P

Stop uploading passwords to Github!


Verwijderd

Topicstarter
Wha nee,

Het wordt een Misdaad RPG. Ik ben lid van www.mobstar.cc, maar ik vind het
niet echt mooi. Die "dig-dug"-level moet een plattegrond van een stad
voorstellen.
Het hele spel zal zich afspelen in één stad. De stad is opgedeeld in wijken, en
die plattegrond is een wijk. Je moet drugs handelen en mensen beroven en
uitgroeien tot leider van de stad. Je moet dus veel huizen bezitten, veel agenten omkopen, winkels bezitten, casino's enz...

Naja, teveel om op te noemen. Ben ik nog wel een tijdje zoet mee :D

Verwijderd

prachtig, checking browser support, IE only.. so 90's

Verwijderd

Topicstarter
Wil je het graag Mozilla compatibel?
Komt voor mekaar :D

Verwijderd

niet perse mozilla compatible als wel DOM 1 browser compatible ;)

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 08:20

crisp

Devver

Pixelated

Ik heb hier eerder iets geroepen over dat het IE5+ event model zuigt, laat ik dat eens onderbouwen aan de hand van een voorbeeld :)

In feite zijn er 2 problemen met het IE5 event model

1) IE ondersteund alleen event-bubbling, geen capturing
2) Het is onmogelijk om tijdens de bubbling-fase het element te achterhalen wat het event op dat moment verwerkt

Een voorbeeld (te testen in IE en in bijvoorbeeld Mozilla/Firebird):

HTML:
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
<html>
<head>
<title>bla2</title>
<script type="text/javascript">

function init() {

  if (typeof document.attachEvent != 'undefined') {

    document.getElementById('box1').attachEvent('onclick', bla_ie);
    document.getElementById('box2').attachEvent('onclick', bla_ie);

  } else {

    // note: changing false to true will use event capturing iso bubbling
    document.getElementById('box1').addEventListener('click', bla_dom, false);
    document.getElementById('box2').addEventListener('click', bla_dom, false);

  }

}

function bla_ie() {

  // always undefined because the function is referenced instead of copied
  alert(this.id);

  // will always reference the element which caused the event to trigger
  alert(event.srcElement.id);

}

function bla_dom(e) {

  // both give the current element that is handling the event
  // either in capturing of bubbling fase
  alert(this.id);
  alert(e.currentTarget.id);

  // simular to srcElement gives the element that originally
  // triggered the event
  alert(e.target.id);

}

</script>
<style type="text/css">

body {
  min-height: 100%;
}

#box1 {
  position: absolute;
  top: 10px;
  left: 10px;
  width: 300px;
  height: 300px;
  background-color: red;
}

#box2 {
  position: absolute;
  top: 100px;
  left: 100px;
  width: 100px;
  height: 100px;
  background-color: blue;
}

</style>
</head>
<body onload="init()">
<div id="box1">
  <div id="box2"> </div>
</div>
</body>
</html>


Je ziet hier een box in een box, beiden krijgen een onclick event toegewezen. Kijk wat er gebeurd als je op het blauwe vierkant klikt:

IE: geeft voor de eerste alert 'undefined' omdat IE enkel een referentie naar de toegewezen functie maakt in plaats van een kopie. Het this keyword verwijst dus naar het window object in plaats van het element dat op dat moment het event afhandeld (omdat IE event-bubbling gebruikt is dat op dit moment box2).
De 2e alert geeft netjes box2 als srcElement.
Vervolgens bubbled het event dus door naar onderen en triggered de onclick op box1. Hier komt het grote manko van IE dus aan het licht: er is geen enkele manier om te achterhalen dat box1 op dit moment het event afhandelt; de 1e alert geeft nog steeds undefined, en de 2e alert nog steeds box2 omdat dat het element was wat als eerste de reeks events triggerde.

Mozilla: maakt itt IE wel een kopie van de toegewezen functie waardoor het this keyword verwijst naar het element wat op dat moment het event afhandeld. Als alternatief kan ook verwezen worden naar de currentTarget property van het event-object (wat dus als een parameter wordt doorgegeven in plaats van dat het een global property van het window object is).
Het 3e argument in addEventListener geeft aan of eventbubbling of eventcapturing gebruikt moet worden; false = bubbling, true = capturing.
We gebruiken eventbubbling in dit voorbeeld, dus het eerste element waarvan het event getriggered wordt is box2; de 1e keer dat functie bla_dom wordt uitgevoerd krijgen we dus 3x 'box2' als alert. Vervolgens bubbled het event naar box1 en verwijzen zowel this als currentTarget naar box1, en blijft target naar box2 verwijzen gelijk srcElement in het IE model.
Als je nu het 3e argument voor addEventListener wijzigt naar true zal je zien dat de event-volgorde omdraait (van onder naar boven) :)

Hoe krijg je het in IE dan toch voor elkaar om te achterhalen welk element het event afhandelt op een bepaald moment in de bubbling fase? Simpel, het DOM level 1 event model gebruiken:

element.onclick = handler;

binnen de handler kan je dan toch gebruik maken van het this keyword. Het grootste nadeel van dit model is dat je niet meerdere handlers aan 1 event kan toekennen (en dus ook niet eenvoudig weer kan verwijderen), en dat je alleen gebruik kan maken van event-bubbling.

Intentionally left blank


Verwijderd

Topicstarter
Crisp,

Je hebt volledig gelijk, maar zolang Microsoft een marktaandeel heeft
van 97%, moet je er wel voor zorgen dat je scripts ook in IE werken...

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 08:20

crisp

Devver

Pixelated

Verwijderd schreef op 09 februari 2004 @ 11:24:
Crisp,

Je hebt volledig gelijk, maar zolang Microsoft een marktaandeel heeft
van 97%, moet je er wel voor zorgen dat je scripts ook in IE werken...
Ja, maar dat is niet het punt :)
Ik wou hiermee alleen aangeven dat voor DHTML het IE5 event model compleet useless is, en je dus beter gewoon het oude model kan blijven gebruiken wat als bijkomend voordeel heeft dat het ook in andere browsers werkt, maar alleen als grootste nadeel dat je niet meerdere handlers aan 1 event kan koppelen...

Intentionally left blank


Verwijderd

Topicstarter
Jawel het is me dan gelukt, de JS werkt nu ook in Mozilla... :D

edit:

schijnt handig te zijn om de URL erbij te geven :D


http://www.nextavenue.com/mobville/

Crisp, zou je even snel naar de code willen kijken (er staat voldoende
commentaar om alles snel te snappen) en zeggen of dit goed is of
slecht?

Vraag 2: hoe kijk jij aan tegen prototypes die de functies van IE
immiteren? Slecht of goed?

[ Voor 16% gewijzigd door Verwijderd op 09-02-2004 11:52 ]


  • André
  • Registratie: Maart 2002
  • Laatst online: 26-05 00:33

André

Analytics dude

Verwijderd schreef op 09 februari 2004 @ 11:51:

Vraag 2: hoe kijk jij aan tegen prototypes die de functies van IE
immiteren? Slecht of goed?
Hoe bedoel je dat? Welke functies wil jij imiteren dan?
Als jij denkt dat je het beter dan IE kan is het altijd goed.

[ Voor 11% gewijzigd door André op 09-02-2004 11:53 ]


Verwijderd

Topicstarter
Om outerHTML in Mozilla toch te kunnen gebruiken, bijvoobeeld:

code:
1
2
3
4
5
HTMLElement.prototype.__defineGetter__("outerHTML", function () {
  var tempElem = document.createElememt("DIV");
  tempElem.appendChild(this);
  return (tempElem.innerHTML);
});

[ Voor 16% gewijzigd door Verwijderd op 09-02-2004 11:57 ]


  • André
  • Registratie: Maart 2002
  • Laatst online: 26-05 00:33

André

Analytics dude

Maak je outerHTML zo niet gewoon gelijk met innerHTML? Dat heeft niet veel nut.

Verwijderd

Topicstarter
Hoe wil jij in Mozilla outerHTML aanroepen? Bestaat niet...
Stel dat je wel alle HTML wil, ook van het Element zelf...
Even goed naar de code kijken...

  • André
  • Registratie: Maart 2002
  • Laatst online: 26-05 00:33

André

Analytics dude

Verwijderd schreef op 09 februari 2004 @ 11:59:
Hoe wil jij in Mozilla outerHTML aanroepen? Bestaat niet...
Stel dat je wel alle HTML wil, ook van het Element zelf...
Even goed naar de code kijken...
Oke ik zie het nu.
Vind het wel ranzig omdat je daar een element voor aan moet maken.

Verwijderd

Topicstarter
Verwijderd schreef op 09 februari 2004 @ 10:20:
prachtig, checking browser support, IE only.. so 90's
http://www.nextavenue.com/mobville/

Tadaaaaaa

Nu werkt hij in Mozilla, Netscape en IE... happy?
Heb die hele menu class geherprogrammeerd, daarmee kan je
super eenvoudig Windows menus genereren.

  • Clay
  • Registratie: Oktober 1999
  • Laatst online: 25-02 11:17

Clay

cookie erbij?

er is geen enkele manier om te achterhalen dat box1 op dit moment het event afhandelt
er is nooit geen enkele manier :)

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function init() {
   addEvent(document.getElementById('box1'), bla_ie);
   addEvent(document.getElementById('box2'), bla_ie);  
}

function addEvent(element, reference) {
   element.reference = reference;
   element.attachEvent('onclick', function() {
      // scope tluuk      
      element.reference();
   });
}

function bla_ie() {
   alert(this.id)
}

Instagram | Flickr | "Let my music become battle cries" - Frédéric Chopin


  • crisp
  • Registratie: Februari 2000
  • Laatst online: 08:20

crisp

Devver

Pixelated

:D slim :)

Intentionally left blank

Pagina: 1