Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 10 of 10
  1. #1
    Regular Coder
    Join Date
    Jan 2013
    Location
    Sunnyvale, CA
    Posts
    115
    Thanks
    8
    Thanked 7 Times in 7 Posts

    background-image fails to load when remote server is down

    NOTE: After posting I realized that, although this is part of an AJAX-heavy distributed web app, the issue itself is not an AJAX issue. Apologies for misplacing it. Please respond it you can offer any guidance.

    Site loads links to pages that exist on various remote servers.

    Every remote-page-link is represented by an icon on the site, and the relevant icon is provided by the remote server at runtime. Consequently, if the remote server's webmaster wishes to replace the icon then the new icon will show up henceforth.

    The site presents all dynamically-loaded icons in span elements, as background images, and offers active images on hover via CSS:hover pseudo-class, and remote page access is handled by a click event.

    When a server is down a blank space is evident, and I want to remove it from the display.

    Programmatically I might iterate through the span objects and search for the ones that are missing the images, but the problem that I have is that the references to the remote images are in the tag, only they fail to load (i.e., background-image: url("xxx/xxx.com/xxxx.png") is still in the tag, so searching for its absence will not work. I need to know if it is actually being painted on the user's screen).

    Any thoughts? Is there an best-practice or standard for dynamically setting missing images to "display: none;" without pinging each server with every page load to see if it is active?
    Last edited by sbhmf; 03-27-2014 at 07:31 PM. Reason: Added note atop description.

  • #2
    Supreme Master coder! glenngv's Avatar
    Join Date
    Jun 2002
    Location
    Philippines
    Posts
    11,074
    Thanks
    0
    Thanked 256 Times in 252 Posts
    As you iterate through the span elements and get the background-image, try to load each image via Image() and have the onerror callback.

    Code:
    //...
    var img = new Image();
    img.onerror = function() {
        //the image failed to load, do what you want here
    }
    img.src = image url taken from background-image;
    Glenn
    ____________________________________

    My Blog
    Tower of Hanoi Android app (FREE!)
    Tower of Hanoi Leaderboard
    Samegame Facebook App
    vBulletin Plugins
    ____________________________________

  • #3
    Supreme Master coder! glenngv's Avatar
    Join Date
    Jun 2002
    Location
    Philippines
    Posts
    11,074
    Thanks
    0
    Thanked 256 Times in 252 Posts
    I think you need to use an array for the img because when it iterates to the next one, the previous img will get overwritten while it is still being fetched.
    Code:
    var img = [];
    //...for loop here 
    {
        var img[i] = new Image();
        img[i].onerror = function() {
            //the image failed to load, do what you want here
        }
        img[i].src = image url taken from background-image;
    }
    Change for loop index from "i" to whatever you're using.
    Glenn
    ____________________________________

    My Blog
    Tower of Hanoi Android app (FREE!)
    Tower of Hanoi Leaderboard
    Samegame Facebook App
    vBulletin Plugins
    ____________________________________

  • #4
    Regular Coder
    Join Date
    Jan 2013
    Location
    Sunnyvale, CA
    Posts
    115
    Thanks
    8
    Thanked 7 Times in 7 Posts
    Decent approach if it were an HTML img tag. The HTML DOM exposes accessors to track and manage state and events within the DOM, but not CSS.

    CSS is independently parsed by the browser, and I do not know of any means by which the successful loading [and painting] of an image via CSS' background-image property may be confirmed. I am VERY interested in a hack that will provide such validation, so please share.

    While on the topic, the DOM image element has a property called 'complete', that conveys the image state, and is possibly a more popular method to use in a loop such as the one that you provided.

  • #5
    Supreme Master coder! glenngv's Avatar
    Join Date
    Jun 2002
    Location
    Philippines
    Posts
    11,074
    Thanks
    0
    Thanked 256 Times in 252 Posts
    Did you try it? What it does is grab the image path (without the "url()" of course) from the background-image and tries to load it via Image() like you would load it as a regular img tag and wait for it to fail.
    Glenn
    ____________________________________

    My Blog
    Tower of Hanoi Android app (FREE!)
    Tower of Hanoi Leaderboard
    Samegame Facebook App
    vBulletin Plugins
    ____________________________________

  • #6
    Regular Coder
    Join Date
    Jan 2013
    Location
    Sunnyvale, CA
    Posts
    115
    Thanks
    8
    Thanked 7 Times in 7 Posts
    ...so in this post I'm thinking out loud...:

    If I understand you correctly, you are suggesting that I iterate through the images and strip out the URLs from their CSS values and try loading them dynamically to see if they load.

    My Expectations: I'm sufficiently confident that the image will be loaded if the remote server is 'live', and am only concerned with the remote servers that may be unexpectedly down (unlikely as it is though eventually these things do happen, and should be handled gracefully). So I ask myself, why should I try to load the images from the server to confirm that they are loading when it's sufficient to use an AJAX call to simply check if the remote servers are 'live', which uses much less bandwidth and minimal server resources (They can support SOAP functions that return true if live, and will time out if they don't answer)?

    My response: I did not try your suggestion, though I am confident that it will work. Following the spirit of your approach though, I should probably refrain from referencing the remote server images in my CSS file, and instead load all remote images into JavaScript image objects that will remain in memory throughout the session. Then I should reference the images in those objects from dynamically-embedded page-level CSS (must be page level because file already loaded before JavaScript, and inline style will not support CSS pseudo-classes). This technique should allow me to gracefully handle images that do not load, are loaded once for the duration of the session, and will ensure that the images are not coming from the browser cache (not quite sure about this last one...).

    Any idea what the syntax would be if I want to reference the CSS background-image from a JS memory-resident object? Certainly cannot use url() syntax. Not even sure that it is possible.. I'll need to look it up...

    Any thoughts?

    Thx a bunch!

    EDIT: Just looked it up: http://stackoverflow.com/questions/9...ing-javascript. Not sure if this will work as I intend for it. I want the CSS to reference the image object in memory, and not its source. Telling it to go to the source defeats some of the purpose if it goes ahead and reloads the image from the remote server a second time.
    Last edited by sbhmf; 03-28-2014 at 01:58 AM.

  • #7
    Supreme Master coder! glenngv's Avatar
    Join Date
    Jun 2002
    Location
    Philippines
    Posts
    11,074
    Thanks
    0
    Thanked 256 Times in 252 Posts
    The remote server may be up but they might have moved or renamed the images so simply checking if it is live is not enough. And when the images fetched from the CSS background-images were loaded successfully, when you try to load them again via Image(), the browser will load them from cache so there is little overhead when you try to reload them.
    Glenn
    ____________________________________

    My Blog
    Tower of Hanoi Android app (FREE!)
    Tower of Hanoi Leaderboard
    Samegame Facebook App
    vBulletin Plugins
    ____________________________________

  • #8
    Regular Coder
    Join Date
    Jan 2013
    Location
    Sunnyvale, CA
    Posts
    115
    Thanks
    8
    Thanked 7 Times in 7 Posts
    Yeah, that's what I figured, since loading from an Image object solves all problems.

    Thanks for talking it through with me.

  • #9
    Regular Coder
    Join Date
    Jan 2013
    Location
    Sunnyvale, CA
    Posts
    115
    Thanks
    8
    Thanked 7 Times in 7 Posts
    Turns out that it's more trouble than it's worth. Perhaps one day, with money to burn...

    Fact is that images load fastest during the browser's initial page load, since it's multi-threaded. Messing around with image manipulation after the page load is costly and arguably not worth the trouble. So how do I handle remote servers that are down? I have some options if I really care to, yet the fact is that these days there exists so much redundancy that a downed server will have a failover take over within a split second.

    If I'm really pressed for a solution then I can probably just ping the remote servers at page load to make sure that they are indeed 'live', and remove their links dynamically if they are unavailable.

    I sometimes need to remind myself that even Defensive Programming has its limits.

    Cheers

  • #10
    Supreme Master coder! glenngv's Avatar
    Join Date
    Jun 2002
    Location
    Philippines
    Posts
    11,074
    Thanks
    0
    Thanked 256 Times in 252 Posts
    Then I suggest to use <img> tags instead of using them as background.
    Code:
    <img src="http://externalsite.com/images/whatever.png" width="10" height="10" alt="" onerror="this.style.display='none';" />
    Glenn
    ____________________________________

    My Blog
    Tower of Hanoi Android app (FREE!)
    Tower of Hanoi Leaderboard
    Samegame Facebook App
    vBulletin Plugins
    ____________________________________

  • Users who have thanked glenngv for this post:

    sbhmf (04-01-2014)


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •