getElementOnDOMIndexArray, handig?

Pagina: 1
Acties:

  • Rekcor
  • Registratie: Februari 2005
  • Laatst online: 08-10-2025
Ik heb onderstaande functies gebakken, en was benieuwd
- of ik niet vreselijk omslachtig zit te doen
- of die functies nog wat te optimaliseren zijn

Probleem: ik wil naar een element kunnen verwijzen zonder 'getElementById'.

Oplossing: wat maakt een element nog meer uniek naast zijn id? Juist, zijn positie in de DOM tree.

Neem bijv.

HTML:
1
2
3
4
5
6
7
8
9
<html>
  <head></head>
  <body>
    <form>
      <input id="a" type="text"></form>
      <input id="b" type="text"></form>
    </form>
  </body>
</html>

Hiervoor geldt, als we even alle #text elementen negeren:

JavaScript:
1
2
3
 //element 1 is gelijk element 2
 var element1 = document.getElementById('b');
 var element2 = document.childNodes[0].childnodes[1].childnodes[0].childnodes[1];

Wat ik nu heb gemaakt, is een functie die een element teruggeeft op basis van de methode waarmee ik element2 te pakken krijg. Ik zet daartoe de waarden a, b, c en d in een array:

JavaScript:
1
document.childNodes[a].childnodes[b].childnodes[c].childnodes[d]; 

en noem die array een DOM index array. De functie getElementOnDOMIndexArray geeft op basis van deze array het originele element terug.

JavaScript:
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
/**
 * function getElementDOMIndexArray(oElement)
 * 
 * + gets DOM index array of element; e.g. 
 *
 *  +--- HTML -----------------------+ DOM index array +
 *  | <html>                         | 0               |
 *  |  <head></head>                 | 0,0             |
 *  |  <body>                        | 1,0             |
 *  |   <form>                       | 0,1,0           |
 *  |    <input type="text" id="a">  | 0,0,1,0         |
 *  |   </form>                      |                 | 
 *  |   <form>                       | 1,1,0           |
 *  |    <input type="text" id="b">  | 0,1,1,0         |
 *  |    <input type="text" id="c">  | 1,1,1,0         |
 *  |  </body>                       |                 | 
 *  | </html>                        |                 |
 *  +--------------------------------+-----------------+
 *  
 *  because:
 *   var el = document.getElementById('c');
 *   
 *  equals
 *   var el = document.childNodes[0].childnodes[1].childnodes[1].childnodes[1] //DOM index array 1,1,1,0
 *   
 * @param  element  DOM element
 * 
 * @returns  array  DOM index array        
 **/    
function getElementDOMIndexArray(oElement, aReturn)
{ 
  if (!aReturn) aReturn = new Array(); 
  aReturn[aReturn.length] = getIndexOfElementInChildNodesArray(oElement);
  
if (oElement.parentNode && getIndexOfElementInChildNodesArray(oElement.parentNode)!=-1)
  {    
    aReturn = getElementDOMIndexArray(oElement.parentNode, aReturn);
    
  }  
  
  return aReturn;  
}

/**
 * function getElementIndexInChildNodesArray(oElement)
 * 
 * + returns the index of an element in its parentNode childNodes array
 * 
 * @param  element  DOM element
 * 
 * @returns integer index number
 **/         
function getIndexOfElementInChildNodesArray(oElement)
{
  oParent = oElement.parentNode;
  
  if (oParent)
  {
    var iLength = oParent.childNodes.length;   
    for (var i=0;i<iLength;i++)
    {      
      if (oElement == oParent.childNodes[i])
      {        
        return i;
      }
    }
  }
  return -1;
}

/**
 * function getElementOnDOMIndexArray(aDOMIndexArray)
 * 
 * + returns an element using its DOM index array
 * 
 * @param  aDOMIndexArray  DOM index array, see documentation on getElementDOMIndexArray
 * 
 * @returns  element
 **/        
function getElementOnDOMIndexArray(aDOMIndexArray)
{    
  var oElement = window.document; 
  
  iLength = aDOMIndexArray.length;
  
  for (i=iLength-1; i>=0; i--)
  {    
    oElement = oElement.childNodes[aDOMIndexArray[i]];    
  }
      
  return oElement;   
}

[ Voor 0% gewijzigd door Rekcor op 23-10-2006 12:10 . Reden: wat alerts uit de code gehaald ]


  • user109731
  • Registratie: Maart 2004
  • Niet online
getElementDOMIndexArray hoeft niet recursief, dat kan ook gewoon met een while loop:
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function getElementDOMIndexArray(e) {
    var retval = [];
    do {
        if (e.parentNode) 
            retval.push(getElementIndex(e));
    } while(e = e.parentNode);
    return retval;
}
function getElementIndex(e) {
    var p=e.parentNode;
    for(var i=0, c=0; i<p.childNodes.length; i++) {
        if (e === p.childNodes[i]) return c;
        if (p.childNodes[i].nodeType == 1) c++;
    }
    return -1;
}

Is waarschijnlijk wat sneller en ik kijk hier ook gelijk naar het node type, zodat je alleen elementen pakt, en geen andere soorten nodes.

Verder ben ik wel benieuwd waarom je dit zo doet? Stel dat je een node invoegt, dan werkt het toch al niet meer? :)

edit: ik zie dat jij 'm andersom nummert, dus ik heb unshift vervangen door push. Is het niet handiger om je volgorde om te draaien? Zodat head 0,0 is, body 0,1, ...

[ Voor 69% gewijzigd door user109731 op 23-10-2006 13:14 ]


  • Rekcor
  • Registratie: Februari 2005
  • Laatst online: 08-10-2025
Bedankt!

Deze functie is handig als je geen id mee kunt geven aan elementen.

Het nadeel is inderdaad dat je tussendoor niet ongestraft DOM-elementen in kunt voegen (maar in mijn toepassing gebeurt dat ook niet)

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

crisp

Devver

Pixelated

Kijk dan eens naar Dean's cssQuery

Intentionally left blank


  • Rekcor
  • Registratie: Februari 2005
  • Laatst online: 08-10-2025
Bedankt!

De uiteindelijke code (mocht iemand ter wereld er in geinteresseerd zijn :))

JavaScript:
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
/**
 * function getElementDOMIndexArray(oElement)
 * 
 * + gets DOM index array of element; e.g. 
 *
 *  +--- HTML -----------------------+ DOM index array +
 *  | <html>                         | 0               |
 *  |  <head></head>                 | 0,0             |
 *  |  <body>                        | 0,1             |
 *  |   <form>                       | 0,1,0           |
 *  |    <input type="text" id="a">  | 0,1,0,0         |
 *  |   </form>                      |                 | 
 *  |   <form>                       | 0,1,1           |
 *  |    <input type="text" id="b">  | 0,1,1,0         |
 *  |    <input type="text" id="c">  | 0,1,1,1         |
 *  |  </body>                       |                 | 
 *  | </html>                        |                 |
 *  +--------------------------------+-----------------+
 *  
 *  because:
 *   var el = document.getElementById('c');
 *   
 *  equals
 *   var el = document.childNodes[0].childnodes[1].childnodes[1].childnodes[1] //DOM index array 1,1,1,0
 *   
 * @param  element  DOM element
 * 
 * @returns  array  DOM index array        
 **/    
function getElementDOMIndexArray(oElement)
{
    var retval = [];
    do {
        if (oElement.parentNode) 
            retval.unshift(getElementIndex(oElement));
    } while(oElement = oElement.parentNode);
    return retval;
} 

/**
 * function getElementIndexInChildNodesArray(oElement)
 * 
 * + returns the index of an element in its parentNode childNodes array
 * 
 * @param  element  DOM element
 * 
 * @returns integer index number
 **/         
function getElementIndex(oElement)
{
    var p=oElement.parentNode;
    for(var i=0, c=0; i<p.childNodes.length; i++) {
        if (oElement === p.childNodes[i]) return c;
        if (p.childNodes[i].nodeType == 1) c++;
    }
    return -1;
}

/**
 * function getElementOnDOMIndexArray(aDOMIndexArray)
 * 
 * + returns an element using its DOM index array
 * 
 * @param  aDOMIndexArray  DOM index array, see documentation on getElementDOMIndexArray
 * 
 * @returns  element
 **/        
function getElementOnDOMIndexArray(aDOMIndexArray)
{ 
  var oElement = window.document; 

  iLength = aDOMIndexArray.length;
  
  for (i=0; i<iLength; i++)
  {        
    oElement = oElement.childNodes[aDOMIndexArray[i]];        
  }  
        
  return oElement;   
}