1

I'm trying out github and thpught i would put a small test project up there. Since it is public i ran i through JSHint but i get an error that i can't shake:

Line 21 preloadImages();

'preloadImages' is not defined.

This is the code:

$(function() {

    var allImagesLoaded = false, imagesLength = 0, counter = 0, imageArray = [], loadedImages = [], loadedImagesCounter = 0;

    /*--------------------------------
    Add your images to the array
    and your good to go
    --------------------------------*/
    imageArray = ["img/1.jpg", "img/2.jpg", "img/3.jpg", "img/4.jpg"];
    imagesLength = imageArray.length;

    if(imagesLength === 0) {
        $('#container').html('<p><strong>You need to put some images in your array</strong></p>');
    }
    else {

        preloadImages();
    }

    function preloadImages() {
        var tempImage = $("<img />").attr("src", imageArray[loadedImagesCounter]);

        tempImage.load(function(){

            loadedImages.push(this);
            loadedImagesCounter++;
            if(loadedImagesCounter == imagesLength) {
                imageArray = loadedImages;
                initEverything();
            }
            else {
                if(!allImagesLoaded)
                {
                    preloadImages();
                }
            }       
        });
    }

    function initEverything() {


        allImagesLoaded = true;
        $('#preloadingImages').hide();

        // Deactivate the context menu that appears on right click
        $(document).bind("contextmenu", function(e) {
            return false;
        });

        var theSource = $(imageArray[0]).attr('src');

        var theImage = $('<img />');
        $(theImage)
            .attr('src', theSource)
            .attr('width', imageArray[0].width)
            .attr('height', imageArray[0].height)
            .attr('alt', 'demobild 1')
            .attr('id', 'pageImage');

        $('#container').append(theImage)

        $("#pageImage").mousedown(function(e) {
            if (allImagesLoaded) {
                switch (e.which) {
                    case 1:
                        stepForward();
                        break;
                    case 2:
                        // center button on the mouse
                        break;
                    case 3:
                        stepBackward();
                        break;
                    default:
                        // Nada
                }
            }
        });
        $(document).keydown(function(e) {
            e.preventDefault();
            if (allImagesLoaded) {
                switch (e.keyCode) {
                    case 37: // Left
                        stepBackward();
                        break;
                    case 38: // Up
                        stepBackward();
                        break;
                    case 39: // Right
                        stepForward();
                        break;
                    case 40: // Down
                        stepForward();
                        break;
                    default:
                        // Nada
                }
            }
        });

    }

    function stepForward() {

        if (counter === imagesLength-1) {
            counter = 0;
        } else {
            counter++;
        }
        $("#pageImage").attr("src", $(loadedImages[counter]).attr('src'));
        $("#pageImage").attr("alt", "demobild " + counter);
    }

    function stepBackward() {

        if (counter === 0) {
            counter = imagesLength-1;
        } else {
            counter--;
        }
        var sourcePath = $(imageArray[counter]).attr('src');
        $("#pageImage").attr("src", sourcePath);
        $("#pageImage").attr("alt", "demobild " + counter);
    }

});

Where is best practise to put functions? At the top?

Here is my project https://github.com/Benjaminsson/Image-expo

1
  • 1
    @Daniel: No. It's a regular function. Commented Sep 19, 2011 at 11:41

3 Answers 3

1

JavaScript hoists function declarations to the beginning of the scope. So the function is available in the whole scope (the function passed to $()) no matter where it is defined. JSLint might not detect this properly and think the function in undefined at the point you are calling it.

Sign up to request clarification or add additional context in comments.

3 Comments

JSLint/JSHint would have to make two passes (one to hoist functions and one to parse the document). They don't. However for readability sake it's still valuable to place functions at the top
So best practice would be this order? Variables, functions, init code?
It doesn't matter. Do it in the way to make it most readable.
1

Your code worked because JavaScript runtime will first hoist all named function before code execution:

alert(typeof(preloadImages)); // "function
function preloadImages() {
    // your code
}

Best practice would be putting all your named function at the top of an execution scope; In your case it's after the first line: $(function() {

This is to avoid any possible confusions.

Read more at http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting

Comments

0

Some people think it is a good idea to put all your function definitions and variable declarations at the top of their scope (i.e. at the beginning of the function). This is because the Javascript interpreter will do that, wherever your code is, and it helps to avoid confusing errors if your code is as close as possible to the interpreter's understanding of it.

This is a stylistic choice; you are free to ignore it. With JSHint, you can deselect the "Require variables to be declared before usage" option, and your code will pass.

(Well, it will when you correct the other error JSHint reports!)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.