Reputation: 3820
Have never seen this before. Something so simple I'm doing wrong.
My JQuery code just stopped working in the head tag, and now will only work in the body.
This will work:
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
</head>
<body>
<div id="foo">
Click Me
</div>
<script type="application/javascript">
$('#foo').click(function(){
alert("I got here");
});
</script>
</body>
</html>
And this will not:
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script type="application/javascript">
$('#foo').click(function(){
alert("I got here");
});
</script>
</head>
<body>
<div id="foo">
Click Me
</div>
</body>
</html>
A bit confused. I don't see the typo. Advice most appreciated!
Upvotes: 1
Views: 150
Reputation: 9235
Try this. It happens because the DOM isn't yet loaded.
$(document).ready(function() {
$('#foo').click(function(){
alert("I got here");
});
});
Or without using a specific library (I think it's more self-describing)
window.onload = function(){
document.getElementById('foo').onclick = function(){
alert('I got here');
};
};
HTML file is loaded sequentially, so your code works within the body
because it fires after the div
has been created, but it doesn't work within the head
section because at that moment the div
wasn't yet created. That's way is .onload
event used - it guaranteed that nothing will be executed until the DOM isn't ready.
Upvotes: 3
Reputation: 1074198
The problem is that your code runs before the element exists, so $("#foo")
doesn't find it.
Unless you use the async
or defer
attributes, the code in your script
tags is run when it is encountered in the HTML. So:
<script>/* your code here */</script>
<div id="foo">..</div>
...will not find the #foo
element, because it doesn't exist yet.
But if you have
<div id="foo">..</div>
<script>/* your code here */</script>
...the element exists and your code can find it.
You have three choices:
Use event delegation, where you hook the event on document
but only respond to it if the event travelled through a #foo
element during the bubbling phase. Example:
$(document).on("click", "#foo", function() {
// Do something
});
This works well unless something else will handle the event on a descendant element of document
and prevent it bubbling.
Put the script below the elements it refers to in the HTML. This is vastly preferred. Any elements defined in the markup above the script
tags will exist as of when your script runs. So the usual advice is put the script
just before the closing </body>
tag.
If you don't control where the script
element goes, use jQuery's ready
function.
$(document).ready(function() {
// Your code here
});
or the shortcut:
$(function() {
// Your code here
});
Upvotes: 5
Reputation: 1510
You need to execute your script when the dom is ready. If you put the code into head it will get executed before the browser has loaded the dom inside body, therefore jquery can not find foo. If the code is in body after the element with id "foo" then it will have created the element before the javascript code gets executed.
$(document).ready(function() {
$('body').on('click', '#foo', function(event) {
alert('Hello World');
});
});
If you wrap an on ready around your code it will again work. You could also use jQuery on, and tell jquery to listen on the body, this has the advantage that it will still work even if the element foo is loaded by ajax and inserted into the dom after ready got executed.
Here is the jsfiddle: http://jsfiddle.net/6uLHL/
Upvotes: 1
Reputation: 582
The comments and answers that tell you to wrap the code in $(document).ready()
are correct but fail to mention why this happens.
This behavior occurs because when you try to excecute the script the DOM has not been created in its enterity and therefore the element you are looking for does not exist. When using $(document).ready()
you make sure that the scripts run after the DOM is ready
Upvotes: 0