2012-12-16 18 views
5

Tôi đang sử dụng thẻ tùy chỉnh để xác định các phần trong một ứng dụng, vì vậy tôi có một cái gì đó như thế này:Javascript Bắt yếu tố cụ thể (công ty mẹ) theo tên

<mysection> 

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

</mysection> 

Tôi đang sử dụng sau đây và có thể nhận được thẻ (in để an ủi, mọi thứ đều groovy)

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

vấn đề tôi đang gặp là tìm lĩnh vực con theo tên:

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

... vì tôi không muốn nhận bất kỳ phần 'khác' nào có thể có đầu vào với tên 'myfield'.

EDIT:

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

đã được đề xuất và trả về để an ủi các nội dung phần, tuy nhiên, getElementsByName ném một lỗi:

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

Tại sao lại ghét 'id'? –

+0

Bằng cách sử dụng id bạn có thể loại bỏ tất cả các vấn đề của bạn. –

+0

Vì đây là một dự án lớn và tôi không muốn quá tải ID. – Fluidbyte

Trả lời

9

Sử dụng getElementsByTagName()getElementsByName() sẽ trả về một NodeList, bạn cần để lấy phần tử đầu tiên của danh sách như sau:

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

Sửa

Bạn đã đúng, getElementsByName không hợp lệ cho một phần tử. Tôi không chắc chắn làm thế nào để bản địa hóa các chức năng của nó như bạn đang cố gắng để làm. Có vẻ như nó sẽ chỉ hoạt động với document. Bạn có thể phải tự mình thực hiện getElementsByName nếu bạn muốn sử dụng nó trong phạm vi địa phương hóa.

Second Sửa

Để được tốt đẹp, tôi đã thực hiện điều đó cho bạn: D Ở đây nó là trong tất cả các "vinh quang" của nó.

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]; 

sửa chữa nhỏ

Tôi đã sai đi qua phần tử và không con của nó vào đệ quy. Đoạn mã trên đã được chỉnh sửa với đối số thích hợp được truyền ngay bây giờ. Xem fiddle làm việc: http://jsfiddle.net/js6NP/5/

+0

Lưu ý: 'getElementsByTagName()' và 'getElementsByName()' không trả về 'Mảng'. Thay vào đó, họ trả về ['NodeList'] (https://developer.mozilla.org/en-US/docs/DOM/NodeList). –

+0

@Derek - Không phải về mặt kỹ thuật, đã thay đổi để phản ánh rằng đó là một NodeList chứ không phải một mảng. –

+0

'getElementsByName' đã trả lại lỗi:' Loại lỗi không hợp lệ: Đối tượng # không có phương thức 'getElementsByName'' – Fluidbyte

0

Chỉ cần sử dụng một ID thay vì:

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

ID là supposed to be unique on a page. Vì vậy, bạn không nên gặp sự cố khi truy cập phần tử phù hợp.

Nếu bạn thực sự sử dụng tên/tagname, getElementsByTagNamegetElementsByName cả luôn luôn trả về một array (Một chiếc xe rỗng nếu không có yếu tố được tìm thấy).bạn có thể truy cập phần tử phù hợp, giống như bạn truy cập các phần tử trong mảng:
document.getElementsByTagName('mysection')[0]; Đối với phần tử đầu tiên có tên thẻ mysection.

3

Tôi thực sự tìm ra một cách đơn giản hơn nhiều để xử lý này:

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

Tại đây bạn có thể xem ví dụ nơi mà nó chỉ đổi lĩnh vực này bên trong phần quy định: http://jsfiddle.net/fluidbyte/kph6H/

QSA hỗ trợ các trình duyệt hiện đại và tương thích xuống IE8, Dưới đây là một polyfill để hỗ trợ quay lại IE7: https://gist.github.com/2724353

Các vấn đề liên quan