[JS] getElementsByName werkt niet op alle elementen

Pagina: 1
Acties:

  • jsiegmund
  • Registratie: Januari 2002
  • Laatst online: 10:13
Even een kort testscript gemaakt. Het volgende werkt wel in FF, niet in IE... rara waarom. Zal wel weer een of ander stom syntax dingetje zijn maar ik krijg het er niet uit :(

HTML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<html>
    <head> 
        <script type="text/javascript">
            function highlight() {
                var elements = document.getElementsByName("test");
                for (i=0; i<elements.length; i++) 
                    elements[i].style.color = "red";
            }
        </script>
    </head>
    <body>
        <a href="#" onmouseover="javascript:highlight();">testing!</a>
        <div name="test">test1</div>
        <div name="test">test2</div>
    </body>
</html>


Extra info:
code:
1
2
var elements = document.getElementsByName("test");
document.write(elements.length);


geeft 0 in IE, 2 in FF.... ?

En dit:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<html>
    <head> 
        <script type="text/javascript">
            function highlight() {
                var elements = document.getElementsByName("test");
                for (i=0; i<elements.length; i++) {
                    elements[i].style.backgroundColor = "red";
                }
                document.getElementById("test").style.backgroundColor="red";
            }
        </script>
    </head>
    <body>
        <a href="#" onmouseover="javascript:highlight();">testing!</a>
        <div name="test" id="test">test1</div>
        <div name="test">test2</div>
    </body>
</html>


highlight dan weer wel een enkele rij in IE... raar maar waar, ik snap 't even niet meer 8)7

[ Voor 121% gewijzigd door jsiegmund op 24-01-2006 16:35 ]


  • MisterData
  • Registratie: September 2001
  • Laatst online: 09-04 12:07
Name wordt niet meer gebruikt, als je id="test" gebruikt en dan getElementById dan ben je er... een id is uniek, er mag maar 1 tag zijn met een bepaald id (dat is met naam ook). Wil je alle tags van een bepaalde soort hebben, doe dan iets in de trant van document.getElementsByTagName ofzo :)

Overigens is een 'tag name' dus gewoon DIV. Wat ook kan is een parent div maken en daarvan door de children loopen:

HTML:
1
2
3
4
<div id="parent">
<div></div>
<div></div>
</div>


en dan

JavaScript:
1
2
3
4
5
6
7
var parent = document.getElementById('parent');
for(var a=0;a<parent.childNodes.length;a++) {
   var node = parent.childNodes[a];
  if(node.tagName=="DIV" en eventueel wat meer checks) {
      ...
   }
}

[ Voor 44% gewijzigd door MisterData op 24-01-2006 16:38 ]


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 18:44

Creepy

Tactical Espionage Splatterer

JS? Voor javascript zul je in Webdesign & Graphics moeten zijn. Move -> Webdesign & Graphics

[ Voor 6% gewijzigd door Creepy op 24-01-2006 16:37 ]

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • jsiegmund
  • Registratie: Januari 2002
  • Laatst online: 10:13
MisterData schreef op dinsdag 24 januari 2006 @ 16:36:
Name wordt niet meer gebruikt, als je id="test" gebruikt en dan getElementById dan ben je er... een id is uniek, er mag maar 1 tag zijn met een bepaald id (dat is met naam ook). Wil je alle tags van een bepaalde soort hebben, doe dan iets in de trant van document.getElementsByTagName ofzo :)

Overigens is een 'tag name' dus gewoon DIV. Wat ook kan is een parent div maken en daarvan door de children loopen:

HTML:
1
2
3
4
<div id="parent">
<div></div>
<div></div>
</div>


en dan

JavaScript:
1
2
3
4
5
6
7
var parent = document.getElementById('parent');
for(var a=0;a<parent.childNodes.length;a++) {
   var node = parent.childNodes[a];
  if(node.tagName=="DIV" en eventueel wat meer checks) {
      ...
   }
}
In zoverre dat dit:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<html>
    <head> 
        <script type="text/javascript">
            function highlight() {
                var elements = document.getElementsByName("test");
                for (var i=0; i<elements.length; i++) {
                    elements[i].style.backgroundColor = "red";
                }
                document.getElementById("test").style.backgroundColor="red";
            }
        </script>
    </head>
    <body>
        <a href="#" onmouseover="javascript:highlight();">testing!</a>
        <form>
        <input name="test" value="test"/>
        <input name="test" value="test2"/>
        </form>
    </body>
</html>


Wel gewoon werkt, dus het name attribuut van een div is blijkbaar niet netjes meer.

Dan heb ik een volgend probleem, want ik kan ze in de pagina waar het om gaat niet onderbrengen onder een parent (staan verspreid in een tabel) en met ID werken is ook geen optie aangezien het om meerdere div's gaat.

Zie ook (voorbeeld): http://www.aglasshalffull...thgetelementsbyname.html#

[ Voor 15% gewijzigd door jsiegmund op 24-01-2006 16:44 ]


  • Standeman
  • Registratie: November 2000
  • Laatst online: 18:45

Standeman

Prutser 1e klasse

hier staat het volgende:
Remarks

When you use the getElementsByName method, all elements in the document that have the specified NAME or ID attribute value are returned.

Elements that support both the NAME and the ID attribute are included in the collection returned by the getElementsByName method, but not elements with a NAME expando.
Misschien dat het iets met dat "expando" dinges te maken heeft?

Als je hier gaat kijken naar DIV object, zie je dat de "name attribute" niet gespecificeerd is. Dus dat zal er wel mee te maken hebben..

[ Voor 20% gewijzigd door Standeman op 24-01-2006 16:48 ]

The ships hung in the sky in much the same way that bricks don’t.


Verwijderd

Dat klopt. name is geen geldig attribuut voor een DIV dus het wordt niet herkend door de getElementsByName. Kijk hier voor meer info over de attibuten en hun geldige tags:
http://www.w3.org/TR/1998...424/index/attributes.html

  • BtM909
  • Registratie: Juni 2000
  • Niet online

BtM909

Watch out Guys...

Wil je volgende keer ook een omschrijvende titel verzinnen voor je probleem? ;)

Overigens zou je in dit geval getElementsByTagName kunnen gebruiken en dan het name attribuut controleren.

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.


  • jsiegmund
  • Registratie: Januari 2002
  • Laatst online: 10:13
Uhhh ja, zal de volgende keer proberen wat creatiever te zijn O-)

Ok, duidelijk dus dat het niet werkt omdat dat niet in de specificatie is opgenomen. Maar bestaat er dan wel een ander mechanisme om een groepje van die dingen terug te krijgen? Vond het nu juist voor dit geval zo handig dat je alles met een bepaalde naam kunt opvragen (niet dus)... alternatieven?

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 13-04 10:40
Ik gebruik vaak getelementsbyclassname van Crisp: [rml][ handig] getElementsByClassName[/rml]

  • jsiegmund
  • Registratie: Januari 2002
  • Laatst online: 10:13
Ok een meer gedetailleerde probleemomschrijving is wel op z'n plaats denk ik.

Ik heb een grote tabel, bestaande uit:

- header met 20 cellen waarvan er 17 een naam bevatten
- 30 tal rijen
- herhaling van de headers voor het overzicht
- 30 tal rijen
- herhaling van de headers voor het overzicht
- 30 tal rijen
- herhaling van de headers voor het overzicht

Het gaat om een roostermatrix, elke cell kan aangeklikt worden (onclick event) om de gebruiker de mogelijkheid te geven iemand in te roosteren (verticaal staan de verschillende jobs).

Om de boel overzichtelijk te maken, wil ik de matrix kleuren aan de hand van de muispositie. Daarom bevat elke cell mouseover en mouseout events, die ervoor moeten zorgen dat:
- in iedere header de juiste kolom gekleurd wordt
- horizontaal de juiste job een kleurtje krijgt

Hopelijk een beetje logisch verhaal zo, ik kan jullie niet 1-2-3 toegang geven tot een voorbeeld.

Nu probeerde ik dus met die mouseover events de header kolommen te kleuren door ze een name= attribuut te geven, dat werkt dus niet. Sowieso is het op deze manier in IE echt HEEL ERG langzaam. FF niet, maar uiteraard werkt het overgrote deel van de gebruikers met IE.

Heldere ideeen over een slimme oplossing?

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 18:59

crisp

Devver

Pixelated

iCe01 schreef op dinsdag 24 januari 2006 @ 19:27:
[...]
Heldere ideeen over een slimme oplossing?
Je kan met classes werken en getElementsByClassName gebruiken (voor voorbeeld zie link in djlucs' post), of je kan door een duidelijke scheiding aan te brengen tussen headers en data (bijvoorbeeld door met thead en tbody te werken) mbv getElementsByTagName bepaalde elementen en hun children benaderen (cellIndex kan een handige property zijn overigens).

Voor snelheid heb ik 1 tip: initialiseren en referenties cachen - kan je het meteen unobtrusive aanpakken door de eventhandlers dynamisch te koppelen.

[ Voor 14% gewijzigd door crisp op 25-01-2006 00:07 ]

Intentionally left blank


  • jsiegmund
  • Registratie: Januari 2002
  • Laatst online: 10:13
Dat eerste deel snap ik. Ik krijg dat script niet aan de praat. Beetje vaag, ook geen foutmeldingen maar werken doet het niet (zowel IE als FF). Maar met het verschil TH en TD moet ik er ook wel uit komen.

Dat tweede deel is een beetje abacadabra voor me, wat bedoel je precies?


Daarbij is getElementsByClassName ook niet geheel handig. Ik verander het uiterlijk van een header cell door de CSS class aan te passen. Dat werkt snel en handig, maar schiet natuurlijk niet op als ik vervolgens de classname ga lopen aanpassen in m'n script :) Maar goed, kan er wel omheen borduren.

[ Voor 38% gewijzigd door jsiegmund op 25-01-2006 11:51 ]


  • jsiegmund
  • Registratie: Januari 2002
  • Laatst online: 10:13
Kleine update... het werkt nu wel zoals het zou moeten werken, met gebruik van de classnames... maar het is nu wel zo traag geworden dat het eigenlijk niet op te leveren valt.

Ik neem aan dat je bedoeld dat het de moeite loont om referenties naar de objecten in arrays op te slaan, zodat je niet heel het document hoeft te doorzoeken? Klinkt aannemelijk maar kun je me een klein voorbeeld geven van de manier waarop je dat doet?

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 18:59

crisp

Devver

Pixelated

Ik zal kijken of ik een voorbeeldje voor je kan bakken, maar dat zal wel eind van de middag/vanavond worden...

Intentionally left blank


  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 13-04 10:40
Even heel simpel gedacht:

De 1e kolom in de rij een className geven:
code:
1
2
onmouseover="this.parentNode.childNodes[0].className='show';
onmouseout="this.parentNode.childNodes[0].className.replace(/show/g, '');


En dan nog de kolomheaders een kleurtje geven:
JavaScript:
1
2
3
4
5
6
                //td    //tr              //tbody       //table
var heads=this.parentNode.parentNode.parentNode.getElementsByTagName('thead');
var i=head.length;
while(i--) {
  head.childNodes[this.cellIndex].className='show';
}

  • jsiegmund
  • Registratie: Januari 2002
  • Laatst online: 10:13
djluc schreef op woensdag 25 januari 2006 @ 13:54:
En dan nog de kolomheaders een kleurtje geven:
JavaScript:
1
2
3
4
5
6
                //td    //tr              //tbody       //table
var heads=this.parentNode.parentNode.parentNode.getElementsByTagName('thead');
var i=head.length;
while(i--) {
  head.childNodes[this.cellIndex].className='show';
}
Werkt wel in IE, niet in FF. Daar lijkt de index niet hetzelfde te zijn. De verkeerde kolommen worden gehighlight en sommige kolommen helemaal niet.

Sterker nog... het lijkt wel alsof FF 2x zoveel nodes heeft. Bij de 4e kolom krijg ik header 2 gehighlight, bij de 5e niks, bij de 6e header 3... Misschien dat er ergens nog elementen tussen gestopt worden ofzo, zal eens zoeken.

Dit is overigens inderdaad vele malen sneller!

Update: er zitten inderdaad nodes tussen in FF... maar door met getElementsByTagName de "echte" th's eruit te filteren valt dat probleem te omzeilen. Nu werkt het helemaal naar behoren, en snel! Thanks! :)

[ Voor 37% gewijzigd door jsiegmund op 25-01-2006 18:31 ]


  • crisp
  • Registratie: Februari 2000
  • Laatst online: 18:59

crisp

Devver

Pixelated

De extra nodes zijn textNodes die enkel whitespace bevatten - Gecko neemt die ook mee in de DOM structuur itt IE ;)

Intentionally left blank


  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 13-04 10:40
Zoals al vermeld moet je inderdaad wat whitespaces negeren. Hier vind je wat meer info daarover: http://developer.mozilla.org/en/docs/Whitespace_in_the_DOM inclusief handige functies.

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 18:59

crisp

Devver

Pixelated

Ik zal niet onthouden wat ik gefabriceerd had:
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
<style type="text/css">

table#matrix {
    border-collapse: collapse;
}

table#matrix thead tr {
    background-color: yellow;
}

table#matrix thead tr th.active {
    background-color: red;
}

table#matrix tbody tr.active {
    background-color: red;
}

</style>
<table id="matrix" border="1">
    <thead>
        <tr>
            <th>Job</th>
            <th>Column 1</th>
            <th>Column 2</th>
            <th>Column 3</th>
            <th>Column 4</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>job 1</td>
            <td>data</td>
            <td>data</td>
            <td>data</td>
            <td>data</td>
        </tr>
        <tr>
            <td>job 2</td>
            <td>data</td>
            <td>data</td>
            <td>data</td>
            <td>data</td>
        </tr>
        <tr>
            <td>job 3</td>
            <td>data</td>
            <td>data</td>
            <td>data</td>
            <td>data</td>
        </tr>
        <tr>
            <td>job 4</td>
            <td>data</td>
            <td>data</td>
            <td>data</td>
            <td>data</td>
        </tr>
    </tbody>
</table>
<script type="text/javascript">

var matrix_headers = [];
var init_matrix = function()
{
    window.matrixCurHeader = null;

    var matrix = document.getElementById('matrix');
    if (matrix)
    {
        var i, j, k, cells, rows;

        var headers = matrix.getElementsByTagName('thead');
        i = headers.length;
        while (i--)
        {
            matrix_headers[i] = headers[i].rows[0].cells;
        }

        var bodys = matrix.getElementsByTagName('tbody');
        i = bodys.length;
        while (i--)
        {
            rows = bodys[i].rows, j = rows.length;
            while (j--)
            {
                cells = rows[j].cells, k = cells.length;
                while (--k)
                {
                    cells[k].onmouseover = activate;
                    cells[k].onmouseout = deactivate;
                }
            }
        }
    }
}();

function activate()
{
    this.parentNode.className = 'active';
    var i = matrix_headers.length;
    while (i--)
    {
        matrix_headers[i][this.cellIndex].className = 'active';
    }
}

function deactivate()
{
    this.parentNode.className = '';
    var i = matrix_headers.length;
    while (i--)
    {
        matrix_headers[i][this.cellIndex].className = '';
    }
}

</script>

Intentionally left blank


  • jsiegmund
  • Registratie: Januari 2002
  • Laatst online: 10:13
Ok zo zou het inderdaad nog sneller moeten werken, van tevoren de juiste headers opslaan in een array en dat array later doorlopen ipv elke keer opnieuw zoeken... klinkt in ieder geval sneller :) Bedankt voor de input!
Pagina: 1