abenci
abenci

Reputation: 8651

Dynamic image tag

How do I create an tag that look for the image name in 10 different folders and if not found outputs a placeholder image using Javascript?

Thanks.

Upvotes: 0

Views: 1007

Answers (7)

Martin Jespersen
Martin Jespersen

Reputation: 26183

Since you are asking about how to do it with a tag i'll show a solution, although i'd never do it myself:

<script>
urlsToTry = ['http://url2.com','http://url3.com','http://you.get.the.picture.com','http://www.google.com/images/logos/ps_logo2.png'];
</script>
<img src="http://url1.com" style="display: none;" onload="this.style.display='block';" onerror="if(urlsToTry.length) { this.src = urlsToTry.shift(); } else { alert('none of the urls worked!'); }">

You can see an example of it here: http://jsfiddle.net/LLQLH/1/

One of the downsides to this approach is that it tries to load the picture serially which can cause quite a wait if they all fail. The parallel approach using proper js would be the way to go imo:

<script>
var loadQueue={};
var urlsToTry = ['http://url1.com','http://url2.com','http://url3.com','http://you.get.the.picture.com'];

function showTag(url) {
    var tag = document.getElementById('myimage');
    if(url) tag.src = url; 
    tag.style.display='inline-block';       
}

function onLoadEventHandler(url) {
    return function() {
        delete loadQueue[url];
        for(var i = 0, img; img = loadQueue[i]; i++) {
            img.onload = null;
        }
        loadQueue = null;
        showTag(this.src);
    }
}

function onErrorEventHandler(url) { 
    return function() {
        delete loadQueue[url];
        for(var i in loadQueue) return;
        showTag(); //we will only get here if loadQueue is empty
    }
}

for(var i = 0, url; url = urlsToTry[i]; i++) {
    loadQueue[url] = new Image();
    loadQueue[url].onload = onLoadEventHandler;
    loadQueue[url].onerror = onErrorEventHandler(url);
    loadQueue[url].src = url;
}
</script>
<img id="myimage" src="http://www.google.com/images/logos/ps_logo2.png" style="display: none;">

You can see it working here: http://jsfiddle.net/DJ2SH/

Upvotes: 0

egze
egze

Reputation: 3236

I'd solve it with Ajax, try to load each image, if you get a 200 that means the image exists, if 404 try next image.

var images = ['/images/1.jpg', '/images/2.jpg', '/images/3.jpg'];
var imageExists = false;
for(var i = 0; i < images.length; i++){
  if(!imageExists){
    $.ajax({
      url: images[i],
      async: false,
      success: function(){
        // use images[i] as your image
        imageExists = true;
      }
    });
  }
}
if(!imageExists) {
  // use default image
}

Upvotes: 0

Shadow Wizard
Shadow Wizard

Reputation: 66389

I would go with such script:

<script type="text/javascript">
var arrPossibleImageFolders = ["folder1", "folder2", "folder3"];
var strDefaultImage = "nopicture.gif";
function TryDifferentFolder(oImage) {
    var folderIndex = parseInt(oImage.getAttribute("folder_index"), 10);
    if (isNaN(folderIndex))
        folderIndex = 0;
    folderIndex++;
    if (folderIndex >= arrPossibleImageFolders.length) {
        oImage.src = strDefaultImage;
        return;
    }

    var lastSlashIndex = oImage.src.lastIndexOf("/");
    var strNewSource = arrPossibleImageFolders[folderIndex] + "/" + oImage.src.substr(lastSlashIndex);
    oImage.src = strNewSource;

    oImage.setAttribute("folder_index", folderIndex + "");
}
</script>

Then have such image tag to trigger the code:

<img src="folder1/mypicture.gif" onerror="TryDifferentFolder(this);" />

This will search for "mypicture.gif" in folder1 first, then if not found (onerror triggered) will try in folder2 etc, finally loading the default picture.

Upvotes: 2

Sounds like you may need to use a bunch of onerror handlers. Try to load some image, catch possible error till you run out of candidates. Load placeholder as the last image.

Upvotes: 0

epascarello
epascarello

Reputation: 207501

var img = new Image();
img.onload = function(){ alert("I am loaded"); };
img.onerror = function(){ alert("I am not loaded"); };
img.src = "/foo/bar.gif";

If you get onerror, try setting the source again to the next image in your list.

Upvotes: 2

crimson_penguin
crimson_penguin

Reputation: 2778

Really, you should do something like this on the server side, where the files actually are; make a script that looks for the image and sends what it finds.

(Edited to remove my original JS solution, since it was bad, and others have suggested better ones.)

Upvotes: 1

Patrik Fiala
Patrik Fiala

Reputation: 56

lol, this cant be done only with some tag, you should propably make js(jquery/ajax) function to search for that file and then update href attribute of img... or you should explain your intends a little more

Upvotes: -1

Related Questions