2012-12-19 29 views
18

Something tốt đẹp với đồng bằng javascript sẽ được để có thể sử dụng forEach, map, filter, vv, vào các mục được trả về bởi document.querySelectorAll, document.getElementsBy*, vvLàm thế nào để có forEach có sẵn trên mảng giả được trả về bởi querySelectorAll?

This'd dẫn đến ít phụ thuộc vào jQuery, và mã đơn giản sạch . Ngay bây giờ, đây là cách chúng ta có thể làm điều đó, theo một cách xấu xí:

[].forEach.call(document.querySelectorAll(sel), function(el) { 
}); 

Đây là ... tiết.

Bất kỳ cách nào để có thể sử dụng forEach và lượt thích ngay trên các phần tử được trả lại?

+1

Tại sao mọi người phân bổ mảng ('[]') thay vì sử dụng 'Array.prototype.forEach'? –

Trả lời

14

Một cách ngây thơ sẽ làm điều này nếu bạn đã thử nghiệm trên Chrome:

NodeList.prototype.forEach = Array.prototype.forEach; 

này hoạt động. Trên Webkit. Nó không có trên Firefox. Bởi vì FF trả về một HTMLCollection ...

Các nhất qua trình duyệt cách tôi đã tìm thấy:

NodeList.prototype.forEach = HTMLCollection.prototype.forEach = Array.prototype.forEach; 

Nó không làm việc trên IE8 và giảm mặc dù, bởi vì họ nghẹt thở khi thêm thuộc tính để lưu trữ đối tượng nguyên mẫu.

Danh mục đầy đủ:

NodeList.prototype.forEach = HTMLCollection.prototype.forEach = Array.prototype.forEach; 
NodeList.prototype.map = HTMLCollection.prototype.map = Array.prototype.map; 
NodeList.prototype.filter = HTMLCollection.prototype.filter = Array.prototype.filter; 
NodeList.prototype.reduce = HTMLCollection.prototype.reduce = Array.prototype.reduce; 
NodeList.prototype.reduceRight = HTMLCollection.prototype.reduceRight = Array.prototype.reduceRight; 
NodeList.prototype.every = HTMLCollection.prototype.every = Array.prototype.every; 
NodeList.prototype.some = HTMLCollection.prototype.some = Array.prototype.some; 

Hoặc, để làm hài lòng Bergi thân yêu của chúng tôi (và cũng vì nó sạch):

['forEach', 'map', 'filter', 'reduce', 'reduceRight', 'every', 'some'].forEach(
    function(p) { 
    NodeList.prototype[p] = HTMLCollection.prototype[p] = Array.prototype[p]; 
}); 

Xét liên kết đến perfectionkills, nó chủ yếu là không thích hợp đó. Vấn đề là DOM hầu như không hoạt động giống nhau trên các trình duyệt khi mở rộng. Sửa đổi này là lành mạnh trong tất cả các trình duyệt ngoại trừ IE < = 8.

+4

Tôi thiếu liên kết đến http://perfectionkills.com/whats-wrong-with-extending-the-dom/. Ngoài ra, vui lòng sử dụng vòng lặp cho "danh sách đầy đủ của bạn" – Bergi

+0

@Bergi Edited :) –

+0

Tôi không muốn mở rộng phần vòm. – andlrc

6
function forEach(a, fn) { 
    return [].forEach.call(a, fn); 
}; 

forEach(document.querySelectorAll(sel), function(el) { 
}); 

Và nhiều hơn nữa:

function map(a, fn) { 
    return [].map.call(a, fn); 
}; 
function filter(a, fn) { 
    return [].filter.call(a, fn); 
}; 
function reduce(a, fn) { 
    return [].reduce.call(a, fn); 
}; 
function reduceRight(a, fn) { 
    return [].reduceRight.call(a, fn); 
}; 
function every(a, fn) { 
    return [].every.call(a, fn); 
}; 
function some(a, fn) { 
    return [].some.call(a, fn); 
}; 

Có lẽ bạn sẽ cần

[].slice.call(a) 

trong một số tình huống.

function forEach(a, fn) { 
    return [].forEach.call([].slice.call(a), fn); 
} 
+0

Uh, vâng, quên đề cập đến điều đó. Tôi muốn sử dụng phương pháp 'bind' mặc dù (tôi không nhớ ra khỏi đầu của tôi làm thế nào để làm điều đó). Nhưng tôi vẫn thích cách thể hiện trong câu trả lời của tôi trong số này. Nó cảm thấy "mẹ" hơn. –

+0

@ FlorianMargaine Tôi nghĩ có ai đó đang đại diện cho ai? – andlrc

+1

Không. Thành thật mà nói, câu hỏi/câu trả lời là để săn mũ. Tôi thành thật thích cách thể hiện trong câu trả lời của tôi. Như đã nói trong bình luận trước của tôi, tôi đã biết về cách của bạn rồi - tôi chỉ không đặc biệt thích nó. Bên cạnh đó, tại sao đại diện whoring khi tôi đã rep mũ?! –

2

Nếu bạn không thích thay đổi mẫu và muốn tất cả các chức năng mảng để chỉ làm việc, nó có thể được dễ dàng hơn để chỉ đổi bộ sưu tập của bạn để một mảng:

Array.from(document.querySelectorAll('a')) 

Tất cả các chức năng mảng sẽ có sẵn , không cần phải cập nhật mã của bạn khi phiên bản mới của JavaScript được phát hành:

Array.from(document.querySelectorAll('a')).forEach(a => console.log(a)) 
Các vấn đề liên quan