I have an API that a number of my clients use, using my own specifications and instructions for manipulating it from their own sites. It means that, unfortunately for me, changing the HTML code on their side is not an option. This is the general idea how their code looks and I need to make it still work after I do the changes I want:
<script src="player.js"></script>
<script>
console.log(player.someProperty);
</script>
I want to do the following changes:
rename player.js to player_2.0.js
create a small script which will be named player.js so the HTML5 at the top would work like it did before. Then player.js would load player_2.0.js dynamically.
The problem is when the following part of the code gets to be exectuded
<script>
console.log(player.someProperty);
</script>
player_2.0.js still isn't done loading, resulting player.someProperty to be undefined.
So my question is if I can manipulate or postpone the 'onload' event for player.js script until it's done loading player_2.0.js, or do anything that could get me accomplish that.
You're loading player_2.0.js asynchronously, therefore the code below is unable to access player.someProperty.
There is an old and ugly technique for synchronous loading, which uses Document.write()
In short:
<script type="text/javascript">
document.write('<script type="text/javascript" src="other.js"></script>');
</script>
<script type="text/javascript">
functionFromOther();
</script>
See document.createElement(“script”) synchronously for more details.
This is a very bad thing to do, since you will block the loading of other resources, and you can not inject this script dynamically without iframes.
I would rather use a technique called Friendly Iframes, but that will require some changes in your public API.
Related
We're using a webprogram that uses ajax and jquery and the like (Netsuite). I want to change something on a page and have tried to use document.ready and window.load to get an external script loaded on the page. I've tried to load the external script in the head and body.. but the contents aren't written. The external file looks for a specific div id and then prepends some code to that. It never works, because the page itself loads dynamically and the div I'm looking for loads when the rest of the page is done. So window.load, etc. never work...
At last I'm in the program itself that loads parts and pieces and am trying to simply write the external script file in there. Now this time the external file has a simple document.write in it, so it's straightforward. In other words, the script is in the middle of html code in the body of the page. (I know this is a terrible way of doing it, but I've got to try something to get this to work....)
According to firebug, it writes the external file where it should be (check!) and firebug shows me the contents of that file (check!), but ... it never 'writes' it onto the page...
The file just contains this:
document.write('<div id="shpblk" style="border:2px solid #ffa500;border-radius:7px;color:#000066;margin:5px;padding:5px;text-align:left;"><img border="0" width="12" height="12" src="/images/icons/store/icon_exclamation2c.gif">Hazardous conditions blahblah... Potential delays and disruptions can be anticipated.</div>');
What am I missing?
Edit: some more clarification is necessary...:
Situation: I have to be able to put a piece of html on the page every now and then that creates a message.
Environment: What I have is a page that loads a header and footer first (which are set up in separate files) and then it takes a second or so to load the rest of the page. From what I understand, this "rest of the page" is written in a certain code, similar to javascript/jquery.
What I CAN do is: edit the files for the header and footer and put javascript in there to make modifications to the rest of the page. I can access some of the files that contain parts and pieces of the "rest of the page", but this is a huge pile of spaghetti.
What I've tried:
Since I want to be flexible with the html that I need to put into the page, I preferably would like to create a piece of javascript or html or whatever on another site and have the "environment" pick up that code. I can do this with javascript or iframe. But since it's a secure area (https), I thought it would be best to use a javascript file instead of an iframe. So....
I created the javascript file and tried it out in a normal environment where I knew for sure it would work.. and it works like a charm. But when I tried this in the before mentioned "environment", I am running against a wall...
The javascript file has document.ready jquery statement in it and it would prepend the html div to an existing div on the page.
This way it would load the page and write the page.. easy as pie.
However.. since the header and footer load first (which includes the external script file), and then the rest of the page, SOMEHOW the div where the script checks for DOES NOT EXIST YET. So I tried window.load instead of document.ready. Same result.
Now, it WOULD appear ONLY when I refresh the page. So there may be a way to have it refresh the page, but I only want this as the absolute last attempt.
So then I tried to see if I could go around this by changing the script so that, instead of using a document.ready it would just do a simple javascript document.write statement.
Then I call the script in the middle of the body of the page (I put it in one of the files that load in the middle of the page). I know this is not something I would do normally, but wanted to try it out anyway. So.... I would have something like this:
<div id="block1">
<div id="block2">stuff here<div>
<script type="text/javascript" src="https://someotherdomain.com/include.js" ></script>
<div id="block3">stuff here<div>
<div id="block4">stuff here<div>
</div>
Now when I run this, I do not get any errors, but nothing is being done with the contents of that js file. In firebug it shows me the contents of that file though.. so I assume it's being read.
But I have no idea why it doesn't run.
Again.. back to 'normal' practices: I've tried window.load, because this would run the statement after the page loads, HOWEVER.. like I said before, I have the feeling it builds the contents of the (middle of the) page through this somehow and my script runs before this; it cannot find the div (block3) where it would prepend to. Whenever I stop running the page at my script, the div it's depending on doesn't exist yet...
I hope this made sense...
Solution
For the external script file to work as expected, OP will need to load it using an asynchronous script tag like this:
<script type="text/javascript" src="include.js" ></script>
Yet, the file contains a document.write() statement, which is generally something to avoid. A better alternative would be remove document.write() from the file and save it as a plain HTML file. This could then be safely loaded using using jQuery:
$("#include1").load("include.html");
( Requires adding a target DIV to the page where the content should load. )
DETAILS
The question doesn't tell us how the external file is included on the page. And without that information it's difficult to understand the problem or provide a solution ... which is probably why this question has gone unanswered.
Yet, let's assume the the script is being injected into the page on the client side using JavaScript or jQuery. And if that's true then it will fail if not done the correct way.
Let's look at some ways we might add the script to the page:
These script tags will all fail because the file contains a document.write statement and the script is loaded asynchronously.
<script type="text/javascript" src="include.js" async ></script>
<script type="text/javascript" src="include.js" defer ></script>
<script type="text/javascript" src="include.js" async defer ></script>
The browser does load the file, but reports:
Failed to execute 'write' on 'Document': It isn't possible to write
into a document from an asynchronously-loaded external script unless
it is explicitly opened.
This jQuery sort of works. It loads the script, but the document.write implicitly calls document.open, which erases the original content of the page. That's probably not what OP wants.
$.getScript('include.js');
This synchronous method works so long as the document.write is executed on load, i.e., is not inside function called later. So this is a possible solution for OP.
<script type="text/javascript" src="include.js" ></script>
I have those lines that should be blocked for some of pages.
So we don't have to use them.
<script src="/Scripts/jquery.validate.js"></script>
<script src="/Scripts/jquery.validate.unobtrusive.js"></script>
Is it possible to do somehow? I mean I don't have access to the Layout page and core code.
Can we do it using JavaScript/jQuery somehow?
Check this reference.
Removing a script element does not do anything. If you can somehow access a script element, it was executed a long time ago and removing it will have no effect.
Following will totally remove them from DOM only but not effect to code at all because already they are executed before. So be sure you don't need them at all to that page. Apply them before that script loads and after jquery load. like:
<script>
$('script[src="/Scripts/jquery.validate.js"],
script[src="/Scripts/jquery.validate.unobtrusive.js"]').remove();
</script>
<script src="/Scripts/jquery.validate.js"></script>
<script src="/Scripts/jquery.validate.unobtrusive.js"></script>
But I would prefer not to remove them, because they will harm other I believe.
Since you do not have access to the Layout, you really can't remove them before they're loaded and parsed by the user's browser.
If you need them for some pages and not others, there is no harm loading them for all pages since the browser should cache them on the first request and use the cache on each additional request. A little overhead on initial page load, but should be insignificant for future page loads
What are the differences between the two solutions below ?
In particular, is there a good reason to favour 2 over 1. (note: Please assume the name of the script to load is known. The question is just about if there is value in creating a minimal script to load a script in the given situation )
1 - Script At The Bottom
<html>
<body>
...
...
<script src='myScript.js'></script>
</body>
</html>
2 - Script at the bottom loads external script
<html>
<body>
...
...
<script>
// minimal script to load another script
var script = document.createElement('script');
script.src = 'myScript.js'
document.body.appendChild(script);
</script>
</body>
</html>
One important feature of the second one is that it allows the browser to finish parsing the page immediately, without waiting for the script to load. That's because the first example allows the script to use document.write to change the parsing state around the <script> tag, while the second one doesn't.
Now, we know that it's at the bottom of the page so that there isn't any important content left to parse, but this is still an important difference. It's not until parsing is done that the browser fires the popular DOMContentLoaded event. In method 1, the event fires after the script loads and executes. In method 2, the event fires before the script starts loading.
Here are some examples. In these demos, a DOMContentLoaded listener changes the background color to yellow. We try to load a script that takes 3 seconds to load.
http://jsfiddle.net/35ccs/
http://jsfiddle.net/VtwUV/
(edit: Maybe jsfiddle wasn't the best place to host these demos. It doesn't show the result until the slow-loading script loads. Be sure to click Run again once it loads, to see what happens.)
Pick the approach that's best for your application. If you know you need the script to run before DOMContentLoaded, go with method 1. Otherwise, method 2 is pretty good in most cases.
1. Script at the bottom
When you use a "synchronous" script tag, it will block the browser from rendering the page until the script is loaded and executed. This method has the following effects:
Regardless of where you put the script tag, the browser cannot fire DOMContentLoaded until the script is downloaded and executed.
Placing such a script tag at the bottom only ensures that the browsers has rendered all content before getting blocked by the script.
2. Script at the bottom loads external script
When you inject a script tag using JavaScript, it will create an "asynchronous" script tag that does not block the browser. This method has the following effects:
Regardless of where you put the JavaScript code that generates the script tag, the browser executes it as soon as it is available without blocking the page. The DOMContentLoaded fires when it should; irrespective of whether the script has downloaded/executed.
The second approach has the following advantages:
The script that injects a script tag can be placed anywhere including document head.
The script will not block the rendering.
DOMContentLoaded event does not wait for the script.
The second approach has the following disadvantages:
You cannot use document.write in such scripts. If you do, such statements might wipe the document clean.
Asynchronous execution does not mean that browser has finished parsing the page. Keep the script executes as soon as it is available clause in mind.
Execution order is not guaranteed. Example: If you load "library.js" and "use-library.js" using injected script tags, it is possible for "use-library.js" to load and execute before "library.js".
Having said all that, there is another method for loading scripts, with three variations:
<script src="myScript.js" async></script>
<script src="myScript.js" defer></script>
<script src="myScript.js" async defer></script>
Regarding Steve Souders's work: he proposed 6 techniques for loading scripts without blocking. The async and defer attributes introduced in HTML5 cover the Script DOM Element and Script Defer techniques and their browser support is more than enough for you to worry about the other techniques.
These two ways of initializing a script are basically the same, although theres no reason to use the second way if you can directly put in the result. However you can wrap the second example in a $(document).ready() method for example which would lead to sort of a lazy loading effect. This basically means that the page would load first and after the loading of the page is finished it would load the script. Or of course you can create a method which initializes a certain script this way. It's useful when you have a large script which is used only in some situations. This would prevent loading it unless you need it, thus decreasing the overall loading time.
This isn't a direct answer to your question, but it's good to know regardless.
The 2nd approach is sometimes used as a library fallback.
For example, you load jQuery from the Google CDN. But, if it were to fail for any reason, load jQuery from your own local copy.
Here's how the popular HTML5 Boilerplate recommends doing this:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="js/vendor/jquery-1.11.0.min.js"><\/script>')</script>
The first method means that the script tag is hardcoded in. The second method dynamically adds a script tag to the bottom of the page using JavaScript. The benefit of the second method is that you can add additional logic if needed to modify the script tag. Perhaps you might want to load a different script file based on culture, browser or some other factor you can determine in JavaScript. The second method also causes the JavaScript file to be loaded without blocking the loading of the rest of the web page. In method one the page will stop loading when it gets to the script tag, load the JavaScript file, then finish loading the rest of the page. Since this tag is at the bottom of your page it doesn't make too much of a difference.
If you are creating a Windows Store app using JavaScript then the first method is recommended as this will allow the app to bytecode cache the JavaScript file which will make it load up faster.
I've been trying to add JavaScript to my HTML/CSS, but been running around in circles.
My current set-up is where the html, CSS, and JavaScript files (2 files; my JavaScript code, and jQuery's code) are all separate, but linked to each other via the html page.
So here are my questions:
1) Do I put the link to the jQuery code within the html head? Or within my JavaScript code page?
2) Where does this code go? The html page, or my JavaScript page?
$(document).ready(function(){
//Code here
});
3) Above, by 'code here', they mean JavaScript code, right? Not my html code?
4) I've read about initializing JavaScript code at the bottom of an html page. From what I take though, I don't have to do that with jQuery's .ready function, right?
You should like to your JavaScript files either in the <head> or above the closing </body> tag.
The code can go anywhere really, but I would suggest an external JavaScript page.
Yes
This is correct.
When Javascript code is executing in your browser, all of your included Javascript files and any code you write in-between those "script" tags in the HTML document is going to be executed as though it were all part of one giant file (same namespace). So in some sense, it doesn't matter whether you write your code in the HTML document or whether you write it in an external file that you include - you're free to do either, and it will be executed the same. You can balance maintainability, reusability and convenience (think about what functions you write that you might want to reuse on other pages) and do whichever you feel is best.
To make this concrete - this is one valid way to write your Javascript, if you wanted to write the code inside your HTML file:
<html>
<head>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
$(document).ready(function(){
alert('Document Ready!');
});
</script>
</head>
<body>
...
Here's the intro at the jQuery site, for reference:
http://docs.jquery.com/Tutorials:Getting_Started_with_jQuery
Writing your Javascript code at the bottom of the HTML page was/is a technique for getting it to execute as soon as the document is loaded, which is unnecessary when using jQuery's '$(document).ready' (that's what it does - it abstracts the business of getting Javascript functions to execute on page load, and implements it in a cross-browser way).
See: Introducing $(document).ready() for more.
It doesn't really matter where you place your jQuery code. If you place it in the head tag, it'll automatically load everything. If you decide to place it all in an external JavaScript file, you need to link it with a <script type="text/javascript" src="my_file.js"></script> tag.
The 'code here' part is only for JavaScript. What the code is saying is that when the document is ready, run this function. The function can be whatever you like - whatever you put inside the function will run when the document is ready (i.e. when the webpage is called by the browser).
You don't need to insert it at the bottom of the HTML page - you can do it anywhere. People only insert it at the bottom to optimize their loading speed. It's nonessential.
$(document).ready(function(){
//Code here
});
goes in your javascript file. All javascript code that should be executed once the page has loaded goes where the //Code here comment is.
Perhaps a quick jQuery tutorial would be in order?
Or, you can put your script tag in the bottom of your body, and not have to use the $(document).ready() function.
Put in the head. This is the most stable way and it works. Some people may disagree and say it is slower, etc, but I have found this to always work.
Where you put your code is up to you. You can put in your head with a
<script>Code here</script>
or in a separate file and include it with
<script src="reftomyscript.js"></script>
Yes, put your javascript code in this, either in the head or in a separate file.
Yes, and see (1)
this is what im trying to do
<script type="text/javascript" src="resources/application.js"></script>
<script type="text/javascript" >
$(document).ready(createHeader());
$(document).ready(scriptSet());
</script>
id like to avoid having to separate the two, and while generally i see script links only inside the header the document.ready functions dont seem to work when put there. However, everything seems to work completely fine when placed at the end of the body, so would this cause any problems or is this fine?
Functionally, as long as you enclose your code inside a $(document).ready(function(){ }); and it comes after the jQuery file includes, it does not matter if it's in the head or the body. $(document).ready ensures that the DOM is fully loaded before any script is executed.
HOWEVER, putting all of your script includes and scripts at the bottom of the body is best for loading performance.
This article explains it nicely.
Example:
<body>
<!-- MY HTML CODE -->
<!-- START javascript -->
<script type="text/javascript" src="/javascript/jquery/jquery-1.6.2.min.js"></script>
<script type="text/javascript" src="/javascript/jquery/plugins/jquery.random_plugin.js"></script>
<script type="text/javascript" src="/javascript/jquery/plugins/jquery.random_plugin2.js"></script>
<script type="text/javascript" src="/javascript/some_other_scripts.js"></script>
<script type="text/javascript" language="JavaScript">
//<![CDATA[
$(document).ready(function(){
// my code
});
//]]>
</script>
<!-- END javascript -->
</body>
There is no problem with having script tags in the body. Just remember that the page is parsed top-down, so scripts have to be included before they are used.
You do realize that the functions you have put inside $(document).ready() are not going to wait for DOMContentLoaded to fire? You have to wrap them inside a function call (event handler) in order to avoid calling them instantly when they show up in the code. An anonymous function is usually just fine.
$(document).ready(function(){
createHeader();
scriptSet();
});
I have deployed a number of web applications, and haven't ever had a problem with the script being in the body tag. I like to place it at the end of the page so as not to impede download progress of the visible elements on the page. I believe that Google has also done this with some of their scripts (maybe Analytics?).
Like some of the others have said, make sure that you have your jQuery reference before the $(document).ready(); call. It's easy to slip past, and hard to troubleshoot :)
JMax
Nop, in fact its good for "performance" to put your scripts at the end of your HTML.
Still a good practice is to have all your javascript in another file and just set a header calling it, if posible even compressing the file.
Now, I would change that code for this
$(document).ready(function(){
createHeader();
scriptSet();
});
so you dont call $(document).ready twice :)
It typically does not matter if you put your script includes and blocks within your BODY element; they'll run perfectly fine in most cases. Some people believe it a bad practice, but it's not a wrong practice. It happens all the time.
However, I'd like to point out that it will not matter where you put a $.ready() function call, as long as it's after the jQuery include, as it will always run AFTER the DOM is ready (which will occur AFTER page load). So, in this case it doesn't make any difference.
Note the anonymous function in the function call. This passes a reference to $.ready() for the anonymous function, which allows it's function body to be executed at a later time, hence your functions will be called at a later time.
<script type="text/javascript">
$(document).ready(function(){
createHeader();
scriptSet();
});
</script>