2015-04-07 11 views
10

Giả sử tôi có một mảng đầy đủ các URL nguồn hình ảnh, như:Cách thêm danh sách hình ảnh vào tài liệu từ một mảng URL?

var imgs = ['http://lorempizza.com/380/240', 
      'http://dummyimage.com/250/ffffff/000000', 
      'http://lorempixel.com/g/400/200/', 
      'http://lorempixel.com/g/400/200/sports/']; 

Làm thế nào để lấy tất cả những hình ảnh và chèn chúng vào trang web của tôi tại một địa điểm cụ thể không? Nói ...

<div id="imageContainer"></div> 

Trả lời

26

Một cách để làm điều này là để lặp qua mảng lại hình ảnh, tạo ra một yếu tố img cho mỗi, thiết lập src của phần tử với nguồn hình ảnh hiện tại trong mảng của bạn, sau đó thêm nó vào bạn thùng đựng hàng. Điều này sẽ trông giống như:

var imgs = ['http://lorempizza.com/380/240', 
      'http://dummyimage.com/250/ffffff/000000', 
      'http://lorempixel.com/g/400/200/', 
      'http://lorempixel.com/g/400/200/sports/']; 
var container = document.getElementById('imageContainer'); 

for (var i = 0, j = imgs.length; i < j; i++) { 
    var img = document.createElement('img'); 
    img.src = imgs[i]; // img[i] refers to the current URL. 
    container.appendChild(img); 
} 

Tuy nhiên, đây không phải là đặc biệt hiệu quả:

  • Chúng tôi đang sử dụng một vòng lặp không cần thiết
  • Chúng tôi đang truy vấn các dom trên mỗi iteration
  • Chúng tôi đang giới thiệu các biến số ij toàn cầu
  • Chúng tôi không sử dụng các phương pháp Mảng tuyệt vời của JavaScript!

Thay vào đó, hãy sử dụng phương thức documentFragment và JavaScript forEach.

var imgs = ['http://lorempizza.com/380/240', 
      'http://dummyimage.com/250/ffffff/000000', 
      'http://lorempixel.com/g/400/200/', 
      'http://lorempixel.com/g/400/200/sports/']; 
var container = document.getElementById('imageContainer'); 
var docFrag = document.createDocumentFragment(); 

imgs.forEach(function(url, index, originalArray) { 
    var img = document.createElement('img'); 
    img.src = url; 
    docFrag.appendChild(img); 
}); 


container.appendChild(docFrag); 

Bằng cách này chúng tôi:

  • Chỉ nhấn DOM một lần
  • Không giới thiệu các biến toàn cục
  • Duy trì sạch hơn, dễ dàng hơn để đọc mã!

Sau đó chỉ cần để đảm bảo hình ảnh mới của bạn trông đẹp, thêm một chút CSS để trộn:

#imageContainer img { 
    width: 20%; 
    height: auto; 
} 

Bam! Dưới đây là fiddle

+1

Câu trả lời hay! +1 Tôi thực sự thích việc thực hiện DocumentFragment của bạn. Tôi muốn chỉ ra rằng 'Array.prototype.forEach()' không có sẵn trên IE8. Chỉ cần một cái gì đó để ghi nhớ nếu có ai đó buộc phải hỗ trợ trình duyệt cổ xưa :-) –

+3

@HowardRenollet Điểm tốt. Đôi khi tôi chỉ muốn giả vờ rằng IE8 và dưới đây không tồn tại. – monners

+0

Tôi thích giả vờ IE không tồn tại –

3

Vì một tiền thưởng khác được cung cấp (và tôi phải thừa nhận rằng tôi không hoàn toàn đồng ý với một số đối số trong câu trả lời khác, tuy nhiên, sử dụng các phương pháp hiện đại 'nặng') Tôi giả định rằng Neal có một câu trả lời rõ ràng hơn trong tâm trí, tôi sẽ có một shot vào nó.

Điều quan trọng nhất mà bạn nghĩ đến (cho rằng Q không đặt bất kỳ yêu cầu nào đối với đánh dấu/thuộc tính/hình ảnh của hình ảnh) là: Array.prototype. join ([separator = ',']) Phương thức kết hợp tất cả các phần tử của một mảng thành một chuỗi, được phân cách bằng bất kỳ thứ gì được chuyển thành arguments[0] (aka separator) bị ràng buộc thành chuỗi (nếu cần) hoặc mặc định chuỗi ',' (dấu phẩy) khi bỏ qua.
join ing là/thường là một cách rất phổ biến để nối chuỗi bởi vì nó được sử dụng để nhanh hơn trên các trình duyệt cũ hơn và/hoặc ít hơn 'phổ biến'/'được tối ưu hóa'. Trên các trình duyệt được tối ưu hóa phổ biến hơn và tốt hơn sau này, chuỗi nối bằng cách sử dụng + hiện có vẻ nhanh hơn (điều này thực sự có ý nghĩa).Tuy nhiên, khi viết mã được dự định là tương thích ngược, bạn nên chọn/sử dụng mẫu số chung chậm nhất (vì các quái vật tốc độ đã được tối ưu hóa). Xem câu trả lời (và các jsperfs được liên kết) với các câu hỏi thisthis về SO chẳng hạn.

Bây giờ chúng ta có một chuỗi, chúng tôi muốn sử dụng nó cùng với element.innerHTML đó là often faster hơn truy cập vào DOM để createElement hình ảnh và thêm nó vào DOM 's documentFragment hơn và hơn nữa trước khi chuyển sang những yếu tố trên đến yếu tố phụ huynh dự định trong cách bố trí ... Đừng làm cho tôi sai, documentFragment là một điều thú vị và hữu ích khi chúng ta cần phải làm rất nhiều DOMwork mà không nhận được bố trí vẽ lại theo cách trên mỗi hoạt động.

var imgs = ['http://lorempizza.com/380/240', 
 
      'http://dummyimage.com/250/ffffff/000000', 
 
      'http://lorempixel.com/g/400/200/', 
 
      'http://lorempixel.com/g/400/200/sports/']; 
 

 
document.getElementById('imageContainer') 
 
     .innerHTML = '<img src="' + imgs.join('" /><img src="') + '" />';
<div id="imageContainer"></div>

Có một vấn đề nhỏ với điều này: chúng ta có được một hình ảnh 'rỗng' nếu mảng img của chúng tôi là sản phẩm nào. Không có gì đơn giản là if không thể xử lý khó khăn .. Vì array.length là 1-based, chúng tôi thậm chí có thể có javascript ép buộc một chiều dài 0 đến false.
Ngoài ra chúng ta có thể thay đổi/sưng lên này để một nặc danh (giấu tên) biểu hiện ngay lập tức gọi function (IIFE):

(function(container, arr){ 
    if(arr.length) container.innerHTML = '<img src="' + arr.join('" /><img src="') + '" />'; 
}(document.getElementById('imageContainer') 
, imgs 
)); 

hoặc thậm chí chấp nhận lập luận cho dấu và dẫn mã HTML xung quanh của url:

(function(container, arr, leadStr, trailStr){ 
    if(arr.length) container.innerHTML = leadStr + arr.join(trailStr+leadStr) + trailStr; 
}(document.getElementById('imageContainer') 
, imgs 
, '<img src="' 
, '" />' 
)); 

Vv, v.v ...

Tùy thuộc vào thực tế (trình duyệt) thực hiện động cơ (và tối ưu hóa), 'tham gia' này (giống như tất cả các giải pháp khác) có lẽ vẫn còn ha loop sa trong nền ..

Kể từ forEach thường được xem như là một phương pháp hơi chậm (tất cả chúng tôi đồng ý có vẫn là một vòng lặp ở chế độ nền) mà có xu hướng (như mọi khi, tùy thuộc vào động cơ) để làm rất nhiều nhiều công việc hơn có thể được yêu cầu và nó sẽ gọiBack một hàm (chuyển xung quanh một số (3) đối số) cho mọi phần tử trong mảng, tôi sẽ trình bày một phiên bản vòng lặp tại đây, sử dụng chuỗi-nối (để đa dạng trong câu trả lời này và chuỗi kết nối 'hiện đại' 'nhanh hơn):

(function(container, arr, leadStr, trailStr){ 
    var i=0, L=arr.length, r=''; 
    if(L){ 
    for(; i<L ; ++i){ 
     r += leadStr + arr[i] + trailStr; 
    } 
    container.innerHTML = r; 
    } 
}(document.getElementById('imageContainer') 
, imgs 
, '<img src="' 
, '" />' 
)); 

Tất cả điều này sẽ hoạt động trên mọi trình duyệt sử dụng HTML4 và HT ML5. Cũng lưu ý rằng ở trên sẽ ghi đè nội dung của 'container' (không thêm vào nó). Tuy nhiên, theo mặc định, các phương thức DOM là bắt buộc đối với X (H) ML vì các phần tử không có thuộc tính innerHTML chính thức (mặc dù rất nhiều trình duyệt không quan tâm), nhưng chúng tôi vẫn có thể sử dụng một cách đơn giản (không -hidden) vòng lặp trong khi không bị rò rỉ bất cứ điều gì đến phạm vi toàn cầu, chỉ bằng cách thay đổi các chức năng trên:

(function(container, arr){ 
    var i = 0, L = arr.length, docFrag = document.createDocumentFragment(); 
    if(L){ 
    for(; i<L; ++i){ 
     docFrag.appendChild(document.createElement('img')).src = arr[i]; 
    } 
    container.appendChild(docFrag); 
    } 
}(document.getElementById('imageContainer') 
, imgs 
)); 

Lưu ý rằng ví dụ này thêm đến nội dung trong 'container'.

Ví dụ này nhằm phác thảo một vài điều: innerHTML, join, không cần phải giới thiệu các biến toàn cục/rò rỉ và quan trọng nhất: không có gì 'tiết kiệm' vòng lặp 'không cần thiết' (trên thực tế, tùy thuộc vào bạn đang thực hiện, vòng lặp hiển thị thực sự có thể nhanh hơn).

Tuy nhiên, người ta chỉ có thể đặt tên cho các hàm gói (IIFE trong các ví dụ trên) và chỉ cần gọi chúng, chuyển các đối số bắt buộc của bạn. Bằng cách đó bạn có thể thêm vào hoặc cập nhật/ghi đè lên khu vực hình ảnh của bạn một cách linh hoạt (như khi bạn tải các hình ảnh-url-mảng khác nhau trên ajax, v..v ..) nhiều lần.
Đối với ví dụ cuối cùng này tôi đã sử dụng cloneNode theo cách 'thông minh' (sẽ g-zip độc đáo) để giảm thiểu một số tra cứu (trong khi không để lại cho chúng tôi nút hình ảnh còn sót lại nhưng không có):

var imgs = ['http://lorempizza.com/380/240', 
 
      'http://dummyimage.com/250/ffffff/000000', 
 
      'http://lorempixel.com/g/400/200/', 
 
      'http://lorempixel.com/g/400/200/sports/']; 
 

 
function addPics(container, arr){ 
 
    var i = 0, L = arr.length, docFrag = document.createDocumentFragment(), img; 
 
    if(L){ 
 
    for(docFrag.appendChild(img=document.createElement('img')).src = arr[i] 
 
     ; ++i<L 
 
     ; docFrag.appendChild(img.cloneNode(false)).src = arr[i] 
 
     ); 
 
    container.appendChild(docFrag); 
 
    } 
 
} 
 

 
addPics(document.getElementById('imageContainer'), imgs);
<div id="imageContainer"></div>

Hy vọng rằng những lời giải thích giữa các ví dụ này là gì Neal đã có trong tâm trí ..
trong mọi trường hợp, bây giờ cần phải có đủ tài liệu tham khảo giữa điều này và câu trả lời khác (s) để đi xung quanh.

+0

hu .. nơi mà tiền thưởng khác đi (được cung cấp bởi @Neal) đã được mở trong 5 ngày khi tôi bắt đầu gõ câu trả lời này một vài giờ trước? Edit: không minding Tôi đã không nhận được nó, chỉ cần tự hỏi về 5 ngày ... – GitaarLAB

+0

Hmm, figured it out .. ([1] (http://meta.stackexchange.com/questions/107282/i-want -to-award-a-bounty-to-an-hiện-trả------------ng-24-giờ), [2] (http://meta.stackexchange.com/questions/137939/ xác định lại-the-reward-existing-answer-bounty-reason)). Ít nhất tôi không phải là người duy nhất không hiểu điều đó (.. 'một hoặc nhiều câu trả lời là gương mẫu và xứng đáng với một tiền thưởng bổ sung' không có nghĩa là 'mọi người đều có thể có khả năng kiếm tiền tiền thưởng) với một câu trả lời tuyệt vời ') .. NP, tôi vẫn đứng đằng sau bản chất của câu trả lời của tôi. – GitaarLAB

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