11

I am a beginner learning jQuery and web development, so this may be a dumb question, but I cannot find an answer to this on Google (probably I'm not searching for the right keywords). I have a simple HTML file (say, 'test.html' that loads jQuery, an external javascript file (say, 'test.js') that I wrote, and have a button in it. For example,

<html>
....
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script src="scripts/test.js" type="text/javascript"></script>
....
<body>
<button type="button" class="button" id="my_button">test</button>
</body>
</html>

In 'test.js', I have:

$( "#my_button" ).click(function() {
    alert('test');
    return false;
});

But when I click on the button, it doesn't work. However, when I put what's in 'test.js' in 'test.html' like this:

<html>
....
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script type="text/javascript">
$(function() {
    $( "#my_button" ).click(function() {
        alert('test');
        return false;
    });
});
</script>
....
<body>
<button type="button" class="button" id="my_button">test</button>
</body>
</html>

It works. First question is: Can someone explain me why it would work when I insert the code in external file and load it? Is that always necessary to wrap jQuery code with $(function() {......} for it to work?

Ideally, I don't want javascript code in my HTML template because it's obviously messy. Related/second question is: What is the cleanest/best way to separate the javascript/jQuery code like above and yet make it work in the intended HTML template?

Thank you for your answer.

user1330974
  • 2,500
  • 5
  • 32
  • 60
  • 3
    $(function(){}) == $(document).ready() as in the dom elements have been loaded and it is safe to attach listeners to it. – Patsy Issa Jul 11 '13 at 18:00
  • 1
    *"What is the cleanest/best way to separate the javascript/jQuery code like above and yet make it work in the intended HTML template?"* Move the scripts to right before the closing body tag. – Kevin B Jul 11 '13 at 18:01
  • Yes, you would do this in any file you're doing a direct – Thinking Sites Jul 11 '13 at 18:02
  • Thank you all. @ThinkingSites could you please direct me to a resource that explains the circumstances when I wouldn't want to use it? – user1330974 Jul 11 '13 at 18:35
  • Hi @KevinB, wouldn't moving the scripts before

    just delay the loading of those scripts? I understand it sort of moves javascript stuff below HTML, but is that a good practice to follow? I want to build good habits as I am beginning to learn it. Habits die hard, as you know. :) Thank you

    – user1330974 Jul 11 '13 at 18:36
  • 1
    Yes, it would delay the loading and execution of the scripts, which is precisely what you need in order for them to execute properly. Without moving it to the closing body or binding to the ready event, the scripts will execute before the elements exist(you can't bind an event *directly* to an element that doesn't exist yet). Moving it to before the closing body tag can result in your page *appearing* to load faster to the end user because the HTML will likely be parsed and rendered before the javascript is downloaded/executed. – Kevin B Jul 11 '13 at 18:37
  • @PatsyIssa, does that mean $( "#my_button" ).click(...) is a listener and therefore, must be wrapped around $(document).ready() in order to use it only when dom elements have been loaded? Does that apply to any listener? Thank you! – user1330974 Jul 11 '13 at 18:39
  • Thanks, @KevinB. That makes sense and now I feel like I understand this much better. :) – user1330974 Jul 11 '13 at 18:44

4 Answers4

13
$(document).ready(function() {

    $( "#my_button" ).click(function() {
        alert('test');
        return false;
    });

});
simongus
  • 440
  • 2
  • 6
10

You need to have $(function() { ... }) for your click function to work. It tells jquery that the document is loaded and it can start working on the DOM. Before then, the DOM is not ready and your element might not exist.

EDIT: Use this for your external files too, unless you are more advanced and know when NOT to use it.

Thinking Sites
  • 3,494
  • 17
  • 30
  • As I asked before, it would be very helpful if you could link/explain when I should NOT use it. Thank you @ThinkingSites – user1330974 Jul 11 '13 at 18:45
  • It's mostly a case by case basis and for advanced usage. Here are a few: If you have a single page application that guarantees ready has already fired. If you have another library with its own ready event you're using. If it's part of a module library and the module parent already calls it. In all of these cases, it's okay to call document.ready since it won't hurt anything, but chances if you know what you're doing, there are cases when you can skip it. – Thinking Sites Jul 24 '13 at 12:32
1

Event binding on jquery needs the HTML object already rendered to work.

If you say $('#button').click(function(){dosomething()}); You need #button already exist on HTML to work.

When you use $(function(){}); The code waits to document ready event to execute the code. So, if you call button.click on wrong time it wouldn't find the button and doesn't work.

Paritosh
  • 11,144
  • 5
  • 56
  • 74
Guerra
  • 2,792
  • 1
  • 22
  • 32
0

Move your script tag of test.js just above closing body tag (or after button tag). If you call your script before your button, then it can not find button with id name. If you put it after button then it will work.

ndmeiri
  • 4,979
  • 12
  • 37
  • 45
Ankur Patel
  • 129
  • 1
  • 3