2010-12-29 18 views
7

Tôi đang gặp một thời gian khó khăn chuyển đổi một NodeList để một mảng trong IE 8. Các công trình sau đây một cách hoàn hảo trong Chrome, nhưng trong IE 8 toArray() không được công nhận là hợp lệ:Chuyển đổi NodeList để mảng

NodeList.prototype.toArray = function() { 
    var a = []; 

    for (var i = 0, len = this.length; i < len; i++) { 
     a[i] = this[i]; 
    } 

    return a; 
} 

document.all.tags("div").toArray(); 

tôi đã thử thêm một hàm nguyên mẫu vào một mảng chỉ để kiểm tra sự tỉnh táo của tôi và nó hoạt động chính xác. Điều đó làm cho tôi nghĩ rằng IE 8 không thực sự trở lại một NodeList? Dưới đây là ví dụ đầy đủ:

http://jsfiddle.net/e4RbH/

Tôi đang làm gì sai?

+1

Không có tiêu chuẩn hiện hành mà nói rằng 'NodeList' phải là một hàm constructor có thể nhìn thấy và alterable, hoặc nếu có hàm khởi tạo có thể nhìn thấy dưới dạng 'NodeList', nó sẽ được sử dụng làm kiểu trả về của tất cả các phương thức trả về NodeList. (Sau khi tất cả, một NodeList 'childNodes' và một NodeList' getElementsByTagName' làm những việc rất khác nhau.) Prototyping vào các đối tượng JS gốc được xác định bởi tiêu chuẩn ECMAScript và là đáng tin cậy; prototyping vào DOM Nút và các đối tượng khác không được xác định theo tiêu chuẩn ngôn ngữ là không đáng tin cậy và nên tránh. – bobince

Trả lời

3

Trước tiên, không sử dụng document.all - không chuẩn và không được dùng nữa. Sử dụng document.getElementsByTagName để nhận các yếu tố DIV trong trường hợp của bạn.

Thứ hai, không mở rộng đối tượng DOM chẳng hạn như NodeList - đối tượng dựng sẵn là một giống rất lạ và không bắt buộc phải hoạt động giống như bất kỳ đối tượng nào khác mà bạn thường làm việc. Xem bài viết này để có giải thích chi tiết về điều này: What's wrong with extending the DOM.

+0

Tôi đã sử dụng 'getElementByTagName', nhưng chuyển sang' document.all' trong khi thử nghiệm. Đây là một phần của một vấn đề lớn hơn và tôi đã cố gắng đơn giản hóa nó. Vấn đề thực sự đã kết thúc là một phương thức mở rộng cho 'Array' được triển khai không đúng và ảnh hưởng đến mã khác. –

1

IE không hỗ trợ NodeList theo cách tiêu chuẩn. Đây là lý do tại sao bạn nên cuộn vùng tên của riêng mình và KHÔNG mở rộng các đối tượng lõi trình duyệt.

Bạn có thể làm alert(typeof window.NodeList) và xem nó có được xác định hay không.

+0

Trong Chrome, đó là 'hàm', trong IE 8, đó là' đối tượng', không phải 'không xác định'. Dù bằng cách nào, điều này đã được gỡ lỗi một số mã cũ mà tôi đã bây giờ refactored vào một không gian tên tôi đã có. –

+0

Bạn phải có phiên bản mới hơn của IE8 vì tôi không được xác định. –

3

Cũ câu hỏi, nhưng đây là một cố gắng & phương pháp đúng:

var nodes=document.querySelectorAll("div"); // returns a node list 
nodes=Array.prototype.slice.call(nodes); // copies to an array 

Giải thích

  • document.querySelectorAll sử dụng một bộ chọn CSS-style để tìm các yếu tố và trả về một danh sách node. Nó hoạt động như của IE 8.
  • Phương thức slice sao chép một phần của một bộ sưu tập giống như mảng (trong trường hợp này là tất cả) thành một mảng mới.
  • call cho phép bạn mượn một phương pháp từ một đối tượng để sử dụng trên một

Để tìm danh sách nút bạn cũng có thể đã sử dụng 'document.getElementsByTagName(), nhưng điều này là linh hoạt hơn.