2012-12-16 12 views
5

używam niestandardowe znaczniki zdefiniować sekcje w aplikacji, więc mam coś takiego:JavaScript Pierwsze konkretny element (rodzica) wg nazwy

<mysection> 

    <form> 
     <input name="myfield"> 
    </form> 

</mysection> 

Używam następujących i stanie uzyskać znacznik (wydrukowany do konsoli, wszystko jest Groovy)

var parent = document.getElementsByTagName('mysection'); 

problem mam jest znalezienie boiska dzieci o nazwie:

var myfield = parent.getElementsByName("myfield"); 

... ponieważ nie chcę odbierać żadnych innych "sekcji", które mogą mieć dane wejściowe o nazwie "myfield".

EDIT:

var parent = document.getElementsByTagName('mysection')[0]; 

sugerowano i wraca do konsoli zawartość sekcji, jednak getElementsByName zgłasza błąd:

Uncaught TypeError: Object #<NodeList> has no method 'getElementsByName' 
+2

Dlaczego nienawiść do "id"? –

+0

Używając identyfikatora, możesz pozbyć się wszystkich swoich problemów. –

+0

Ponieważ jest to duży projekt i nie chcę przeciążać identyfikatora. – Fluidbyte

Odpowiedz

9

Korzystanie getElementsByTagName() i getElementsByName() zwróci NodeList, trzeba Aby uzyskać pierwszy element listy w następujący sposób:

var parent = document.getElementsByTagName('mysection')[0]; 
var myfield = parent.getElementsByName("myfield")[0]; 

Edit

Byłaś poprawne, getElementsByName nie jest ważny element. Nie jestem pewien, jak zlokalizować jego funkcjonalność, tak jak próbujesz to zrobić. Wygląda na to, że będzie działać tylko dla document. Być może będziesz musiał napisać własną implementację getElementsByName, jeśli chcesz użyć go w zlokalizowanym zasięgu.

Druga Edycja

być miły, zrobiłem to dla ciebie realizacji: D Oto ona w całej swej chwale „”

Element.prototype.getElementsByName = function (arg) { 
    var returnList = []; 
    (function BuildReturn(startPoint) { 
     for (var child in startPoint) { 
      if (startPoint[child].nodeType != 1) continue; //not an element 
      if (startPoint[child].getAttribute("name") == arg) returnList.push(startPoint[child]); 
      if (startPoint[child].childNodes.length > 0) { 
       BuildReturn(startPoint[child].childNodes); 
      } 
     } 
    })(this.childNodes); 
    return returnList; 
}; 
var parent = document.getElementsByTagName('mysection')[0]; 
var myfield = parent.getElementsByName("myfield")[0]; 

Mała poprawka

byłem nieprawidłowo przejściu elementu, a nie swoje dzieci do rekursji. Powyższy kod został zmodyfikowany przy użyciu właściwego argumentu przekazanego teraz. Zobacz skrzypce roboczy: http://jsfiddle.net/js6NP/5/

+0

Uwaga: 'getElementsByTagName()' i 'getElementsByName()' nie zwracaj 'Tablicy'. Zamiast tego zwracają ['NodeList'] (https://developer.mozilla.org/en-US/docs/DOM/NodeList). –

+0

@Derek - Nie technicznie, dokonano zmiany, aby odzwierciedlić, że jest to NodeList, a nie tablica. –

+0

'getElementsByName' zwraca błąd:' Uncaught TypeError: Object # nie ma metody 'getElementsByName'' – Fluidbyte

0

Wystarczy użyć identyfikatora zamiast:

<mysection> 
    <form> 
     <input name="myfield" id="fieldName"> 
    </form> 
</mysection> 
var myfield = document.getElementById("fieldName"); 

ID są supposed to be unique on a page. Nie powinieneś mieć problemów z dostępem do właściwego elementu.

Jeśli naprawdę mieć używać nazwę/zmiennej, getElementsByTagName i getElementsByName zarówno zawsze zwracają array (A pustą jeśli żaden element nie został znaleziony).możesz uzyskać dostęp do odpowiedniego elementu, tak jak w przypadku dostępu do elementów w tablicach:
document.getElementsByTagName('mysection')[0]; Dla pierwszego elementu ze zmienną mysection.

3

faktycznie znalazłem o wiele bardziej prosty sposób obsłużyć to:

document.querySelectorAll('mysection [name="myfield"]'); 

Tutaj można zobaczyć przykład gdzie to tylko modyfikuje pole wewnątrz sekcji określonej: http://jsfiddle.net/fluidbyte/kph6H/

QSA obsługuje nowoczesnych przeglądarek i jest kompatybilny do IE8, Oto polyfill do obsługi z powrotem do IE7: https://gist.github.com/2724353

Powiązane problemy