Keeping javascript external - doesn't work - javascript

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>

Related

Jquery Not Being Processed

The below Jquery does not run within my browser even though the syntax is correct( checked via online syntax checker) and the functions do run (tested with pure JS). Why is it that so?
I apologize in advance if the answer to this question is rather simple but after 15min of googling I could not arrive at an answer.
JAVASCRIPT:
document.getElementById('overlay').addEventListener('click', function( {
closeLightBox()
});
function closeLightBox() {
$("#overlay").fadeOut(1000);
}
function lightbox(x) {
}
HTML
<!DOCTYPE html>
<html>
<head>
<title> Lightbox </title>
<link rel="stylesheet" type="text/css" href="lightboxcss.css">
</head>
<body>
<div id = "overlay"> </div>
<img src="batman.jpg" alt="" href="javascript:void(0)" onclick="lightbox(1)" id="batman" style="height:100px;width:160px;margin-left:45%;margin-top:16%;">
<br><br><br><br>
<p> RANDOM TEXT STUFF </p><br><br>
<p> 328ueekfuuirgh40t43h8hohro8ht </p>
<script src="lightboxjs.js"> </script>
</body>
</html>
I assume that javascript code is located in your .js file "lightboxjs.js". Did you include the jQuery library anywhere?
If you don't, start by adding this line <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script> before including your custom javascript file.
$(document).ready(function(){
//page is ready
$("#overlay").on("click",function(){
this.fadeOut(1000);
});
});
You cannot add an eventlistener if the dom isnt loaded. Also dont forget to include jquery before executing the upper script
...
Where are you calling the jquery lib? You need to load the jquery just above lightboxjs.js and may as well use jquery syntax to listen to the #overlay click event.

jQuery : why is document.ready function not working properly

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.

jquery load time and css styling inside it

like you see in the code below, the jquery loads a page but it seems that all the .css styling inside the jquery waits until the jquery is loaded which can take some fraction of a second if the file is big. So if I have .css("display","none") it will not work for that time causing a flickering before the styling kicks in. I have this problem only with Mozilla. The code below its only an example and it works well because is small. Some ideas how to fix this?
$(document).ready(function() {
$(".rectangle").click(function() {
$("body").load("debugging2.html", function() {
$(".rectangle").css("display","none")
$(".rectangle").fadeIn(1000);
}) ;
});
})
.rectangle{
height: 200px;
width: 200px;
background-color:#000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<body>
<div>
<div class="rectangle"></div>
</div>
</body>
$(document).ready(function() {
$(".rectangle").click(function() {
$("head").append("<style>.rectangle{display:none;}</style>");
$("body").load("debugging2.html", function() {
$("rectangle").fadeIn(1000);
});
});
})
Since script tags are loaded synchronously (by default) they indeed block page rendering. It can result in blank unstyled page if HTML is not processed and styles are not loaded by that moment. Hence the common very simple solution is to move heavy script tags to the very end of the </body> and put necessary CSS style in the <head>.
As the result of above, CSS gets downloaded first, after HTML is loaded quickly, rendered and styled and only after that slow scripts get downloaded.
In code it will look something like this:
<head>
<link href="style.css" rel="text/css" type="stylesheet">
</head>
<body>
<div>
<div class="rectangle"></div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<!-- some other scripts -->
</body>
As the bonus, you don't need to bind to document ready event anymore ($(document).ready(function() {});), since HTML is all loaded by default, when scripts are executed.

Avoid GET of all contents of the HTML DOM

Context
I have a HTML5+CSS+JS slideshow designed to be synchronized between 50 clients in a domestic LAN with one wireless router.
Problem
Since the contents of the slides (mainly pictures) may be too heavy, I want to load them dynamically for each slide (e.g. as the client clicks a "next" button), since currently the site GETs all the files for every slide from the server at the beginning when the page is loaded, overloading the router.
In this question (another approach for the same problem) an user suggested me using AJAX to get only the DOM and then loading its contents dynamically. Nevertheless, his solution doesn't work for me, as the contents are loaded before the moment I want to.
Is this AJAX based approach correct? If so, what may I be doing wrong?
My code
slideshow.html (slideshow structure)
<html>
<head>
<title>My Slideshow</title>
<script src="javascripts/slidesplayer.js"></script>
<link rel="stylesheet" href="/stylesheets/style.css">
</head>
<body>
<div id="slides-containter">
<div class="slide" id="slide_1">
<!--Contents such as images, text, video and audio sources -->
</div>
<div class="slide" id="slide_2">
<!--Contents -->
</div>
<!--A bunch of slides here-->
</div>
<script>
// Here I load the slides calling a function defined in slidesplayer.js
</script>
</body>
</html>
slideshow-placeholder.html (loaded when I enter to the slideshow URL)
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="/path/to/ajaxSlidesScript.js"></script>
</head>
<body>
<h1>Hello slides!</h1>
</body>
</html>
ajaxSlidesScript.js
$(document).ready(function() {
$.ajax('/path/to/slideshow.html', {
async : false,
complete : function ajaxCallback(slidesDOM) {
// Pull out the individual slides from the slideshow HTML
$slides = $(slidesDOM.responseText).find('.slide');
// For each one ...
$slides.each(function prepareSlide() {
// Store a reference to the slide's contents
var $slideContent = $($(this).html()); // <--- GETs all the files for this slide which I want to avoid.
// Empty the contents and keep only the slide element itself
var $slideWrapper = $(this).empty();
// Attach to focus event handled by the slideware
$slideWrapper.appendTo('body').on('focus', function injectContent() {
// Put the content in — NOW external resources should be downloaded via GET and loaded, not before.
$slideWrapper.append($slideContent);
});
});
}
});
});
Update: This approach won't work, as manipulating DOM object will cause the download of the resources even if you don't insert them in the DOM. You can see what I did in this question.
Ajax is definitive the right technology for your problem but as far as I can see your problem is simple.
<script src="javascripts/slidesplayer.js"></script>
<link rel="stylesheet" href="/stylesheets/style.css">
With this piece of code it doesn't matter if you use ajax or not because you load the CSS file already and all images referenced in this CSS file are load directly at the beginning. In addition you should load all files asynchronous.
You can add <img> tags via JavaScript and load the images asynchronous...

Basic jQuery .load Problem

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();
});

Categories