Html array images with

How to add a list of images to the document from an array of URLs?

One way to do this is to loop over your array of images, create an img element for each, set the element’s src to the current image source in your array, then append it to your container. This would look like:

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

However, this isn’t particularly efficient:

  • We’re using an unnecessary loop
  • We’re querying the dom on every iteration
  • We’re introducing the global i and j variables
  • We’re not using JavaScript’s wonderful Array methods!

Instead, let’s use a documentFragment and JavaScript’s forEach Array method.

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); 
  • Only hitting the DOM once
  • Not introducing global variables
  • Maintaining cleaner, easier to read code!

Then just to make sure your new images look nice, add a bit of CSS to the mix:

Good Answer! +1 I really like your DocumentFragment implementation. I would like to point out that Array.prototype.forEach() is not available on IE8. Just something to keep in mind if anyone is forced to support that archaic browser 🙂

Since another bounty is offered (and I must admit that I don’t fully agree with some of the arguments in the other answer, which does however use fancy and even arguably somewhat ‘heavy’ modern methods), I am assuming that Neal has a more obvious answer in mind, I’m going to have a shot at it.

The most straight-forward thing that comes to mind (given that the Q doesn’t set any requirements to the image’s markup/attributes/etc) is: the Array.prototype.join([separator = ‘,’]) method which joins all elements of an array into a string, separated by anything that is passed as arguments[0] (aka separator ) which is coerced to string (if needed) or defaults to the string ‘ , ‘ (comma) when omitted.
join ing is/was often a very popular way to concatenate strings because it used to be faster on older and/or less ‘popular’/’optimized’ browsers. On the later more popular and better optimized browsers, string-concatenation using + currently appears to be faster (which actually makes sense). However, when writing code that is intended to be backwards compatible it often makes sense to choose/use the least slow common denominator (since the speed-monsters are already optimized). See answers (and linked jsperfs) to this and this question on SO for example.

Now that we have a string, we’d use it together with element.innerHTML which is often faster than accessing the DOM to createElement image and add it to the documentFragment ‘s DOM over and over again before moving these elements over to the intended parent element in the layout. Don’t get me wrong, documentFragment is a cool and useful thing when we need to do a lot of DOMwork without getting layout-redraw in the way on each and every operation.

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 = '';

There is one tiny problem with this: we get one ’empty’ image if our img array is empty. Nothing that a simple if can’t handle tough.. Since array.length is 1-based we can even have javascript coerce a length of 0 to false .
In addition we could change/bloat this to an anonymous (unnamed) immediately invoked function expression (IIFE):

(function(container, arr)< if(arr.length) container.innerHTML = ''; >( document.getElementById('imageContainer') , imgs )); 

or even accept arguments for the trailing and leading HTML code surrounding the url’s:

(function(container, arr, leadStr, trailStr)< if(arr.length) container.innerHTML = leadStr + arr.join(trailStr+leadStr) + trailStr; >( document.getElementById('imageContainer') , imgs , '' )); 

Depending on the actual (browser’s) engine implementation (and optimizations), this ‘join’ (like all other solutions) most probably still has a loop in the background..

Читайте также:  Css hide text in padding

Since forEach is commonly seen as a somewhat slow method (we all agree there is still a loop in the background) which tends (as always, depending on engine) to do a lot more work than might be required and it will callBack a function (passing around some (3) arguments) for every element in the array, I’ll present a loop-version here, using string-concatenation (for diversity in this answer and ‘modern’ ‘faster’ string-concatenation):

(function(container, arr, leadStr, trailStr) < var i=0, L=arr.length, r=''; if(L)< for(; icontainer.innerHTML = r; > >( document.getElementById('imageContainer') , imgs , '' )); 

All of this should work on any browser using HTML4 and HTML5. Also note that the above will overwrite the contents of ‘container’ (not add to it).

The DOM-methods however are technically required for X(H)ML as the elements don’t have an innerHTML property officially (although a lot of browsers don’t mind), but we can still use a simple (non-hidden) loop while not leaking anything to the global scope, just by modifying the above function:

(function(container, arr) < var i = 0, L = arr.length, docFrag = document.createDocumentFragment(); if(L)< for(; icontainer.appendChild(docFrag); > >( document.getElementById('imageContainer') , imgs )); 

Note that this example adds to the content in ‘container’.

These examples are intended to outline a couple of things: innerHTML , join , there is no need to introduce global/leaking variables and most importantly: nothing ‘saves’ an ‘unnecessary’ loop (in fact, depending on what you are doing, the visible loop might actually be faster).

However, one might just name the wrapping functions (IIFE in above examples) and just call them, passing your required arguments. That way you can add to or update/overwrite your image-area dynamically (like when you’d load different image-url-array’s over ajax etc..) more than once.
For this final example I’ve used cloneNode in a ‘clever’ way (that will g-zip nicely) in order to minimize some lookups (whilst not leaving us with a leftover, but unplaced image-node):

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> addPics( document.getElementById('imageContainer'), imgs );

Hopefully the explanations between these examples are what Neal had in mind..
In any case, there should now be enough reference between this and other answer(s) to go around.

Читайте также:  Тег А, атрибут target

Источник

Showing an image from an array of images — Javascript

I have a large image which is shown on my homepage, and when the user clicks the «next_img» button the large image on the homepage should change to the next image in the array. However, the next arrow when clicked does nothing, and the main image on the homepage does not change. I need to do this in javascript. In the HTML:

var imgArray = new Array(); imgArray[0] = new Image(); imgArray[0].src = 'images/img/Splash_image1.jpg'; imgArray[1] = new Image(); imgArray[1].src = 'images/img/Splash_image2.jpg'; imgArray[2] = new Image(); imgArray[2].src = 'images/img/Splash_image3.jpg'; imgArray[3] = new Image(); imgArray[3].src = 'images/img/Splash_image4.jpg'; imgArray[4] = new Image(); imgArray[4].src = 'images/img/Splash_image5.jpg'; imgArray[5] = new Image(); imgArray[5].src = 'images/img/Splash_image6.jpg'; /*------------------------------------*/ function nextImage(element) < var img = document.getElementById(element); for(var i = 0;ielse var j = i + 1; document.getElementById(element).src = imgArray[j].src; break; > > > 

6 Answers 6

Just as Diodeus said, you’re comparing an Image to a HTMLDomObject . Instead compare their .src attribute:

var imgArray = new Array(); imgArray[0] = new Image(); imgArray[0].src = 'images/img/Splash_image1.jpg'; imgArray[1] = new Image(); imgArray[1].src = 'images/img/Splash_image2.jpg'; /* . more images . */ imgArray[5] = new Image(); imgArray[5].src = 'images/img/Splash_image6.jpg'; /*------------------------------------*/ function nextImage(element) < var img = document.getElementById(element); for(var i = 0; i < imgArray.length;i++) < if(imgArray[i].src == img.src) // document.getElementById(element).src = imgArray[i+1].src; break; > > > 

@Nuktu: You’re welcome. Please keep in mind: even if imgArray[0] = Image() and img = document.getElementById(#myimage) are treated as HTMLImageElement , they won’t be the same even if they are equal (same attributes) as they’re different object instances.

Here’s a somewhat cleaner way of implementing this. This makes the following changes:

  1. The code is DRYed up a bit to remove redundant and repeated code and strings.
  2. The code is made more generic/reusable.
  3. We make the cache into an object so it has a self-contained interface and there are fewer globals.
  4. We compare .src attributes instead of DOM elements to make it work properly.
function imageCache(base, firstNum, lastNum) < this.cache = []; var img; for (var i = firstNum; i > imageCache.prototype.nextImage(id) < var element = document.getElementById(id); var targetSrc = element.src; var cache = this.cache; for (var i = 0; i < cache.length; i++) < if (cache[i].src) === targetSrc) < i++; if (i >= cache.length) < i = 0; >element.src = cache[i].src; return; > > > // sample usage var myCache = new imageCache('images/img/Splash_image', 1, 6); myCache.nextImage("foo"); 

Some advantages of this more object oriented and DRYed approach:

  1. You can add more images by just creating the images in the numeric sequences and changing one numeric value in the constructor rather than copying lots more lines of array declarations.
  2. You can use this more than one place in your app by just creating more than one imageCache object.
  3. You can change the base URL by changing one string rather than N strings.
  4. The code size is smaller (because of the removal of repeated code).
  5. The cache object could easily be extended to offer more capabilities such as first, last, skip, etc.
  6. You could add centralize error handling in one place so if one image doesn’t exist and doesn’t load successfully, it’s automatically removed from the cache.
  7. You can reuse this in other web pages you develop by only change the arguments to the constructor and not actually changing the implementation code.
Читайте также:  Сумма элементов числа java

P.S. If you don’t know what DRY stands for, it’s «Don’t Repeat Yourself» and basically means that you should never have many copies of similar looking code. Anytime you have that, it should be reduced somehow to a loop or function or something that removes the need for lots of similarly looking copies of code. The end result will be smaller, usually easier to maintain and often more reusable.

Источник

Display images from array in HTML

I need create a load-on-demand image gallery, and I start from a JSON that defines all the images in the gallery in a format like:

function getArticleImage() < var image = new Image; image.className = 'banner-img'; image.src = 'aws.netclime.net/Images/1.png'; image.setAttribute("height", "200px"); image.setAttribute("width", "200px"); image.onload = function() < image.classList.remove(); >; return image; > 

This is quite unclear. How should the result look? What does the desired HTML structure look like? Is the text the title of the link, an image description, the value for the alt -attribute? Have you tried anything already?

3 Answers 3

This should get you started.

var GALLERY_JSON = < "size" : "200x200", "images": [ < "src" : "http://aws.netclime.net/Images/1.png", "text" : "This is an image1", "link" : "http://cnn.com" >, < "src" : "http://aws.netclime.net/Images/2.png", "text" : "This is an image2", "link" : "http://google.com" >, < "src" : "http://aws.netclime.net/Images/3.png", "text" : "This is an imageN", "link" : "http://yahoo.com" >] >; function getArticleImage(data) < var image = new Image; image.className = 'banner-img'; image.src = data.src; image.setAttribute("height", data.height); image.setAttribute("width", data.width); image.onload = function() < image.classList.remove(); >; return image; > GALLERY_JSON.images.forEach(function(data)< data.width = GALLERY_JSON.size.match(/^4+/); data.height = GALLERY_JSON.size.match(/1+$/); document.body.appendChild( getArticleImage(data) ); >)

You should loop over your array, create a link element containing an image and append it to the DOM. Here are two links providing documentation and examples :

I would recommend templating.

IMHO it’s a much more powerful solution, you can easily change the template to embed your data in any third party gallery/carousel you want and it’s more legible.

Here is an example with the template embeded in the HTML (you could have it out there for better organization)

  • MustacheJS for the templating
  • JQuery just for getting divs by id (you could easily remove that JQuery dependency with DOM if you don’t need JQuery anywhere else)

The hacky .match() part is to extract the width and height, if you could provide those 2 values as variables at GALLERY_JSON you wouldn’t need that.

var GALLERY_JSON = < "size" : "200x200", "images": [ < "src" : "http://aws.netclime.net/Images/1.png", "text" : "This is an image1", "link" : "http://cnn.com" >, < "src" : "http://aws.netclime.net/Images/2.png", "text" : "This is an image2", "link" : "http://google.com" >, < "src" : "http://aws.netclime.net/Images/3.png", "text" : "This is an imageN", "link" : "http://yahoo.com" >] >; var width = GALLERY_JSON.size.match(/^5+/); var height = GALLERY_JSON.size.match(/5+$/); GALLERY_JSON.width = width; GALLERY_JSON.height = height; var template = $('#template').html(); var gallery = Mustache.render(template, GALLERY_JSON); $('#gallery').html(gallery);

Источник

Оцените статью