Apologies if this is an old question. I have spent a few hours searching for an answer but had no luck.
I'm attempting to convert an existing (primarily jQuery) application to use AngularJS. I've hit a problem where a JavaScript file I am including in index.html is being run too early when being included in my AngularJS application. i.e. by using a <script> tag:
<script type="text/javascript" src="/components/js/theme.js"></script>
This file contains a lot of jQuery which needs the rest of the page to have been rendered to have an effect. So is there a way I can include this script and ensure it is only loaded after the rest of the page has finished loading? I have a set of directives on the page and the script is being loaded before these are rendered.
Update:
Here is the structure of my index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<title>App Title</title>
<base href="/">
<!-- icons and CSS -->
<link href="/img/ico/favicon.ico" rel="shortcut icon"
type="image/vnd.microsoft.icon">
<link href="/css/bootstrap.min.css" media="screen" rel="stylesheet"
type="text/css">
<!-- External Libraries -->
<script type="text/javascript" src="/external/jquery/dist/jquery.min.js"></script>
<script type="text/javascript" src="/external/angular/angular.js"></script>
<!-- Angular Components -->
<script type="text/javascript" src="/components/services/ui.js"></script>
<script type="text/javascript"
src="/components/navigation/js/navigation.js"></script>
<!-- App set and config -->
<script type="text/javascript" src="/js/app/app.js"></script>
<script type="text/javascript" src="/js/app/config.js"></script>
<script type="text/javascript" src="/js/app/routes.js"></script>
<!-- endbuild -->
<!-- Precompiled HTML templates -->
<script type="text/javascript" src="/js/templates.module.js"></script>
</head>
<body ng-cloak>
<!-- directive -->
<top-nav-bar></top-nav-bar>
<div class="content">
<div class="container">
<!-- directive -->
<side-nav-bar></side-nav-bar>
<!-- angular view -->
<div ng-view></div>
</div>
</div>
<!-- directive -->
<adysis-footer></adysis-footer>
<!-- Bootstrapper -->
<script src='/js/app.bootstrap.js' type='text/javascript'></script>
<!-- JAVASCRIPT FILE WHICH NEEDS TO RUN AFTER PAGE HAS LOADED! -->
<script type="text/javascript" src="/components/js/theme.js"></script>
</body>
</html>
As you can see, the "theme.js" file is the last item of the <body>. I have stopped in the file to ensure it is being loaded. But this is always done before the rest of the page has rendered. Could some other JavaScript be interfering upsetting things? Note that I have not included all of the JavaScript files that are being included.
Update 2:
I've added further break points in the JavaScript functions for the directives you can see in my index.html. Each of them is stopped in after the theme.js is executed. I don't know why this is, so I'm mentioning this in case it gives more clues as to the problem.
Update 3:
The first line of the "theme.js" file is:
jQuery(document).ready(function($)
And then the function contains a long series of jQuery selectors to setup events and so on. My understanding is the point of this line is to wait until the document has been loaded. But could something in my setup, e.g. Angular, be preventing this from happening?
I've tried changing this line to:
angular.element(document).ready(function($)
and whilst this does lead to the content on the function to be run later, it's still not after the whole document has loaded.
Make sure it's at the end of your HTML Body and not in the header section. If it's in the head section it'll load before the page renders.
So typically, in our HTML files, the general structure looks a bit like this:
<!DOCTYPE HTML>
<html lang="en">
<head>
<!-- Favicon -->
<!-- Meta Stuff -->
<!-- Title -->
<!-- CSS Files -->
<!-- JavaScript Files -->
<!-- Other Header Stuff -->
</head>
<header>
<!-- Navbar & Header Stuff -->
</header>
<body>
<!-- Body Stuff -->
</body>
<footer>
<!-- Copyright & Footer Stuff -->
</footer>
</html>
However, I often find myself using JavaScript Files that need to be loaded after the body, or whatever element it interacts with. As such, the body may end up looking like this:
<body>
<!-- Body Stuff -->
<script src="..."></script>
<script src="..."></script>
<script src="..."></script>
...
<script src="..."></script>
</body>
Sure, I could merge all of that stuff into one large Script File, either manually or using some sort of compiler. I could even wrap all of my scripts into a separate div so that I can mark that as "separate" in my mind.
However, all I'm really doing is injecting a bunch of scripts at the end of my document. This stuff shouldn't really go in a body tag, because it's not actual content, just code.
To rectify this, I often use a tail tag, like so:
<!DOCTYPE HTML>
<html lang="en">
<head></head>
<header></header>
<body>
<!-- Body Stuff -->
</body>
<footer></footer>
<tail>
<script src="..."></script>
<script src="..."></script>
<script src="..."></script>
...
<script src="..."></script>
<script>(function() { console.log('Custom code'); })();</script>
</tail>
</html>
Browsers seem to be fine with this, and I'm happy with this solution. However, the tail tag isn't a part of the HTML specifications, and I've seen little to no usage of a tail tag, except old HTML4 stuff that used a tail tag as a footer tag.
So what I'm wondering is: Is this good practice? Are there any downsides to this approach?
I see where you're going with this. I've considered the same concept. There are valid cases for putting <script> tags at the bottom of a document, and they don't really need to be in the <body> tag -- except that there is no other valid place to put them (save the <head>). In lieu of creating invalid tags for organizational purposes, I have done the following:
<section id="tail">
...
</section>
</body>
With some CSS like
section#tail { display: none; }
to ensure there are no errant display effects.
Is this good practice?
No.
Are there any downsides to this approach?
You would have to perform exhaustive browser testing to see whether this worked, including text browsers and screen readers. Also, people may laugh at you, and Steve Faulkner will create an amusing meme about you... which is a downside if that may offend you.
Put all of your content in the body tag, and just place all of the scripts before the </body> tag, not wrapped in anything. They are not displayed, so there is no need to group them in an element.
<!DOCTYPE HTML>
<html lang="en">
<head></head>
<body>
<header></header>
<!-- Body Stuff -->
<footer></footer>
<script src="..."></script>
<script src="..."></script>
<script src="..."></script>
...
<script src="..."></script>
<script>(function() { console.log('Custom code'); })();</script>
</body>
</html>
Not good practice. As an alternative to including scripts within the <body></body> tags, you could leave them in the <head></head> section and the code you want after the page has loaded could be called using the following Jquery:
$( document ).ready(function() {
});
Or the following javascript:
window.onload = function() {
};
HTML Tail defines the HTML code to insert at the bottom of each HTML document, usually to include a link back to your home page or insert a small graphic. It is inserted as a table data element and is right aligned with the page.
Sorry, but I don't agree with your method.
Basic structure:
<!DOCTYPE html>
<html>
<head>
<!-- Some meta data -->
<!-- Title -->
<title></title>
<!-- Link to css script -->
<link rel="stylesheet" type="text/css" href="example.css"/>
</head>
<body>
<!-- Some Content -->
<!-- Script tag to .js source script -->
<script src="example.js"></script>
</body>
</html>
And simple explanation of a proper basic-page load:
When browser goes through that HTML script,
it first recognizes the type of a script defined,
then it runs onto a LINK tag, which directs it to the .css script. Browser reads it and first displays a style on a page,
then it goes through a BODY tag and displays a content,
and let's say at last, it runs onto a SCRIPT tag, which directs the browser to a .js script, reads it, and as last loads the interactivity to a page.
Which gives a user nicer experience when visiting some page.
i have a HTML template in which i have used a third party javascript code. this particular code provides an chat option.i have added this script in my header.html so that it gets displayed in all the pages. however i dont want this to display in my login page.i want this to be displayed only after logging in.
How do i hide this from a particular page(here login.html)?
Header.html
<!doctype html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="bower_components/weather-icons/css/weather-icons.min.css">
<link rel="stylesheet" href="styles/main.css">
</head>
<body data-ng-app="app" id="app" class="app" data-custom-page="" data-off-canvas-nav="" data-ng-controller="AppCtrl" data-ng-class=" {'layout-boxed': admin.layout === 'boxed' } ">
<section data-ng-include=" 'views/index.html' " id="header" class="header-container" data-ng-class=" {'header-fixed': admin.fixedHeader} " data-ng-controller="HeaderCtrl" data-ng-intro-options="introOptions" data-ng-intro-method="startIntro" data-ng-intro-autostart="true"></section>
<script src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script src="scripts/vendor.js"></script>
<script src="scripts/jquery.leanModal.min.js"></script>
<script src="scripts/ui.js"></script>
<script src="scripts/app.js"></script>
<script src="scripts/product_listing.js"></script>
<script src="scripts/angular-cookies.js"></script>
<script id="SettingsScriptTag">
**Third Party script Goes here**
</script>
</body>
</html>
The above header.html is included in all the other templates. hense the thrid party script runs in login page too. I need to hide this in login page.
If you're using jQuery (which... I think you are...?)
$(function () {
if (window.location.pathname !== '/login.html') {
// Third-party script goes here
}
});
If Using jquery .remove() is used to remove the html elements. So you can write this script on document ready of the login page.
$(document).ready(function(){
$( "#SettingsScriptTag" ).remove();
});
I'm trying to load up angular inside my body tag but for some reason nothing is getting loaded, when I check the resources panel it only contains files from the head. If I move all this stuff to the head It shows up in resources and its loaded, but when in the body, it's unloaded.
<body>
<section ui-view=""></section>
<!-- inject:js-->
<script src="/angular/angular.js"></script>
<script src="/json3/lib/json3.js"></script>
<script src="/es5-shim/es5-shim.js"></script>
<script src="/jquery/dist/jquery.js"></script>
<script src="/angular-resource/angular-resource.js"></script>
<script src="/angular-cookies/angular-cookies.js"></script>
<script src="/angular-sanitize/angular-sanitize.js"></script>
<script src="/angular-animate/angular-animate.js"></script>
<script src="/angular-touch/angular-touch.js"></script>
<script src="/angular-ui-router/release/angular-ui-router.js"></script>
<!-- endinject-->
<!-- inject:files:js-->
<script src="/js/app.js"></script>
<!-- endinject-->
</body>
What's going on here? why is this not being loaded into the page?
I'm using gulp and gulp-webserver but that shouldn't be the cause.
<base href="http://localhost:9000">
was my problem. A difficult find, it was
<base href="localhost:9000">
before making the root directory obsolete!
Thanks for the help all!
I am trying to experiment with jQuery mobile, but can't seem to get started.
I have the following HMTL file hosted on a local server:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script type="text/javascript" src="http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.js"></script>
</head>
<body>
</body>
</html>
Which is causing
Javascript error: undefined SECUIRTY_ERR: DOM Exception 18
when accessed from my iPhone from http://192.168.1.1:8000/mobile.html
Did you link the CSS stylesheet file as well before the jquery script include tags?
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.1.1/jquery.mobile-1.1.1.min.css" />
<script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script src="http://code.jquery.com/mobile/1.1.1/jquery.mobile-1.1.1.min.js"></script>
Also, in order for the page to show, you must contain content into containers like this:
<body>
<div data-role='page'>
<div data-role='header'>
Header goes here
</div>
<div data-role='content'>
Content goes here
</div>
</div>
</body>