I am trying to learn jQuery and I am confused how document.ready() function works
$(document).ready(function(){}
In html,
<script type="text/javascript" src="jquery.js"></script>
<script src="script.js" type="text/javascript"></script>
links are at the very bottom of the document, just before the closing body tag. In my javaScript file, I have all my code inside the .ready function. Yet, when I load the page, and I hover over a link, my cursor doesn't turn into a pointer for a couple of seconds, and if I immediately scroll down, the text is not yet loaded for a couple of seconds, either.
My javaScript file has a bunch of iframes etc... so I can understand why the delay, but what confuses me is that I thought the whole point of the .ready function was that the javaScript wasn't loaded until everything else in the page was loaded first? So surely my text and my css should be working straight away? Here is my code if it helps. I can post css too if required.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>myPage</title>
<link rel="stylesheet" type="text/css" href="styles2.css">
</head>
<body>
<div id="container">
<div id="backgroundLeft"><img id='backgroundLeftImage' src="Left.jpg" width="100%"></div>
<div id="wrap">
<p id="text">...some text... <span id="firstLink" class="link">click me</span>.<span><iframe id="frame" class="rect" scrolling="no" marginwidth=0 marginheight=0></iframe>
</span> ...some more text.... <span id="secondLink" class="link">click me</span>,
</span><span>
<iframe id="frame2" class="rect" scrolling="no" marginwidth=0 marginheight=0></iframe>
</span>
... some more text... <span id="thirdLink" class="link">click me</span> </span><span>
<iframe id="frame3" class="rect" scrolling="no" marginwidth=0 marginheight=0></iframe>
</span> ... some more text...
ETC...
</p>
</div>
<div id="backgroundRight"><img id='backgroundRightImage' src="2VillesRight.jpg" width="100%"></div>
<script type="text/javascript" src="jquery.js"></script>
<script src="script2.js" type="text/javascript"></script>
</body>
</html>
js
$(document).ready(function(){
var frame = $("#frame");
frame.attr("src","iframe.html");
var frame2 = $("#frame2");
frame2.attr("src","iframe2.html");
var frame3 = $("#frame3");
etc...
var player;
frame.bind("load", function () {
player = $(this).contents().find("#firstVid");
player.on('ended', function () {
frame.removeClass("open");
});
});
$("#firsLink").click(function(){
if (frame.hasClass("open"))
{
frame.removeClass("open");
player[0].pause();
}
else {
frame.addClass("open");
player[0].play();
}
});
var player2;
frame2.bind("load", function () {
player2 = $(this).contents().find("#sylvainVid");
player2.on('ended', function () {
frame2.removeClass("open");
});
});
$("#secondLink").click(function(){
if (frame2.hasClass("open"))
{
frame2.removeClass("open");
player2[0].pause();
}
else {
frame2.addClass("open");
player2[0].play();
}
});
var player3;
frame3.bind("load", function () {
player3 = $(this).contents().find("#etienneVid");
player3.on('ended', function () {
frame3.removeClass("open");
});
});
$("#thirdLink").click(function(){
if (frame3.hasClass("open"))
{
frame3.removeClass("open");
player3[0].pause();
}
else {
frame3.addClass("open");
player3[0].play();
}
});
etc...
});
I do know my code is repetitive, I am teaching myself so focused on getting it to work for now. Why is my main page taking so long to load if all my code is inside the "document.ready"? Thanks for your time
you can instead bind your javascript to the window.load event like this
Edit: tis is not good practice and unsupported in newer versions of jQuery
$(window).load(function(){ ... });
Correct way to do this
$(window).on("load", function(){ ... });
document ready lets you access the complete markup, even if the images and iframes have not loaded yet, this is desired in most cases.
In your case however, you might want to take the time penalty of waiting for everything to load, this is that the window.load event does.
$(document).ready() will only wait for all of the page's elements to load. It will NOT wait for the iFrames to load their content.
You can refer to this post if you have more questions:
$(document).ready and iframe content
Are you sure JQuery is loading properly? The source (src) property needs to point to the correct path. I find using the developer's tools to review errors, manipulate CSS and check DOM state to be helpful when learning. I prefer Chrome.
Happened to me too. What I found that, the solution is to include the file at the bottom outside of html tag (i.e the file in which you are using $(document).ready() ).
I assume that, this is because the html document is not ready by the time when browser compiler reached at this function.
Related
I really don't know why this isn't working. In my HTML, if I put my script in the head section, I get the following error in my console:
Uncaught TypeError: Cannot read property 'addEventListener' of null
If I put my script in the bottom part of the body, it's working fine.
HTML :
<head>
<link rel="stylesheet" type="text/css" href="style.css">
<script type="text/javascript" src="script.js"> </script>
</head>
<body>
<ul>
<li> Shahin </li>
<li> Lina </li>
<li> Adrita </li>
</ul>
<img src="./img/1.jpg" class="hidden">
<img src="./img/2.png" class="hidden">
<img src="./img/3.jpg" class="hidden">
</body>
JavaScript :
var shahin = document.getElementById('img1');
var lina = document.getElementById('img2');
var adrita = document.getElementById("img3");
shahin.addEventListener('click',picShow);
lina.addEventListener('click',picShow);
adrita.addEventListener('click',picShow);
function picShow() {
console.log(this);
}
Can anybody tell me what I'm doing wrong and where is the proper place to put the script tag? Also, what change should I make to run my script from head section? I will be glad for your answer. Thanks in advance
Your script is loading and being executed prior to the rest of the body HTML, so naturally, document.getElementById is going to return null.
You should be running your event listener subscription code on or after the document.ready event.
Wrap the code you posted into a JS function, then set that function as the callback to be executed on document.ready:
document.addEventListener('load', initFn);
<script type="text/javascript" defer src="script.js"> </script>
Add key word defer, script runs when all DOM elements will loaded
If you put your <script> in the <head> javascript loading from top to bottom. So when loading it returns undefined eventlistener. So try use the script just before the end of your </body> tag and it will works.
Like so:
<script type="text/javascript" src="script.js"> </script>
</body>
Further to Josh E's answer:
You should be running your event listener subscription code on or after the document.ready event
If you want to execute your code as soon as the element is available, you can use requestAnimationFrame to scan the DOM during page load instead of waiting for the entire page to load:
function doSomethingWithElement(myElement) {
myElement.addEventListener('click', function() {
// Do stuff here
});
}
function searchForElement() {
const el = document.getElementById('img1');
if (el) {
return doSomethingWithEl(el);
}
window.searchID = window.requestAnimationFrame(searchForElement);
}
// Store the request ID so it can be cancelled later
// Otherwise it'll run forever!
window.searchID = window.requestAnimationFrame(searchForElement);
window.addEventListener('load', function() {
window.cancelAnimationFrame(window.searchID);
});
This might be overkill but it's super useful when you want to manipulate or add listeners to DOM elements as soon as is possible.
Real simple but I'm starting with javascript so it should be quickly soved
I have this html:
<body>
<div id="content">
<div id="logo">
<noscript>
<img src="fin_palais.png"/>
</noscript>
</div>
</div>
</body>
and i want to select the div with an id of "logo" with javascript to then overwrite the <noscript> with the apropriate file ( a simple browser test to see if you can support SVG )
this innerHTML look like this:
document.getElementById('logo').innerHTML='<content to be added>';
Firebug send me this error: TypeError: document.getElementById("logo") is null
but its right there!
Thanks
okay so here is the full HTML:
<html>
<head>
<META CHARSET="UTF-8">
<title>Bienvenu au Fin Palais</title>
<script type="text/javascript" src="svg_support.js"></script>
<script type="text/javascript">getSvgSupport("fin_palais")</script>
</head>
<body>
<div id="content">
<div id="logo">
<noscript>
<img src="fin_palais.png"/>
</noscript>
</div>
</div>
</body>
</html>
and here's the full svg_support.js I've made;
function getSvgSupport(file)
{
var ua = navigator.userAgent;
if( ua.indexOf("Android") >= 0 )
{
var androidversion = parseFloat(ua.slice(ua.indexOf("Android")+8));
if (androidversion <= 2.3)
{
document.getElementById('logo').innerHTML='<img src="',file,'.png"/>';
}
} else {
document.getElementById('logo').innerHTML='<!--[if lt IE 9]><img src="',file,'.png"/><![endif]--><!--[if gte IE 9]><!--><embed src="',file,'.svg" type="image/svg+xml" /><!--<![endif]-->';
}
}
yes that is the only reason, and since you seem new to javascript I guess this would make more sense to you
window.onload=function(){
document.getElementById('logo').innerHTML='<content to be added>';
}
You see when your script runs you page has not loaded. so you must use window.onload.
Or you can use this too, if your code is in file.js:
<script defer src="file.js"> </script>
this makes sure your code doesn't run unless document is parsed.
You may be trying to run the javascript before the DOM has finished loading. Try this:
$(document).ready(function(){document.getElementById('logo').innerHTML='<content to be added>';});
This assumes you've included jQuery.
As #Thristhart said, you can also use window.onload. This is a built-in javascript event which happens AFTER $(document).ready() does, so you should be safe with that as well.
If using JQuery:
$(document).ready(function(){
$('div#logo').html('<content to be added>');
});
Or
$(function(){
$('div#logo').html('<content to be added>');
});
You don't have to load jQuery if you don't want to it seems like something is off with the chaining of the javascript. When I broke it apart it worked fine.
Fiddle: http://jsfiddle.net/DamianHall/GxghG/
var ele = document.getElementById('logo');
ele.innerHTML = 'content to be added';
Looking at other posts it is an onload issue. The JS fiddle did the onload for me so I didn't notice.
When i keep my javascript/jquery external, my code doesn't work. but when i combine them in my html file everything is fine.
any suggestions as to why this is?
here is the code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<script type ="text/javascript" src="jquery.js"></script>
<script type ="text/javascript" src="program.js"></script>
</head>
<body>
<div id="clickme">
Click here
</div>
<img id="book" src="book.png" alt="" width="100" height="123" />
<p>First Paragraph</p>
<p>Second Paragraph</p>
<p>Yet one more Paragraph</p>
</body>
</html>
with external javascript
$('#clickme').click(function() {
$('#book').fadeOut('slow', function() {
// Animation complete.
});
});
$("p").click(function () {
$(this).slideUp();
});
VERSUS
<!DOCTYPE html>
<html>
<head>
<script type ="text/javascript" src="jquery.js"></script>
</head>
<body>
<div id="clickme">
Click here
</div>
<img id="book" src="book.png" alt="" width="100" height="123" />
<p>First Paragraph</p>
<p>Second Paragraph</p>
<p>Yet one more Paragraph</p>
<script>
$('#clickme').click(function() {
$('#book').fadeOut('slow', function() {
// Animation complete.
});
});
$("p").click(function () {
$(this).slideUp();
});
</script>
</body>
</html>
I guess you execute the click event before the DOM finishes loading. Wrap your code inside the dom ready event and it should work, Assuming your path to the external javascript file is correct.
$(function(){
$('#clickme').click(function() {
$('#book').fadeOut('slow', function() {
// Animation complete.
});
});
$("p").click(function () {
$(this).slideUp();
});
});
Always use firebug (console) to see what is wrong with the script, if you run into any script errors.
Your javascript is executed before there are elements on the page. You can get around this by using $(document).ready(function(){...}); or moving your external javascript files to the bottom.
Wrap your js code in external file in
$(document).ready(function(){
//your code goes here
});
Right now you are including external js file in header and it is executed. At this point there is no elements so $('#clickme') and $("p") are empty set. In the second example you run this code after rendering html with that elements.
The reason that there is a difference, is that in the external file your code is executing before the browser has fully parsed the DOM so you are attempting to programatically access elements of the page which the browser is not yet aware of. This is exactly what most people have already said, but let me elaborate a bit further...
Whilst a lot of people have mentioned using jQuery's document ready handler, I would like to point out that a workable solution is simply to move your script tags to the bottom of the page.
Not only will this solve your problem in itself, but it will also improve page load times because of how browsers treat scripts. When the browser encounters a script it stops everything else it is doing (known as a "blocking" operation), and parses and executes the script. This causes the page to just appear to stall from a user's perspective, meaning a bad user experience. Thus, because the scripts are parsed and executed only as they are encountered, by moving your scripts to the bottom you allow the browser to fully render the page so that the JavaScript does not block rendering.
Though rather than just moving scripts to the bottom of the page, I'd also follow what the others recommended and wrap the whole code in the document ready handler just to be extra safe that your code will always be executed at the correct time.
Also, in the debate of inline or external, external scripts are generally preferred as they are easier to maintain and the browser can cache them independently of the page (providing the correct HTTP headers are present).
To sum up here's some example code:
<html>
<head></head>
<body>
<!-- all your markup here -->
<!-- script at bottom, markup already rendered by this point -->
<script type="text/javascript" src="jquery.js"></script>
<!-- inline or external, still wrap in document ready handler -->
<!-- though external is better because the browser can cache it independently of the page -->
<script type="text/javascript">
//wrap in document ready to be extra safe
$(function() { /*code here*/ });
</script>
</html>
i use that tag to alert me when a tag has been shows up
<html>
<head>
</head>
<body>
<script type="text/javascript">
document.getElementsByTagName('iframe')[0].onload = function() {
alert('loaded');
}
</script>
<iframe></iframe>
</body>
</html>
strange , since this code working :
<html>
<head>
</head>
<body>
<iframe></iframe>
<script type="text/javascript">
document.getElementsByTagName('iframe')[0].onload = function() {
alert('loaded');
}
</script>
</body>
</html>
why the Js need to under the tag to work?
what's the problem here?
Because the code in a script tag is executed immediately. And in the first example the iframe doesn't exist at that time. But what you can do is to wrap you code into an onload (for the main page) event. E.g.:
window.onload = function() {
//your code
}
Then it doesn't matter where the code is placed.
Iframe tag does not exist at the moment you are trying to access it.
You may check that by simply alerting array length, like
alert(document.getElementsByTagName('iframe'));
Have you thought about executing your javascript after the page is loaded? You may use some frameworks like jQuery to facilitate crossbrowser issues. Or just put all your javascript code to the very bottom of body.
I am trying to use jQuery's .load function to dynamically load content into my webpage. This seem so simple, but I cannot make it work. To try and figure it out, I made a test page with just basic structure, but the external content still won't load:
jquery.html
<html>
<head>
<title>JQuery Test</title>
<script src="jquery1.5.min.js"></script>
</head>
<body>
<script>
$('#foo').load('test.html');
</script>
<div id="foo"></div>
</body>
</html>
test.html
<p>Text text</p>
I'm sure I have made a tiny error, but I can't find it anywhere!
You need to encapsulate your script in the $(document).ready() otherwise #foo won't exist when the script is executed:
<script>
$(document).ready(function(){
$('#foo').load('test.html');
});
</script>
You need to wait for the document to be ready before you can access the DOM. Just add a $(document).ready() around your original code:
<html>
<head>
<title>JQuery Test</title>
<script src="jquery1.5.min.js"></script>
</head>
<body>
<script>
$(document).ready( function() {
$('#foo').load('test.html');
});
</script>
<div id="foo"></div>
</body>
</html>
or if you want a shorter code:
$(function() {
$('#foo').load('test.html');
});
Informally, what's happening is that, as your browser reads the code you wrote, it's drawing its contents as it goes along. When it reaches your <script> tag, it executes it. But when $("#foo") gets executed, the browser's still processing the <script> and hasn't reached the part of the code where you told it there's a div called foo, so the browser doesn't know it exists, and jquery will just find nothing.
Of course, the idea that the browser will just sequentially read your code and render it as it goes is naive at best, so while it might seem that just moving the <script> tag to the bottom of the code would work, you're not actually guaranteed it will work. Instead, the browser will notify you when it's done drawing the page by firing a load (and possibly a DOMContentLoaded) event. So all code that depends on the whole html being drawn should be executed in an event handler bound to those events.
jQuery makes waiting for the page to be loaded easy, just use something like this:
$.ready(function() {
doStuff();
});