Via jquery's $.getScript method, can you give the included script a DOM id?
So generated code should be:
<script type="text/javascript" id="xxxxxx" src="..."></script>
I know I could probably just document.write that line myself, but $.getScript must be there for a reason right? (cross browser compatibility, etc?)
I think this has maybe been answered/discussed before here: Why call $.getScript instead of using the <script> tag directly?.
getScript allows you to dynamically load a script in situations where it's either desirable to delay the loading of the script, in situations where you want to get a status callback on when the script has been loaded or in situations where you couldn't use a script tag.
getScript has some downsides in that it's subject to the same-origin policy whereas a script tag is not.
If have seen other web pages put an ID on a script tag (smugmug.com), but I've also seen that flagged as non-standard when testing standard's compliance. It seems to work and be used by others, but I'm guessing it isn't standard.
Related
I'm working on small .js which is going to be embedded on multiple websites, it will be loaded in a classic way - via script tag: <script src="myscript.js"></script> in sites body tag. I cannot add any more scripts to those sites.
I would like to track errors with error tracker such as Sentry, Rollup or HoneyBadger. However, all of them require being loaded with another script tag, most preferred before everything else.
Note: Those services need to load before everything else to catch errors property.
As I cannot add another script tag in the site's code, I need to execute their code inside my script, but before my actual script code.
I tried taking the content of HoneyBadger javascript library and putting it directly inside my file - it worked, however, I feel like it's terrible practice, as their code is written with modern browsers in mind, and mine supports older ones.
Is there any good way in my situation to load their .js externally?
I don't think that would work because of the way honeybadger.js v0.5 parses the script tag to get those attributes--it looks for the script tag in the dom when it's loaded.
Also, we've moved away from using the data- attributes in honeybadger.js v1.0, which was just released. In that version, you must use Honeybadger.configure to set your API key. Take a look at the new docs here:
https://docs.honeybadger.io/lib/javascript/integration/browser.html
I'd recommend going with v1.0, and using Honeybadger.configure for the configuration.
I'm using polyfill.io to polyfill Promise and fetch for older clients. On their website they recommend using a script loader or their callback to make sure the script has loaded completely before running the modern code:
We recommend the use of the async and defer attributes on
tags that load from the polyfill service, but loading from us in a
non-blocking way means you can't know for certain whether your own
code will execute before or after the polyfills are done loading.
To make sure the polyfills are present before you try to run your own
code, you can attach an onload handler to the https://cdn.polyfill.io
script tag, use a more sophisticated script loader or simply use our
callback argument to evaluate a global callback when the polyfills are
loaded:
However, shouldn't setting defer on both scripts already guarantee that they are loaded async but still in the order in which they appear in the document (unless the browser doesn't support defer)?
<script src="https://cdn.polyfill.io/v2/polyfill.min.js" defer></script>
<script src="modernscript.js" defer></script>
According to MDN documentation defer attribute just defines a point of page loading time when script loading will occur.
From documentation that you've citated it can be seen:
To make sure the polyfills are present before you try to run your own
code, you can attach an onload handler to the https://cdn.polyfill.io
script tag
Since (as pointed into comments to this answer) it can't be clearly seen if defer scripts will be executed (1, 2) and taking in mind possible browser implementation differences - it may be not the best idea to rely on such behavior.
So better way would be either:
to use some script loader (RequireJS for example)
to add proposed onload handler to first <script> tag and create dynamic <script> tag for loading your code inside this handler
to bundle your code together with Promise polyfill (manually or using bundler like webpack) and load as single bundle.
UPDATE: As pointed by #PeterHerdenborg in comment - MDN document now clearly states that:
Scripts with the defer attribute will execute in the order in which they appear in the document.
What's the best way to dynamically load HTML content and inject it in the page (when the HTML contains both <script src="..." /> tags and function calls to those scripts)?
Consider this approach (for simplicity, I will consider jQuery):
<script>
$.ajax({
url: 'http://...',
success: function(html) {
$("body").append(html);
}
});
</script>
Let's assume that the returned html contains something as such:
<script src="some_script.js"></script>
<script>
some_function(); // function defined in some_script.js
</script>
Since some_function() is defined in some_script.js it will be available only after some_script.js was loaded but (usually) it will be executed before some_script.js will be loaded (thus causing an error).
Obviously, there are some solutions to overcome this issue, but what is the best practice in this case? Should libraries such as RequireJS be used instead?
The example above is a result of the pattern I use: I have a component which I will load only when it's going to be used (at that point I make an Ajax call to retrieve both the HTML and the required scripts). Still, it can happen that many scripts are required and it's easier to write them as a set of tags in the HTML template rather than loading them through JavaScript (this is also preferred as the script URL may be generated inside the application so a plain JS script may not be aware of the absolute script URL).
Actually Safari and Internet Explorer (and most likely others) won't execute <script>'s that are injected through Ajax as a security measure.
What I can recommended is that when you need a library of considerable size (yet isn't required for actual use of your web application), is to rather load the .js-file containing the library into your document after which you can use all properties and methods defined in the library. Attach a callback listener to your script loader and execute all code in the callback, not in the external .js file itself.
Despite the continued adoption of the script element's async attribute, there is continued advice to place script at the bottom of the document without the async attribute. If document.write is avoided, are there any possible pitfalls when using async?
For example, if I load a script that I wrap in jQuery's $(document).ready(...), is there any chance that I might experience any negative effects when adding the async attribute? Can I reliably specify async on all such scripts?
If your scripts rely on being run in a particular order you cannot use async. This typically means that they rely on each other.
A recent example of this that happened to me was using Google's prettyprint syntax highlighting library. You include the library and then make a call to prettyPrint() to apply the syntax highlighting to relevant blocks.
<script src='http://cdnjs.cloudflare.com/ajax/libs/prettify/r298/prettify.js' type='text/javascript'></script>
<script type='text/javascript'>prettyPrint();</script>
So if all your scripts are wrapped in a $(document).ready then they are most likely perfectly fine to go with async. The question you should be asking though is whether you can combine all your files so you only need to make one request.
The defer attribute is similar to async but waits until the HTML is parsed and then runs the scripts in the same order that they appear in your HTML file. This would work in the above situation provided the call the prettyPrint() was external instead of inline as I don't believe it applies to inline scripts.
I would like to synchronously include a JavaScript file from a different domain via code. This means that using a synchronous XMLHttpRequest will not work. I also want to avoid document.write because my code will be executed when the document is fully loaded. Is this even possible? Does any of the existing JavaScript libraries support that feature?
Basically I want this to work:
<script type="text/javascript">
$(document).ready(function() {
load("path_to_jQuery_UI_from_another_domain");
console.log(jQuery.ui.version); //outputs the version of jQuery UI
});
</script>
EDIT:
My idea is to create a jQuery plugin which loads its JavaScript files based on the enabled features. jQuery plugins can be initialized at any time which means no document.write. It is perfectly fine to load the JavaScript files asynchronously but people expect their plugins to be fully initialized after calling $("selector").something();. Hence the need of synchronous JavaScript loading without document.write. I guess I just want too much.
The only way to synchonously load files is to document.write a script tag into your page. This is generally considered a bad practice. There is probably a better way to do what you actually want, but, in the spirit of transparency:
document.write('<script src="http://otherdomain.com/script.js"></'+'script>')
should do the trick. You have to escape the closing script tag so the parser doesn't close the script tag that you wrote.
**Note that you can't dynamically load scripts that contain a document.write
You should be able to use .getScript()
Edit: Cross-domain requests are always loaded asynchronously in jQuery.
A great library called YepNope exists for loading javascript dependencies from any location - developed by a member of the yayQuery podcast. It can be found here: http://yepnopejs.com/
It's not possible to synchronously execute a script at a URL. Note further that synchronous anything, when networks (or even file systems!) are involved is a Bad Idea. Someone, sometime, somewhere will be on a slow system, or a slow network, or both, and suddenly you've just hung their UI in the process.
Synchronous is bad. Asynchronous with callbacks is good.
Note that, as a worst-case hack, you could overwrite $ with your own function, which returned an object with just the right properties, and you could semi-lazily evaluate all actual calls. This of course breaks if you start relying on immediate execution of the calls, or on their execution being intermingled with the evaluation of arguments, but in the worst case it's not completely implausible.
LABjs.js, is nice library. I used it works well.
http://labjs.com/