I am trying to make a plugging using JS.
I have the following code :
var fileref = document.createElement('script');
fileref.src = "js/index.js";
document.documentElement.appendChild(fileref);
I can verify that the code loads across domain however it doesn't always execute. Even if I set it before </head>
Sometimes it does but sometimes it just doesn't. Any ideas on what I could be doing wrong?
The JavaScript is sometimes running before the document.documentElement exists. So when it goes to append the new script element, it fails. The inconsistency ("sometimes it does but sometimes it just doesn't") is due to the page rendering at ever-so-slightly different speeds.
Update:
Put this in your <head>:
<script type="text/javascript">
(function () {
var scrpt = document.createElement('script');
scrpt.type = 'text/javascript';
scrpt.async = true;
scrpt.src = 'js/index.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(scrpt, s);
})();
</script>
Related
I am adding ZohosalesIQ to the CookieBot Prior Consent widget on w WP install.
This script given by zoho is
<script type="text/javascript" data-cookieconsent="statistics">
var $zoho = [];
var $zoho = $zoho || {};
$zoho.salesiq = $zoho.salesiq || {
widgetcode: "1c636a8a8d8e3410b7e579760898b7768f3cb213adb21970788a3891735df801800b6e4a1385c37b0f792b9ee54ce",
values: {},
ready: function() {}
};
var d = document;
s = d.createElement("script");
s.type = "text/javascript";
s.id = "zsiqscript";
s.defer = true;
s.src = "https://salesiq.zoho.eu/widget";
t = d.getElementsByTagName("script")[0];
t.parentNode.insertBefore(s, t);
d.write("<div id='zsiqwidget'></div>");
</script>
I am supposed to be adding <script type="text/plain" data-cookieconsent="statistics">
to the script tag to enable prior consent on cookies created by this script however, when I add this it breaks and fails to load.
Console is empty but the page renders as a white page after pre-load. When I add the code with the jaavscript type tag, it works fine.
I've tried popping itto a call back function but no joy :(
Any pointers would be great.
If the script tag is using the deprecated JavaScript function “document.write” it might cause the problem you have described above because using this function the script is loaded synchronously and it will then clear the window content (generates blank page).
To prevent this issue please make sure that the script is loaded asynchronously since the Cookiebot triggers all scripts asynchronously (i.e. to wait for the visitor’s consent) in order to work properly.
You need rewrite it to use a different approach e.g. “document.write = function(node) {document.body.insertAdjacentHTML(‘beforeend’, node);}”
We have a custom searchbar on our website and I noticed that sometimes (9/10 times) the JS will throw this error, which forces the content that you searched for to not render
www.googleapis.com/customsearch/v1element?key=AIzaSyCVAXiUzRYsML1Pv6RwSG1gu…oogle.com&callback=google.search.Search.apiary####&nocache=1446053383742:2
Uncaught TypeError: google.search.Search.apiary#### is not a function
Search page when error is thrown:
Search page with error truncated/resolved
But if I were to refresh, or research, this error is trumped and will render all of my searches. After looking through the file, I found out the google.search.Search.apiary#### that they are referring to is only mentioned once. So I believe that this error is truncating the entire file when it does show up. What could be causing this, what would be some options for fixing it?
Alright, I stumbled upon an answer:-
After doing some more research, I found that this user on Google Forums also has the same issue.
To put it simply, the way it works is you use a <script> to generate your searchbar.
You have this function + html element for your search bar
<script>
(function() {
var cx = '###';
var gcse = document.createElement('script');
gcse.type = 'text/javascript';
gcse.async = true;
gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') +
'//cse.google.com/cse.js?cx=' + cx;
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(gcse, s);
})();
</script>
<gcse:searchbox-only resultsUrl="/search-results"></gcse:searchbox-only>
So we generated the bar in our <div class="header"> which is a HAML element, as a part of a template. So it was always loaded within every header. Since we have 10 pages, this same script was generated 1 time per page.
Our Google CSE is made to search and then redirect to the url /search-results where it generates the results.
To generate the results, you needed this function and HTML
<script>
(function() {
var cx = '###';
var gcse = document.createElement('script');
gcse.type = 'text/javascript';
gcse.async = true;
gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') +
'//cse.google.com/cse.js?cx=' + cx;
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(gcse, s);
})();
</script>
Which is the same as the one being loaded in our Header.
With this set up, the results page would call that <script> twice when loading in, and cause the JS to break. So after removing the <script> loading the results, it stopped throwing the error.
To put it brief, just make sure you aren't calling the same function twice on your results page, and it should clear up the Uncaught TypeError.
Don't. Repeat. Yourself
--ether
In my case I accidentally had the form and script for the Google Custom Search repeated twice on the same page. Once the second lot was removed it stopped giving the error.
<script type="text/javascript">
(function() {
var po = document.createElement("script"); po.type = "text/javascript"; po.async = true;
po.src = "https://apis.google.com/js/plusone.js?publisherid=112917099095075652323";
var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(po, s);
})();
</script>
<script async src="https://apis.google.com/js/plusone.js?publisherid=112917099095075652323"></script>
Id like to start switching over scripts that are loaded from third parties into the latter syntax. Curious as if the type attribute is even needed. Looking to load all these scripts asynchronously. Thoughts?
In your first part of codes, you are actually just creating the same HTTP tag. I think it should be checkable by Chrome or FireFox F12 since the codes there (Chrome F12 - Elements) are processed.
What am I trying to do? In an attempt to speed up my website I am loading non-essential javascript after the browser load event. (So the JS files are not render blocking) This is currently functioning correctly.
What is the problem? The problem is sometimes the non-essential javascript depends on other libraries and plus those libraries need to load first.
What have I tried to do to fix the problem? In an attempt to fix the problem I have added a delay event to library dependent javascript. While this works sometimes, the load times of a JS file varies between refreshes and at times can load before the library even with a delay.
QUESTION: Does anyone know of a better way for me the load JS files only after the first JS file has loaded? (See code below)
<script type="text/javascript">
function downloadJSAtOnload() {
var element = document.createElement("script");
var element2 = document.createElement("script");
var delay=40;
element.src = "http://119.9.25.149/sites/all/themes/bootstrap/bootstrap_nova/js/highcharts.js";
element2.src = "http://119.9.25.149/sites/all/themes/bootstrap/bootstrap_nova/js/future-plastic.js";
document.body.appendChild(element);
setTimeout(function(){
document.body.appendChild(element2);
},delay);
}
if (window.addEventListener)
window.addEventListener("load", downloadJSAtOnload, false);
else if (window.attachEvent)
window.attachEvent("onload", downloadJSAtOnload);
else window.onload = downloadJSAtOnload;
</script>
As you can see from the above, I am trying to load the highcharts js file before I load the future-plastic file.
You're not the first to have this problem, thankfully. There's a lot of difficult solutions around this problem, including using a module loader as suggested in the comment (which I agree is the best long term solution, because they account for more browsers and flexibility, but it's a lot to learn to solve one small problem).
The place to start learning about this problem and the ways to tackle it are all over the web. This is a pretty good resource: http://www.html5rocks.com/en/tutorials/speed/script-loading/
You may want to try defer if you don't have to support Opera Mini or IE9. Or, you can load sync and execute as it loads- their examples is this:
[
'//other-domain.com/1.js',
'2.js'
].forEach(function(src) {
var script = document.createElement('script');
script.src = src;
script.async = false;
document.head.appendChild(script);
});
The reason why this might work (different browser implement this differently) is because the default is to load dynamically generated script tags are set to async by default, if you set it to false: "they’re executed outside of document parsing, so rendering isn’t blocked while they’re downloaded"
You should use ScriptElement.onload:
var pre = onload;
onload = function(){
if(pre)pre();
var doc = document, bod = doc.body;
function C(t){
return doc.createElement(t);
}
function downloadJSAtOnload(){
var s = C('script'), ns = C('script'), h = doc.getElementsByTagName('head')[0];
var u = 'http://119.9.25.149/sites/all/themes/bootstrap/bootstrap_nova/js/';
s.type = ns.type = 'text/javascript'; s.src = u+'highcharts.js'; h.appendChild(s);
s.onload = function(){
ns.src = u+'future-plastic.js'; h.appendChild(ns);
}
}
downloadJSAtOnload();
}
Note: The first onload is window.onload, since window is implicit.
On a site we run a basic Twitter button, which works fine 90% of the time. Occasionaly the initialization fails with the error: Uncaught TypeError: Cannot call method 'load' of undefined.
This is the script that does the Twitter initialization:
<script type="text/javascript">
//<![CDATA[
(function() {
var twitterScriptTag = document.createElement('script');
twitterScriptTag.type = 'text/javascript';
twitterScriptTag.async = true;
twitterScriptTag.src = document.location.protocol + '//platform.twitter.com/widgets.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(twitterScriptTag, s);
})();
//]]>
</script>
Can anybody give a hint why this happens?
UPDATE: After setting async = false I get the following error:
'twttr.widgets' is Null or no object
SOLUTION: I load some stuff via AJAX on $(document).ready(). Problem is, when the AJAX content loads faster than the Twitter initialization is done it fails.