When I add event handlers to objects in html using jQuery, do I have to call $.ready(function(){ ... })?

I am constructing a page which uses jQuery to assign event handlers. Now I am assigning onclick events to functions but does the page run the script and then construct the HTML or does the page construct HTML and then run the script?

<script type="text/javascript">
    function opinionbyid(popinionid){
        $.post("index.php", {"opinionid":popinionid}, function(data){
            var data2 = JSON.parse(data);
            $(".opinion").html(data2.opinion);
            $(".note").html(data2.note);
        }, "json");
    }
    function loginform() { $(".middle").html($(".loginform").html()); }
    function registerform() { $(".middle").html($(".registerform").html()); }
    function opinionpostform() {};
    $("#loginbutton").click(function(){
        //UNSURE, MAYBE I SHOULD DO IT IN $.ready(function(){ HERE }))
    });
</script>

like

$.ready(function(){ 
    $("#loginbutton").click(function(){
        // code...
    });
})

so far I habitually used script tags in the head section. this is why I think I should use $.ready() because assigning handlers to obects is done after objects are loaded, in jquery's documentation example.

<!DOCTYPE html>
<html>
<head>
  <style>
  p { color:red; margin:5px; cursor:pointer; }
  p.hilite { background:yellow; }
  </style>
  <script src="http://code.jquery.com/jquery-latest.js"></script>
</head>
<body>
  <p>First Paragraph</p>
  <p>Second Paragraph</p>
  <p>Yet one more Paragraph</p>
<script>
    $("p").click(function () { 
      $(this).slideUp(); 
    });
    $("p").hover(function () {
      $(this).addClass("hilite");
    }, function () {
      $(this).removeClass("hilite");
    });
</script>

</body>
</html>

after solution edit: In the end, I thought "why am I handling the events with script anyway?" now I am using

onClick="dosomething()"

on button properties. no need to complicate anything.

Upvotes: 3

Views: 206

Answers (4)

zzzzBov
zzzzBov

Reputation: 179186

HTML pages are parsed from the top down. Parsing JS blocks the parsing of HTML until the JS has been executed:

<div id="foo">Foo</div>
<script>
  $('#foo').click(..) //will work because #foo exists in the dom already
  $('#bar').click(..) //wont work because #bar doesn't exist in the dom yet
</script>
<div id="bar">Bar</div>

If you're attaching your scripts just before </body>, then you wont need to wait for document.ready because you're essentially already there.

If you're attaching your scripts within the <head> then you'll need to wait for document.ready because none of the DOM will have been parsed when the code is executed.

If you're making modular code, and you're not sure where it'll be added, wait for document.ready before binding so that it's safe no matter where the script is added.

If you're working with dynamic content, or simply don't want to add a document.ready handler, you can use live (deprecated as of 1.7) or on:

//pre 1.7
$('#foo').live('click', ...);
$('#bar').live('click', ...);

//post 1.7
$(document).on('click', '#foo', ...);
$(document).on('click', '#bar', ...);

This format will delegate the event listener to the document object which does exist at the time of execution. jQuery will handle the context behind the scenes to execute everything in the context of the selector provided in the second argument.


As a side note, make sure to alias jQuery to $ before use if you plan on reusing the code with other libraries. The document.ready aliasing shortcut is one of the best ways to do it:

jQuery(function ($) {
  //document.ready
});

Alternatively, use a self-executing closure:

(function ($) {
  //code here
}(jQuery));

Upvotes: 6

Artur Keyan
Artur Keyan

Reputation: 7683

the $("#loginbutton").click() must be in $.ready(function(){})

or

$(function() {
     $("#loginbutton").click(/*body*/)
})

Upvotes: 0

Manse
Manse

Reputation: 38147

The <script> tag is read and executed as the page loads - so if you put the <script> tags at the bottom of the page it will run once the whole page has loaded.

There are several events that occur during / after the page has been loaded - one of which is triggered when the DOM is ready ... in jQuery you can execute functions when this event is triggered using :

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

Docs are here on this function extract on which function to use :

All three of the following syntaxes are equivalent:

  • $(document).ready(handler)
  • $().ready(handler) (this is not recommended)
  • $(handler)

Any code within this function is executed once the whole page has been loaded. This ensures that any event handlers you create are actually bound as the object is within the document.

Upvotes: 0

hugomg
hugomg

Reputation: 69954

Scripts are run as soon as the script tag is encaountered when parsing, so it depends on where your script tag is located.

If you place your script on the <head> section it will run before the body is parsed and constructed, so you are forced to use $.ready to wrap your DOM accessing.

<html>
<head>
   <script> /* div foo is not created yet, must use $ready*/ </script>
</head><body>
   <div id="foo"></div>
</body>
</html>

On the other hand, if you place your script at the end of the body the relevant divs will already be created.

<html>
<head>
</head><body>
   <div id="foo"></div>
   <script> /* div foo already exists at this point*/ </script>
</body>
</html>

In any case, it is usually a good practice to wrap you DOM handling in a $.ready, for consistency and extra safety.

Upvotes: 0

Related Questions