14

Just a quick question here, I wanted to find out how I could set up these into an init() function then have the function run on document.ready. This code is being used in a separate main.js file. Does it need to be called from the index page?

$('#main_right_line_one').click(function(){
    $('#main_regular_layover, #main_deep_layover').fadeOut('slow', function(){
        $('#main_light_layover').fadeIn('slow');
    });
});

$('#main_right_line_two').click(function(){    
    $('#main_light_layover, #main_deep_layover').fadeOut('slow', function(){
        $('#main_regular_layover').fadeIn('slow');
    });
});

$('#main_right_line_three').click(function(){
    $('#main_light_layover, #main_regular_layover').fadeOut('slow', function(){
        $('#main_deep_layover').fadeIn('slow');
    });
});

Any help is appreciated. I'm really trying to wrap my head around this, but I can't seem to find any good tutorials that explain init() well enough for my specific code.

JJJ
  • 32,902
  • 20
  • 89
  • 102
user2635811
  • 171
  • 1
  • 1
  • 8
  • http://api.jquery.com/ready/ – go-oleg Jul 30 '13 at 21:03
  • So would I use get() to retrieve the divs? I'm not sure exactly what I would be loading before this would be initialized. – user2635811 Jul 30 '13 at 21:12
  • $("#main_right_line_one") is the selector to get the div (as a jq object). So, that div has to already be present in your HTML. therefore, you will want to run this in the init. – FlavorScape Jul 31 '13 at 23:13

2 Answers2

39

No need for special "calls", include it on the page with <script src="yourfile.js"></script> and just wrap your code as below to make sure that it is executed after the dom is ready (and the elements present).

$(function () {
   // your code goes here

});

$( a_function ) is short for $(document).ready( a_function ); more about ready handlers in the documentation.


The reason why $(document).ready(...)/$(...) is needed at all is that jquery selection like $('#main_right_line_one') only sees elements that are present at the execution time in the DOM tree. However, <script> tag contents are usually executed by browsers as soon as they're met; and <script> elements are usually located in <head>. Thus the scripts would often see an incomplete DOM tree. Now, thanks to the design of jQuery, even if $('#main_right_line_one') does not match any elements, there would still be no error; and the click handler would be bound to 0 elements.

This all can be avoided by wrapping that kind of code in $(function() { ... }), which ensures that whatever code is in it will be executed after the DOM has been fully initialized (or immediately if it already has been initialized).


The reason for why there is a shorthand like $(function() {}) for $(document).ready(function() {}) is that executing code only after the DOM tree has been finished is such a necessary pattern that almost every single page utilizing jQuery would be using.

  • 3
    and, to be clear, the above is a the same as `$(document).ready(function () {` `// your code goes here` `});`. – Brad Christie Jul 30 '13 at 21:05
  • So it seems simple enough to set this up, which I have done, but the comment above "This code will automatically execute. Be aware however that these elements specified by your selectors have to exist in the DOM before you can attach these events to them." is confusing me. Does jQeury not modify elements that have already loaded on the page? Do I need to do something extra in jquery to get it to recognize the divs on my page to be used with the onclick and fadein/out? – user2635811 Jul 30 '13 at 21:35
  • Why is that equivalent to document.ready? Is this behavior specific to functions passed to $() or jQuery()? For example, would $(document).something run immediatey, while $(function(){alert("hi");} wait for the document to load, by virtue of the parameter being a function? – Triynko Jul 01 '15 at 18:49
  • Great answer! [Here is another Q 'n' A combo](https://stackoverflow.com/a/24070373/2643993) that builds on this theme; it explains how browsers load assets and provides a more UX centric way to handle loading scripts. – plaidcorp Sep 30 '20 at 23:50
24

In your index page:

<html>
<head>
    <title>Your title</title>
</head>
<body>

    <!-- Your HTML here -->

    <script src="http://code.jquery.com/jquery-2.0.0.js"></script>
    <script src="main.js"></script>
</body>

You're right in that it's good practice to wrap all your code in an object and call that with an init() function. So in you main.js, you could have:

$(document).ready(function() {

    myPage.init();

});

And then below that, you can define your page object like so:

var myPage = (function() {

    var that = {};

    that.init = function () {

        $('#main_right_line_one').click(function(){
            $('#main_regular_layover, #main_deep_layover').fadeOut('slow', function(){
                $('#main_light_layover').fadeIn('slow');
            });
        });

        $('#main_right_line_two').click(function(){    
            $('#main_light_layover, #main_deep_layover').fadeOut('slow', function(){
                $('#main_regular_layover').fadeIn('slow');
            });
        });

        $('#main_right_line_three').click(function(){
            $('#main_light_layover, #main_regular_layover').fadeOut('slow', function(){
                $('#main_deep_layover').fadeIn('slow');
            });
        });

    }

    return that;

})();
Simon Adcock
  • 3,554
  • 3
  • 25
  • 41
  • this is a much better answer than the one selected. – George Katsanos Oct 31 '14 at 15:13
  • This adds a whole heap of confusing indirection. The init function would work fine by just being a procedural script, as you wouldn't really want to run that method more than once. The main.js script is the last item in the body so it doesn't even need to wait for document ready. As a bonus there would be no extra global myPage variable and the garbage collector can clean up all the no longer needed objects. – James Wakefield May 24 '16 at 12:37