[JS] Toevoegen van elementen zijn niet meer benaderbaar*

Pagina: 1
Acties:

  • Uhmmie
  • Registratie: Januari 2000
  • Laatst online: 27-10 08:20
Ok ik ben momenteel bezig met een charbuilder voor een game die ik speel. Echter loop ik tegen een probleem aan met de clientside javascript.. (Het onderstaande versie is een ingekorte versie waarin exact hetzelfde probleem naar voren komt). De functionaliteit hiervan slaat nergens op :P.
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
    <HEAD>
        <TITLE>DDO Enchantments</TITLE>
        <SCRIPT type="text/javascript">

        var handles = new Object();
        var box = new Object();

        function updatePts(e) {
            for (var i in handles) {
                if (e.id != handles[i].id) {
                    handles[i]['htmlelem'].checked = !(handles[i]['htmlelem'].checked); 
                }
            }
        }
        
        function inputCreate(id, type, name, value, checked) {
            if (navigator.appName.indexOf("Microsoft") >= 0) {
                var htmlelem = document.createElement('<input id="'+id+'" type="'+type+'" name="'+name+'" value="'+value+'">');
            }else{
                var htmlelem = document.createElement('input');
                htmlelem.setAttribute('type',  type);
                htmlelem.setAttribute('id',    id);
                htmlelem.setAttribute('name',  name);
                htmlelem.setAttribute('value', value);
            }
            htmlelem.defaultChecked = checked;
            htmlelem.onclick = "updatePts(this);";  
            return htmlelem;
        }
        
        function Enchantment(id, level, shared, group_id, label, ench_id, prog, cost, rank, checked) {
            this['div']         = document.createElement('div');
            box.appendChild(this['div']);
            
            this['htmlelem']    = inputCreate(id, "checkbox", "enchantments["+level+"]["+ench_id+"]", 1, checked);
            this['div'].appendChild(this['htmlelem']);
            this['div'].innerHTML += label;
            
            this['id']          = id;
        }
        
        function init() {
            box        = document.getElementById('enchantmentbox');
            handles[0] = new Enchantment(0, 1, 0, 1, 'label A', 1, 0, 1, 1, false); 
            handles[1] = new Enchantment(1, 1, 1, 3, 'label B', 9, 0, 1, 1, true); 
            handles[2] = new Enchantment(2, 1, 6, 14, 'label C', 38, 0, 1, 1, false); 
        }       
        </SCRIPT>
    </HEAD>
    <BODY onload='init()'>
        <FORM ACTION='' METHOD='POST'>
        <TABLE width="80%" align="center">
            <TR>
                <TD class="headerright" colspan="3">
                    <div id="enchantmentbox"></div>
                </TD>
            </TR>       
        </FORM>
    </BODY>
</HTML>

[ Voor 11% gewijzigd door Uhmmie op 22-02-2007 20:42 ]

Currently playing: MTG Arena (PC)


  • Uhmmie
  • Registratie: Januari 2000
  • Laatst online: 27-10 08:20
Na data de init functie is uitgevoerd via de body onload="init()" ziet mijn body er als volgt uit:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<FORM action="" method=post>
<TABLE width="80%" align=center>
  <TBODY>
    <TR>
      <TD class=headerright colSpan=3>
        <DIV id=enchantmentbox>
          <DIV><INPUT id=0 onclick=updatePts(this); type=checkbox value=1 name=enchantments[1][1]>label A</DIV>
          <DIV><INPUT id=1 onclick=updatePts(this); type=checkbox CHECKED value=1 name=enchantments[1][9]>label B</DIV>
          <DIV><INPUT id=2 onclick=updatePts(this); type=checkbox value=1 name=enchantments[1][38]>label C</DIV>
        </DIV>
      </TD>
    </TR>
</TBODY>
</TABLE>
</FORM>

Het doel:Het voorbeeld hierboven zou alle andere checkboxen die geregistreerd staan in het object handels van waarde moeten veranderen zodra men op een checkbox klikt. (normaal gesproken zit hier een hele lijst met checks in die bepaald welke objecten wel en niet aangevinkt moeten worden aan de hand van alle waardes die ik in mijn handles array object).

Het probleem: Zodra ik via reference object binnen mijn object array een waarde aan wil passen veranderd er niks aan het daadwerkelijk gecreeerde html object. Kortom zodra ik dit object append aan een object binnen mijn HTML lijken ze beide een eigen leven te gaan leiden.

Nog meer info als ik elke keer de verwijzing naar het element object opniew aanmaak gaat het wel goed, dus:
code:
1
handles[i]['htmlelem'].checked = !(handles[i]['htmlelem'].checked);

vervang door:
code:
1
document.getElementById(handles[i].id).checked = !(document.getElementById(handles[i].id).checked);

Dit is echter geen doen, want in mijn complete functionaliteit moet ik langs honderden objecten bij elke checkbox die men veranderd.. Als ik dan steeds opnieuw alle objecten op moet zoeken binnen mijn html dan betekend dat dus dat het allemaal zeer traag wordt (en wordt mijn script waarschijnlijk ook gekilled door de browser)..

Nog meer informatie.. Als ik op een checkbox in mijn form klik veranderd de waarde binnen het bij behorende object ook niet (deze blijft gewoon op de default waarde staan van toen ik het object aan maakte).. Ik weet nu dus met 99% zekerheid dat er dus een kopie wordt gemaakt..

Ok ik heb mijn updatePts functie even aangepast naar:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function updatePts(e) {
    for (var i in handles) {
        if (e.id != handles[i].id) {
            alert("init");
            alert(handles[i]['htmlelem'].value);
            alert(document.getElementById(handles[i].id).value);
            handles[i]['htmlelem'].value = 2;
            alert("obj");
            alert(handles[i]['htmlelem'].value);
            alert(document.getElementById(handles[i].id).value);
            document.getElementById(handles[i].id).value = 3;
            alert("elem");
            alert(handles[i]['htmlelem'].value);
            alert(document.getElementById(handles[i].id).value); 
        }
    }
}

Output is iets als: Init 1 1, Obj 2 1, Obj 2 3 Kortom het htmlelem object is totaal niet meer gekoppeld aan het object dat daadwerkelijk in je browser getoont wordt.. Ik weet niet of dit een dikke bug in een browser is? of ik iets fout doe? En al helemaal niet of ik om dit probleem heen kan komen zonder dat ik keer op keer het html object opmoet zoeken in mijn code?

[ Voor 98% gewijzigd door Uhmmie op 22-02-2007 20:09 ]

Currently playing: MTG Arena (PC)


  • Blacksnak
  • Registratie: Oktober 2001
  • Laatst online: 07-07-2024
En wat is het probleem juist?

  • Uhmmie
  • Registratie: Januari 2000
  • Laatst online: 27-10 08:20
Het probleem staat er nu ook bij ;) Het was teveel code om in alleen mijn OP te plaatsen ;)

Update: Even al mijn tests aan mijn bovenstaande post toegevoegd.

[ Voor 255% gewijzigd door Uhmmie op 22-02-2007 19:58 ]

Currently playing: MTG Arena (PC)


  • crisp
  • Registratie: Februari 2000
  • Nu online

crisp

Devver

Pixelated

1) De generated source hoeft inderdaad niet altijd de status van de DOM te representeren
2) ID-attributen mogen niet met een cijfer beginnen
3) waarom instantieer je 'handles' als een object terwijl je daar duidelijk beter een array van kan maken?
4) Een eventhandler-toewijzing in javascript moet een functie-reference zijn, geen string
5) UA-sniffing is onbetrouwbaar
6) waarom gebruik je niet gewoon dot-notatie binnen Enchantment voor je instance-properties?
7) waarom voeg je het label toe mbv innerHTML ipv netjes een textNode aan te maken (hierdoor help je je event-handlers ook om zeep)?

Intentionally left blank


  • Uhmmie
  • Registratie: Januari 2000
  • Laatst online: 27-10 08:20
crisp schreef op donderdag 22 februari 2007 @ 23:32:
1) De generated source hoeft inderdaad niet altijd de status van de DOM te representeren
2) ID-attributen mogen niet met een cijfer beginnen
3) waarom instantieer je 'handles' als een object terwijl je daar duidelijk beter een array van kan maken?
4) Een eventhandler-toewijzing in javascript moet een functie-reference zijn, geen string
5) UA-sniffing is onbetrouwbaar
6) waarom gebruik je niet gewoon dot-notatie binnen Enchantment voor je instance-properties?
7) waarom voeg je het label toe mbv innerHTML ipv netjes een textNode aan te maken (hierdoor help je je event-handlers ook om zeep)?
1) Volg niet precies wat je hier bedoeld..Als je mijn stukje html bedoeld uit mijn 2 post van de body.. Dit is een dump van de innerHTML van de body nadat alle elementen zijn aangemaakt. Dit toont dus de default van alle gegenereerde elementen.
2) Ik had het bovenstaande snel in elkaar gezet normaal zit er ook nog een text label voor het id nummer, maar als ik mijn complete script had gepost dan weet ik zeker dat het niet duidelijker was. Terwijl deze geminimalizeerde code exact hetzelfde probleem genereerd.
3) Omdat mijn handles object normaal ook een aantal functies voor zichzelf heeft. Zie punt 2.
4) ik had ook = function() { updatePts(this.id); } geprobeerd en mijn onclick wordt gewoon uitgevoerd.. Hier zit het probleem niet.
5) UA?
6) Ik heb het op tich manieren geprobeerd ondertussen, vandaar dat ik nu hier om hulp vraag.
7) ik voeg dit ondertussen al toe door de een label element aan te maken die ik vervolgens aan mijn checkbox koppel. Ook dit maakt niks uit..

Ik zit nog steeds met het probleem dat nadat ik:

elem = createElement(....);
.............
anderelem.appendChild(elem);
Uitvoer ik in eens geen een attribute meer in kan stellen met elem.setAttribute(xxx, xxx); Op een of andere manier is mijn elem object niet meer hetzelfde object als het element dat op het scherm getoont wordt.

Currently playing: MTG Arena (PC)


  • crisp
  • Registratie: Februari 2000
  • Nu online

crisp

Devver

Pixelated

Uhmmie schreef op donderdag 22 februari 2007 @ 23:57:
[...]

1) Volg niet precies wat je hier bedoeld..Als je mijn stukje html bedoeld uit mijn 2 post van de body.. Dit is een dump van de innerHTML van de body nadat alle elementen zijn aangemaakt. Dit toont dus de default van alle gegenereerde elementen.
correct, de default. Als ik echter bijvoorbeeld de checked property aanpas in de DOM dan hoeft dat niet in de innerHTML zichtbaar te zijn.
2) Ik had het bovenstaande snel in elkaar gezet normaal zit er ook nog een text label voor het id nummer, maar als ik mijn complete script had gepost dan weet ik zeker dat het niet duidelijker was. Terwijl deze geminimalizeerde code exact hetzelfde probleem genereerd.
Als het gaat om het uitsluiten van fouten moet je natuurlijk niet nieuwe mogelijke fouten gaan introduceren ;)
3) Omdat mijn handles object normaal ook een aantal functies voor zichzelf heeft. Zie punt 2.
Je prototyped Object? Pas dan helemaal op met je for-in construct...
4) ik had ook = function() { updatePts(this.id); } geprobeerd en mijn onclick wordt gewoon uitgevoerd.. Hier zit het probleem niet.
Na puntje 7 deed je onclick handler nogthans helemaal niets meer...
Overigens zou ik gewoon htmlelem.onclick = updatePts; doen en in updatePts zelf met het 'this' keyword werken.
5) UA?
UserAgent (browser in dit geval). Er zijn zat browsers die zich (kunnen) identificeren als IE - dat zegt niets over de mogelijkheden en onmogelijkheden van die browser. In dit geval kan je beter met een try-catch werken of met conditional compilation.
6) Ik heb het op tich manieren geprobeerd ondertussen, vandaar dat ik nu hier om hulp vraag.
Niets mis mee hoor :) Ik probeer echter eerst te doorgronden wat je kennis-niveau precies is en ben je een beetje aan het kietelen om te kijken of je er dan zelf uitkomt. Ik had je testcase in 1 minuut werkend met wat kleine aanpassingen, maar om dat meteen hier te posten is ook zo'n dooddoender ;)
7) ik voeg dit ondertussen al toe door de een label element aan te maken die ik vervolgens aan mijn checkbox koppel. Ook dit maakt niks uit..
Vervang het toch maar gauw door een this.div.appendChild(document.createTextNode(label));

Intentionally left blank


  • BtM909
  • Registratie: Juni 2000
  • Niet online

BtM909

Watch out Guys...

Problemen met Javascript hebben wel meer mensen. ;) Ik heb je topictitel dus even aangepast. Weet je een betere, geef dan even een suggestie middels de Afbeeldingslocatie: http://gathering.tweakers.net/global/templates/tweakers/images/icons/icon_hand.gif knop :)

Ace of Base vs Charli XCX - All That She Boom Claps (RMT) | Clean Bandit vs Galantis - I'd Rather Be You (RMT)
You've moved up on my notch-list. You have 1 notch
I have a black belt in Kung Flu.

Pagina: 1