shakel
shakel

Reputation: 217

Asynchronous image loading

I'm creating a Hangman game for a project. I have most of the functionality I need, however I am having one issue. When the last incorrect guess is made, it displays the alert box telling you you've lost, before loading the image. I want the image to load first and then the alert box.

I realize that the issue is with the way the DOM loads elements and that I should create a callback function in jQuery.

This is the line in my code that changes the image, and it works fine until it gets to the last one.

document.getElementById("gallows").src = displayGallows[incorrectGuesses - 1];

I have tried using a Jquery function to get this working but my knowledge of jQuery is pretty much non-existent.

var img = $("gallows");
    img.load(function() {
        alert("Unlucky, you lost. Better luck next time!");
    });
    img.src = displayGallows[incorrectGuesses - 1];

I have compared this to many posts I have found online and to my untrained eye, it looks OK. When I was troubleshooting I did realize that the img.src was assigned the correct value but the image didn't appear on my page or didn't fire the alert box.

This led me to believe that it may be an issue with linking to the jquery.js file. I have an HTML page that references the jQuery file in it's head tag.

<head>
    <title>Hangman</title>
    <link rel="stylesheet" href="base.css"/>
    <script src="jquery.js"></script>
    <script src="hangman.js"></script>
    <script src="home.js"></script>
</head>

The file I am writing my JavaScript and jQuery from is the hangman.js file.

Do I also need to refer to the jquery.js file from the hangman.js file? While reading up on this I found that I may have to do this, so I've tried this:

///<reference path="jquery.js" />

and this

var jq = document.createElement('script');
jq.src = 'jquery.js';
document.getElementsByTagName('head')[0].appendChild(jq);

but to no avail, though I don't really understand the second one, as I found these examples on the internet.

Note that in my home.js file I have simple a simple jQuery function to em-bold the text on a button when you mouseover it and this works OK.

If anyone could help me out or point me in the right direction that would be great.

Upvotes: 4

Views: 2430

Answers (3)

T.J. Crowder
T.J. Crowder

Reputation: 1074108

Your best bet here is probably not to use alert at all; instead, use modern techniques like an absolutely-positioned, nicely-styled div to show your message. Showing that won't get in the way of the browser showing the image once it arrives, whereas alert basically brings the browser to a screeching halt until the user clicks the alert away.

But if you want to use alert:

Your concept of waiting for the load event from the image is fine, but you may want to yield back to the browser ever-so-briefly afterward to give it a chance to display the image.

Not using jQuery, as you don't appear to be using it otherwise:

var img = document.getElementById("gallows");
img.onload = img.onerror = function() {
    setTimeout(function() {
        alert(/*...*/);
    }, 30); // 30ms = virtually imperceptible to humans
};
img.src = displayGallows[incorrectGuesses - 1];

That waits for the load or error event from the image, then yields back to the browser for 30ms before showing the alert.

But if you pre-cache the images, you can make the load event fire almost instantaneously. Most browsers will download an image even if it's not being shown, so if you add

<img src="/path/to/incorrect/guess.png" style="display: none">

...to your page for each of the incorrect guess images, then when you assign the same URL to your #gallows image, since the browser has it in cache, it will load almost instantly. Here's an example using your gravatar and a 30ms delay after load: http://jsbin.com/fazera/1

Upvotes: 1

jyrkim
jyrkim

Reputation: 2869

please make sure that you have your jQuery code that's within the HEAD tag, inside:

$( document ).ready(function() { ...your jQuery here... });

More info: Using jQuery, $( document ).ready()

Your question: "Do I also need to refer to the jquery.js file from the hangman.js file?"

No, but place <script src="hangman.js"></script> tag in the header after referring to your jQuery file:

<head>
    <script src="jquery_version_that_you_are_using.js"></script>
    <script src="hangman.js"></script>
    <script>
    $( document ).ready(function() {
       //Your jQuery code here
    });

    </script>
</head> 

Upvotes: 0

PurkkaKoodari
PurkkaKoodari

Reputation: 6809

Firstly, to get an object by ID in jQuery, you have to use #.

var img = $("#gallows");

You can not use src or other "vanilla" properties directly on a jQuery object. You can, however do any of these:

  • Get the actual element from the jQuery object.

    var img = $("#gallows");
    img.load(function() { ... } 
    img[0].src = "image.jpg"; // First element in jQuery object 
    
  • Use the jQuery method attr (recommended).

    var img = $("#gallows");
    img.load(function() { ... } 
    img.attr("src", "image.jpg");
    
  • Get the element just like you do now.

    var img = document.getElementById("gallows");
    img.onload = function() { ... } 
    img.src = "image.jpg";
    

Upvotes: 0

Related Questions