2008-11-10 18 views
17

Tôi có một số mã làm điều này:getElementsByName trong IE7

var changes = document.getElementsByName(from); 
for (var c=0; c<changes.length; c++) { 
    var ch = changes[c]; 
    var current = new String(ch.innerHTML); 
    etc. 
} 

này hoạt động tốt trong FF và Chrome nhưng không phải trong IE7. Có lẽ vì getElementsByName không hoạt động trong IE. Cách giải quyết tốt nhất là gì?

Trả lời

17

Trong trường hợp bạn không biết tại sao điều này không làm việc trong IE, đây là the MSDN documentation on that function:

Khi bạn sử dụng phương thức getElementsByName, tất cả các yếu tố trong văn bản có thuộc tính NAME quy định hoặc ID giá trị thuộc tính được trả về.

Các yếu tố hỗ trợ cả thuộc tính NAME và thuộc tính ID được bao gồm trong bộ sưu tập được trả về theo phương thức getElementsByName, nhưng các phần tử có expando NAME không được bao gồm trong bộ sưu tập; do đó, phương pháp này không thể được sử dụng để truy xuất thẻ tùy chỉnh theo tên.

Firefox cho phép getElementsByName() truy xuất các phần tử sử dụng tên mở rộng NAME, đó là lý do tại sao nó hoạt động. Cho dù đó có phải là Good Thing ™ có thể là một cuộc tranh luận, nhưng đó là thực tế của nó. Vì vậy, một tùy chọn là sử dụng phương thức DOM getAttribute() để yêu cầu thuộc tính NAME và sau đó kiểm tra giá trị để xem liệu đó có phải là những gì bạn muốn hay không, và nếu có, hãy thêm nó vào một mảng. Tuy nhiên, điều này đòi hỏi bạn phải lặp lại tất cả các nút trong trang hoặc ít nhất trong một phần con, điều này sẽ không hiệu quả nhất. Bạn có thể hạn chế danh sách đó trước bằng cách sử dụng một cái gì đó như getElementsByTagName() có lẽ.

Một cách khác để thực hiện việc này, nếu bạn kiểm soát HTML của trang, là cung cấp cho tất cả các yếu tố cần quan tâm mà một Id chỉ thay đổi theo số, ví dụ::

<div id="Change0">...</div> 
<div id="Change1">...</div> 
<div id="Change2">...</div> 
<div id="Change3">...</div> 

Và sau đó có JavaScript như thế này:

// assumes consecutive numbering, starting at 0 
function getElementsByModifiedId(baseIdentifier) { 
    var allWantedElements = []; 
    var idMod = 0; 
    while(document.getElementById(baseIdentifier + idMod)) { // will stop when it can't find any more 
     allWantedElements.push(document.getElementById(baseIdentifier + idMod++)); 
    } 
    return allWantedElements; 
} 

// call it like so: 
var changes = getElementsByModifiedId("Change"); 

Đó là một hack, tất nhiên, nhưng nó sẽ làm công việc bạn cần và không quá kém hiệu quả so sánh với một số hack khác.

Nếu bạn đang sử dụng một khung công cụ JavaScript, bạn có nhiều lựa chọn hơn, nhưng tôi không có thời gian để đi vào những chi tiết cụ thể trừ khi bạn cho biết bạn đang sử dụng. Cá nhân, tôi không biết làm thế nào mọi người sống mà không có một, họ tiết kiệm rất nhiều thời gian, công sức và thất vọng mà bạn không thể đủ khả năng không để sử dụng một.

+0

Lấy tài liệu MSDN như là "thực hiện chính xác" có vẻ như một lập trường kỳ lạ. Tên không phải là ID. MSFT đã sai, sai cách. Người ta có thể tranh luận yếu tố nào nên có tên, nhưng trả về một yếu tố không có tên chỉ đơn giản là ngớ ngẩn. (tin đồn có nó là cố định trong chế độ IE8 std) – scunliffe

+0

tài liệu MSDN * là * thực hiện đúng cho IE 7 - poster ban đầu cho biết IE7 đã phá vỡ mã của mình, trong trường hợp bạn không đọc bài viết của mình. OP đã áp dụng thuộc tính name như là một thuộc tính expando trên một thẻ mà tên đó không được cho phép, vì vậy IE không trả về nó, theo tài liệu. –

+3

Tôi xin lỗi, nhưng ** trong đó ** trong câu hỏi OP là có * bất kỳ đề cập * của * thiết lập * tên? Tôi chỉ thấy mã nói rằng OP đã cố gắng lặp qua các mục được truy xuất bằng cách sử dụng 'document.getElementsByName (name)'. Tôi vẫn đứng theo tuyên bố của tôi, rằng việc thực hiện '.getElementsByName (name)' là không chính xác trong IE (trong tất cả các phiên bản cũ). – scunliffe

4

Có một vài vấn đề:

  1. IE thực sự bối rối id="" là với name=""
  2. name="" không được phép trên <span>

Để khắc phục, tôi đề nghị:

  1. Thay đổi tất cả name="" thành class=""
  2. Thay đổi mã của bạn như thế này:

-

var changes = document.getElementById('text').getElementsByTagName('span'); 
for (var c=0; c<changes.length; c++) { 
var ch = changes[c]; 

if (ch.className != from) 
continue; 

var current = new String(ch.innerHTML); 
+0

Vâng, cảm ơn. Trang này ở đây (http://lwww.dege.ukfsn.org/encrypt/decode.php) đó là một minh hoạ đơn giản về việc phá vỡ mã thông qua phân tích tần số các chữ cái. Bạn có thể cần phải nhấn tab khi bạn nhập một chữ cái trong IE. Trong FF, một sự trở lại cũng giống như vậy. – sa386

+1

cảm ơn. Thay đổi thành lớp học là giải pháp tốt – sa386

+0

Lúc đầu tôi không nghĩ rằng điều này làm việc trong IE 11 của tôi cũng như IE 8, nhưng viết hoa của tôi là không chính xác trên 'Id' trong .getElementById(). Tôi đã phạm sai lầm đó rất nhiều lần! Nhưng sau khi sửa chữa * lỗi của riêng tôi *, điều này làm việc rất tốt trong cả IE 8 và IE 11. Cảm ơn bạn đã giải pháp tuyệt vời! nếu chỉ có IE wud làm việc cũng như các trình duyệt khác! Tôi hy vọng Edge không tệ. Thời gian sẽ trả lời. –

1

getElementsByName được hỗ trợ trong IE, nhưng có lỗi. Đặc biệt, nó trả về các phần tử có ‘id’ khớp với giá trị đã cho, cũng như ‘name’. Không thể biết đó có phải là vấn đề bạn đang gặp phải mà không có nhiều ngữ cảnh, mã và thông báo lỗi thực tế hơn không.

Nói chung, getElementsByName có lẽ là tốt nhất nên tránh, vì thuộc tính ‘name’ trong HTML có một số mục đích chồng chéo có thể gây nhầm lẫn. Sử dụng getElementById đáng tin cậy hơn nhiều. Khi làm việc cụ thể với các trường biểu mẫu, bạn có thể sử dụng form.elements [name] đáng tin cậy hơn để truy xuất các trường bạn đang tìm kiếm.

+0

getElementsByName thực sự hữu ích nếu bạn * chỉ * tìm kiếm các trường biểu mẫu mà thuộc tính NAME thực sự là một phần của thông số W3C. Điều đó nói rằng, nó sẽ là một điều hiếm khi thực sự sử dụng nó. –

2

Không phổ biến lắm khi tìm các phần tử sử dụng thuộc tính NAME. Tôi khuyên bạn nên chuyển sang thuộc tính ID.

Bạn tuy nhiên có thể tìm thấy các yếu tố với một tên cụ thể sử dụng jQuery:

$("*[name='whatevernameYouWant']"); 

này sẽ trả lại tất cả các yếu tố với tên được đặt.

+4

Tôi đã tự hỏi khi nào câu trả lời bắt buộc của jQuery sẽ xuất hiện, thường họ sẽ hạ cánh trong vòng vài giây sau khi đăng bài JavaScript. –

+0

đó là vì viết jQuery nhanh hơn rất nhiều rồi javascript thuần :) –

1

Tôi đã thành công sử dụng một wrapper để trả lại một mảng của các yếu tố. Hoạt động trong IE 6 và 7. Hãy nhớ rằng nó không phải 100% chính xác giống như document.getElementsByName, vì nó không phải là một NodeList. Nhưng đối với những gì tôi cần nó, đó là chỉ cần chạy một vòng lặp for trên một mảng các phần tử để làm những việc đơn giản như thiết lập .disabled = true, nó hoạt động đủ tốt.

Mặc dù chức năng này vẫn sử dụng getElementsByName, nó hoạt động nếu được sử dụng theo cách này. Xem cho chính mình.

function getElementsByNameWrapper(name) { 
    a = new Array(); 

    for (var i = 0; i < document.getElementsByName(name).length; ++i) { 
    a.push(document.getElementsByName(name)[i]); 
    } 

    return a; 
} 
1

Cách giải quyết

   var listOfElements = document.getElementsByName('aName'); // Replace aName with the name you're looking for 
      // IE hack, because it doesn't properly support getElementsByName 
      if (listOfElements.length == 0) { // If IE, which hasn't returned any elements 
       var listOfElements = []; 
       var spanList = document.getElementsByTagName('*'); // If all the elements are the same type of tag, enter it here (e.g.: SPAN) 
       for(var i = 0; i < spanList.length; i++) { 
        if(spanList[i].getAttribute('name') == 'aName') { 
         listOfElements.push(spanList[i]); 
        } 
       } 
      }