简体   繁体   中英

Dynamically loading files when user clicks button

I am loading files dynamically when a user clicks a button. There are two different source paths that are hard coded.

When the user clicks the button it should try to load the file using first path. If there is an error loading the file, it should try to load the file using the second path. If there is an error with the second path it should exit and quit trying and put up a message "File not found".

Here is my code:

var bt = $("bt");
var file = "http://www.website.com/files/filename.jpg;
var file2 = "http://www.website.com/files/file2.jpg;

bt.on('click', function(){
    $('#mb').attr('src', file);
    $('#mb').on('error', function(){
          $('#mb').attr('src', file2);
          $('#mb').on('error', function(){
               alert('no files could be found');
               return;
          });
    $('#loadHere').load();
    });
    $('#loadHere').load();
});

it works as long as one of the files are found. But, if neither are found it keeps looping because it cannot get out of the first on error function.

I really appreciate everyone's help.

Thank you.

I think the easiest way might be an array of image src and good ol recursion when the image fails.

Something like this:

var bt = $("#bt");
var files = [
    "http://www.website.com/files/filename.jpg",
    "http://www.website.com/files/file2.jpg"
]

bt.on('click', function loadFile() {
    var file = files.shift();

    if (file) {
        $('#mb').attr('src', file);

        // Avoid rebinding onerror with '.one()' (as suggested by @rbyte)
        $('#mb').one('error', function () {
           loadFile(); 
        });
    } else {
        // Throw error  
        $('body').addClass('no-file');
    }
});

Here's a fiddle which demonstrates when both links are broken:

http://jsfiddle.net/x6pz4txo/

And here are two fiddles which demonstrate when both (or just one) link works:

http://jsfiddle.net/5sf22hka/ (Both links would work - but just loads the first)

http://jsfiddle.net/5sf22hka/1/ (First link broken, second works)

$('#mb').attr('src', file2);

that line makes your infinite loop with onerror event cause you use the same #mb element. You need to different elements for that, but it's better to create new Image for image load waiting

Try to use

var myImage = new Image,
    myImage2 = new Image;

var count = 0

myImage.src = file
myImage2.src = file2

myImage.onload = function(){}
myImage.onerror = function(){}

myImage2.onload = function(){}
myImage2.onerror = function(){}

not sure what you want to do after files loaded or not, but you may just rewrite your code with Image elements and put myImage2 inside myImage.onload if you want

You should unbind the error instead of the return.

Try this..

var bt = $("bt");
var file = "http://www.website.com/files/filename.jpg;
var file2 = "http://www.website.com/files/file2.jpg;

bt.on('click', function(){
    $('#mb').attr('src', file);
    $('#mb').on('error', function(){
          $('#mb').attr('src', file2);
          $('#mb').on('error', function(){
               alert('no files could be found');
               $('#mb').off('error'); 
          });
    $('#loadHere').load();
    });
    $('#loadHere').load();
});

You need to unbind first, do it before the second on error event is attached.

var bt = $("bt");
var file = "http://www.website.com/files/filename.jpg;
var file2 = "http://www.website.com/files/file2.jpg;

bt.on('click', function(){
    $('#mb').attr('src', file);
    $('#mb').on('error', function(){
          $('#mb').off('error'); 
          $('#mb').attr('src', file2);
          $('#mb').on('error', function(){
               alert('no files could be found');

          });
    $('#loadHere').load();
    });
    $('#loadHere').load();
});

You could use the concept of stack to handle this situation.

var bt = $("bt");
var images = [
        "http://www.website.com/files/filename.jpg",
        "http://www.website.com/files/file2.jpg"
];

bt.on('click', function(){
    $('#mb').attr('src', images.shift());
    $('#mb').on('error', function(){
        if (images.length) {
            $('#mb').attr('src', images.shift());
        } else {
            alert('no files could be found');
            return;
        }
        $('#loadHere').load();
    });
    $('#loadHere').load();
});

You keep an array with all the images you want to try to load. Once the button to load the images is clicked, you keep trying to load all the images in the array, until either one of those images exists or there's no more images to load.

This way you don't have to bind an error event more than once or call recursive functions.

Hope it helps.

This is what I used to fix the issue:

var bt = $("bt");
var images = [
        "http://www.website.com/files/filename.jpg",
        "http://www.website.com/files/file2.jpg"
];

bt.on('click', function(){
    $('#mb').attr('src', images.shift());
    $('#mb').on('error', function(){
        if (images.length) {
            $('#mb').attr('src', images.shift());
        } else {
            alert('no files could be found');
            return;
        }
        $('#loadHere').load();
    });
    $('#loadHere').load();
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM