I have an external JavaScript file linked by blogger. I want to change valuess in it. (css values assigned with JavaScript)
Is it possible to run the same code in head or body with different values assigned with JavaScript?
For example, CSS gives least priority to the external CSS stylesheets and assigns the properties which are given inside the file.
Does JavaScript have any priority system like that?
It is not priority, but execution order. Javascript is not involved in any sort of prioritising or doesn't have anything like specificity in CSS to even have a need for it.
Javascript code is executed in the order it is included in the HTML document irrespective of whether it is inline or external js, although events makes things a bit more complicated, we can schedule code to be run later on certain events like 'load' event of window. So it is easy to make sure your code is run after theirs, but if they are say changing style from onload event handler, then you have to add your code to the same event itself. (Order of event handlers are ensured in DOM3 at least in specification)
But, have you tried !important in CSS, it can override inline styles and comes handy in some scenarios like this. But if you are able to remove the styles using JavaScript well and good.
Javascript code is executed at the point of inclusion.
Html parser
parse tags
finds javascript
(optional)download javascript
stop parsing html
parse js
excecute js
resume parsing html
finds javascript
(optional)download javascript
stop parsing html
parse js
excecute js
resume parsing html
etc
Watch out for things like code that hooks itself to domready events, to only be fired when the document is done loading or other events, then it comes down to in which order they were registered.
There are also things like defer and async, which will make it load/execute in parralel to parsing(details and supporr vary per browser).
But in most scenarios without heavily modified templates in google blogs the sequesce i laid out will happen
JS is executed as soon as it is loaded, so putting your script after theirs (either linking to an external file after, or putting it inline), it will be able to change things in the first script, but it may have executed by then.
You might be able to override parts of it, if their script wait for something before running, like the DOM ready event
if you have tow function with same name, one in head and another one in an external .js file and both of them write a value in <a>, the result will be from the internal one, let's look at an example
<html>
<head>
<script src="myscripts.js"></script>
<script type="text/javascript">
function test(){
document.getElementById("tester").innerHTML="Internal";
}
</script>
</head>
<body onload="test()">
<a id="tester"></a>
</div>
</body>
</html>
-------------------------------------
in myscripts.js
function test(){
document.getElementById("tester").innerHTML="external";
}
-------------------------------------
when the page run it shows:
Internal
Related
I'm working on a piece of code that glues Sammy JS (router) and Knockout JS together.
So, this is my problem,
<script id="MyTemplate" type="text/html">
// [HTML Containing a script link (Encoded HTML)]
</script>`
I use jQuery to create an instance of this template :
var TInstance = $($("#MyTemplate").text())
Then, I want to inject the new html TInstance into my <body> or an other existing tag
$("body").html(TInstance)
All Good, now I want to do ko.applyBindings to bind the new TInstance to an ViewModel and it works.
The problem I have is: when I have an <script src="..." /> inside TInstance,
I want to wait until that script is downloaded and parsed, then do ko.applyBindings.
So I tried $(TInstance).ready(() => {ko.applyBindings(...)}), It works the first time the page loaded, but if I redo the whole process, swapping in a new TInstance the ready handler on the new TInstance won't fire.
What should I do?
Ok, this answer will not be "copy & paste and play", it will require some tweaking from you, but i think you will get the concept and you will manage.
Without adding a dependency management module, and without restructuring you code ( usually plain script tags don't get injected dynamically along with html for the same reason you have troubles right now. Its a good idea to load script tags with html for the first page load, but any content added later on, especially if some flow is required, will need programmatic handling, hence the need for module management frameworks for larger projects)
One way to do it is to stop your code execution flow and poll the enviroment to see if your script is loaded. i.e:
var demoInterval = setInterval(function(){
if(myCondition){
clearInterval(demoInterval );
functionThatStartsTheRestOfTheLogicFlow(); // this could apply bindings etc etc
}
},50);
Now for example, if you where loading jQuery with the script tag your condition could be
typeof($) !== 'undefined'
It would poll every 50 milliseconds until $ is defined, and then it would call a function to clear the polling and continue your logic flow.
In your case the condition could be the definition of a function/model, a flag-like variable that your custom js file can set and the polling would expect to read at some point etc etc.
Even better would be to remove the script tag from the html and load the script dynamically by javascript so that you can utilize the onload event of the specific script that is required, you can read an example here. Programatically controlling these cases is much easier for the developer.
Hope this helps
have resolved the problem by using a 0ms setTimeout call
setTimeout(() => { /*all new resources have been loaded and the html rendered*/ });
Help: https://eager.io/blog/how-to-decide-when-your-code-should-run/
So I'm using jquery along with some plugins I wrote.
I do all the initialization in a $(document).ready(function(){}) block however this is executed when the whole DOM has been loaded and is ready to be used.
However that would take long eg. when there is a server load. Or maybe the user clicks a button that has been loaded while the rest of the page hasn't loaded yet (and thus document.ready() hasn't been executed yet) in which case it would do nothing.
So, what if I want a code to be executed right after the related part of the page has been loaded instead of waiting for the WHOLE page to be loaded?
I know placing inline code right after the html that this js operates on would do the trick but what if that code uses a library like jQuery that hasn't been loaded yet?
I know placing inline code right after the html that this js operates on would do the trick but what if that code uses a library like jQuery that hasn't been loaded yet?
That would be the only way. The HTML is parsed from top to bottom. So you can expect every script you included to be accesible after you included it.
Your page should still work without JavaScript anyway, so a user clicking a button extremely fast will just temporarily have a somewhat degraded experience.
That being said, the DOM is basically ready when the HTML document all scripts are loaded. Since you cannot execute meaningful JavaScript before the JavaScript code is loaded (duh), I'd have a close look at page performance. Sending an HTML document and 2,3 JavaScript files should not be slow.
You could also use the old-style inline event handlers, like <button onclick="registerButtonClickEvent()">. However, this would introduce a complex, potentially buggy and hardly testable layer of temporary event holding.
If your <script src="jquery-whatever.js> line precedes the first clickable element in your HTML, it is guaranteed that the jquery library will be loaded and run before the user has anything useful to click on.
Just don't add async or defer attributes to the script element.
The onload event isn't triggered from all html elements, so you're forced to wait for window load. It doesn't matter where you load jQuery since it will have to wait for document to be ready. That total time required to load jQuery plus the rest of the document will be thet same.
I see that Javascript code is normally in heading part of HTML code.
<head>
<script type="text/javascript" language="javascript" src="core.js"></script>
...
</head>
Is it OK to put the Javascript code in a body part of HTML code? I tested it, but it seems to work.
<body>
<script type="text/javascript" language="javascript" src="core.js"></script>
...
</body>
If so, why the examples of Javascript books put the javascript code in heading part?
If not, what's the difference between putting the javascript code in body/heading part?
Not only is it OK, it's actually better, since it lets the content come first.
If your viewers have a slow (eg, mobile) connection, it's better to send the actual content first, so that they can read it while the browser downloads the Javascript.
All the people saying it is better only applies if you are talking about at the bottom of the page (and that is an up for debate thing) from a code quality point of view, it is NOT ok to sprinkle script tags through your html. All references to javascript should be in a single place on the page, either the head (where they should be), or the very bottom (as a perf optimization)
Edit:
Basically, a web page is made up of 3 pieces; style (css), structure (html), and behavior (javascript). These pieces are all very distinct, so it makes sense to keep them as separate as possible. That way if you need to change some javascript, it is all in one place. If it is sprinkled through the file, it becomes much more difficult to find the code you are looking for, and that code basically becomes noise when you are just looking at structure.
It is the same arguments as why not sprinkle db access code all over your page. It has nothing to do with technical reasons, purely an architectural/design decision. Code that does different things should be kept separate for readability, maintainability, and by extension, refactorability (not sure if that last one is actually a word...)
You can do it, and people often do.
For example, people like to put their script tags just before the closing </body> to make web pages render quicker.
Also, if you do a script block after an element is created, you don't need to wait for DOM ready.
Be warned though, don't add, or remove an element from an unclosed ancestor in the markup tree (not including the script block's immediate parent element), or you will get the dreaded Operation Aborted error in IE.
Just something to add on:
I have preference of putting Javascript file right before </body>. My reasons being that:
Content can load and be shown first. If you load huge Javascript files first, which most are meaningless until the page is loaded, the user won't be able to see anything until the JS files are loaded.
Most Javascript code require to work with the UI can only run after the UI has been loaded. Placing the codes at the end of the html file reduces the need to use the onload event handler.
It is very bad habit to place Javascript snippets all over the HTML file. Placing all at the back of the HTML file allows you to manage your Javascript more efficiently.
It is legal according to the spec.
Most examples use them in the header as the headers come first and the browser will be able to parse the reference and download the JS files faster.
Additionally, these are links and are not part of the display, so traditionally, put in the header.
It is perfectly legal but there seem to be some differing opinions about it. Those who say to put all the javascript references in the head argue that the script is downloaded before the rest of the page become visible and dependent on it. So your user will not see an object on screen, attempt to interact with it and get an error because the javascript code is not yet loaded.
On the other hand, the argument goes that it takes longer to load all the script before the user sees the page and that can have a negative impact on perceived speed of your site.
JavaScripts inside body will be executed immediately while the page loads into the browser
Placing javascript at the end of the body will defer javascript load (ie: the page will render faster), but remember that any javascript function used for an event should be loaded before the event declaration, it is mainly because users may be able to fire an event before the page is completely loaded (so before the function is loaded)!
I used to put it in the head, then I've heard that it takes longer for the page to load so I started placing the scripts at the very bottom. However, I found out the most 'clean' way to do it is to place it in the head BUT you place the script inside a document.ready function. This way you have the best of both worlds. It is cleaner because it is in the head and it is not loaded before the content has been loaded, so there aren't any problems performance wise either.
With jQuery for instance, you can do it like this:
$(document).ready(function() {
alert('test');
});
The alert will only popup when the page has been fully loaded, even though the script is in the head.
I am inspecting some interesting behaviors of browser, I don't know it's in standard or not. If I put everythin inside <head></head>, the browser will only begin to render the page after all the resouces in head is retrieved.
So I am thinking that put as little as possible things into head is one of the important website optimization techniques, is it right? My question is:
If I put script/css in body or other parts of the html, how can I know that script has been loaded successfully so that I will not be calling a undefined function?
To answer shortly: You should really put the script tags at the very end of the <body> element. Style tags should be put in <head>, otherwise the document will have to be re-rendered every time a new stylesheet is loaded, so you really want them all to be loaded before the document starts rendering.
As for using javascript code that is not loaded yet. Of course you shouldn't bind any events or anything too early, and shouldn't have inline javascript in the page ideally. The solution can be to just use the window onload event to do your initialization, if you really must have inline code in the page.
My friend read an article which mentioned that moving all JavaScript files to the end of the closing body tag (</body>), will improve the performance of a web page.
I have moved all JS files to the end except the JQuery and the JS files which are attaching event to an element on page, like below;
$(document).ready(function(){
//submit data
$("#create_video").click(function(){ //... });
});
but he's saying to move the jQuery library file to the end of body tag.
I don't think it is possible, because I am attaching many events to page elements on load using jQuery selectors, and to use jQuery selectors it is must to load jQuery library first.
Is it possible to move JQuery library file to the end of page right before closing body tag (</body>) ??
Thanks
It's standard practice to move all your js includes to the bottom of your page. This is because when a browser loads script, it does not spawn a new thread to do so, so basically the browser will wait until it has loaded the script before it proceeds to the next line.
What this means for your users is that they will see a blank screen. Much better to have them see the full(ish) page as then it doesn't look like it has stalled.
The $(document).ready function says not to run until the DOM has finished being instantiated - so moving it to after body is okay so long as the JQuery library is loaded first. Unconventional and some assumptions may not be correct anymore but okay.
Just take in account that the jQuery JavaScript file must be loaded before any call to the $(...) function.
Use a "Dom Ready Queue" to collect functions to be executed once jQuery is loaded and the DOM is ready.
Example:
<html>
<head>
<script type="text/javascript">
var domReadyQueue = [];
</script>
</head>
<body>
...
<div class="foo"></div>
<script type="text/javascript">
domReadyQueue.push(function($){
$('.foo').doSomething();
})
</script>
...
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script type="text/javascript">
jQuery(function(){
while (domReadyQueue.length) {
domReadyQueue.shift()(jQuery);
}
});
</script>
</body>
</html>
The reason that article asked you to move scripts to the bottom, is to allow other artifacts to get downloaded first. (css & images, which will speed up apparent rendering times)
This is because HTTP 1.1 recommends only downloading 2 items per hostname. And you would definitely want your css file to be one of the first files downloaded, rather than javascript which could make the site appear to render slower (just by the fact that the browser hasn't got the css file yet and isn't sure what it should do with the html)
But if you used google to host your jQuery then that would download in parallel and negates any reason for moving it to the bottom of your pages.
Alternatively, you could set up a second hostname to host static content (such as css/scripts/images).
But google have already done the hard work for you, so it makes sense to use it if it suits. :-)
Q - Why do I often see JavaScript
written/included before the closing
body element in an (x)HTML document?
A - DOM elements can not be accessed
by JavaScript until the browser has
loaded the HTML elements into the DOM.
By placing JavaScript at the end of an
(x)HTML document (before the closing
body element), you will ensure that
the script is called as soon as the
DOM is constructed/loaded and ready
for manipulation. An advantage of this
approach is that JavaScript code is
executed right after the DOM is
constructed and possibly before the
onload event would fire.
JavaScript beginners get tripped up by
this constantly by placing code that
manipulates the DOM in the header
element of an (x)HTML document. This
causes an error because the DOM has
not yet been constructed and thus is
not yet accessible to JavaScript that
traverses/manipulates the DOM.
From JavaScript Execution & Onload Techniques in Web Browsers
Use unobtrusive javascript (adding event listeners to elements instead of onclik ="..." etc).
Put all your .js files at the bottom of the body tag, with the main library (jQuery in this case) placed first, and everything will be fine. You can use a bundler like bundle fu
You will see a big performance boost of loading your page.