Why getScript does not work from an external script? - javascript

I am trying to get the google recaptcha script to get loaded with
$.getScript("https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit");
If I put it into the <script> tags and inline the webpage, it loades the captcha correctly, while If I include the getScript, inside an external .js file still hosted on the same domain the javascript from recaptcha is not loaded. Is this a problem with the script itself or with getScript?

The script you're calling is rendered when the 'onload' event fires.
(function() {
if (!window['___grecaptcha_cfg']) {
window['___grecaptcha_cfg'] = {};
};
if (!window['___grecaptcha_cfg']['render']) {
// If the render time isn't set, set it to (window) onload //
window['___grecaptcha_cfg']['render'] = 'onload';
};
window['__google_recaptcha_client'] = true;
var po = document.createElement('script');
po.type = 'text/javascript';
po.async = true;po.src = 'https://www.gstatic.com/recaptcha/api2/r20150826120751/recaptcha__en.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(po, s);
})();
I'm not familiar with the google Captcha specs, but I think this can work. You just need to find the script url that executes in context. Hint: the URL probably won't say 'onload=onloadCallback' in it.

Related

Need to load Javascript lib's and support files dynamically by another javascript file

My task: If I include a single javascript file (vlib.js) it should automatically include all supporting JS lib in to landing document.
What I did: I have a string array which contains all list of JS file paths to append. I have a function declared in Vlib.js as a global function. It appends all the files correctly, but the problem is I'm getting some errors!
The appending starts with some library files like angular.min,... jquery.min.. bootstrap.. and my custom JS files. Even though I append them in the correct order I'm getting errors like angular not defined and others errors which shouldn't have come if it is loaded in correct order. My team mate says even if put it in correct order it might finish load randomly like angular related files loading before angular.min. So is there any way I can load a script and then move on to appending to other js only when the first one is loaded? I have to do this using native JS.
im using this code
function populateJsDynamicX() {
for (var index = 0; index < jsSet.length; index++) {
source = jsSet[index];
if (jsSet[index].includes('.js')) {
console.log(source);
var scriptTag = document.createElement('script'), // create a script tag
firstScriptTag = document.getElementById('viewerHandle'); // find the first script tag in the document
scriptTag.src = source; // set the source of the script to your script
scriptTag.type = "text/javascript";
//firstScriptTag.parentNode.insertBefore(scriptTag, firstScriptTag); // append the script to the DOM
document.head.appendChild(scriptTag);
(document, 'script');
} else {
console.log(source);
var scriptTag = document.createElement('link'), // create a script tag
firstScriptTag = document.getElementById('viewerHandle'); // find the first script tag in the document
scriptTag.href = source; // set the source of the script to your script
scriptTag.type = "text/css";
scriptTag.rel = "stylesheet";
//firstScriptTag.parentNode.insertBefore(scriptTag, firstScriptTag); // append the script to the DOM
document.head.appendChild(scriptTag);
(document, 'script');
}
}
console.log(jsSet.length);
}
Some other guys said $.getScript will get the job done, but I want to do this by native JS, can u guys tell me where I'm wrong?
I get error like this:

Chrome console behaviour

I am injecting through console jquery:
var jq = document.createElement('script');
jq.src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js";
document.getElementsByTagName('head')[0].appendChild(jq);
jQuery.noConflict();
Then I am using some jquery command
$('.first').position()
document.elementFromPoint(xPosition, yPosition).click();
After emulating click page in browser reloading. And than $('.first') allways return []; But on the page there are a lot of tags with class 'first'. It seems that console waiting for updating? Or what?
The appendChild is loading a script element into the DOM, that script tag then goes and downloads the file set to its src property. But this download takes time. It's asynchronous.
var jq = document.createElement('script');
jq.src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js";
document.getElementsByTagName('head')[0].appendChild(jq);
So when you attempt to access jQuery immediately after in your javascript, that file hasn't been downloaded yet. Imagine that the file took an hour to download. You'd need to wait to be notified that the file had finished downloading before using that code. There's a number of ways to think about this, like using an interval to check if the global variable is there, but I think the simplest is just to use an onload event.
var jq = document.createElement('script');
jq.src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js";
jq.onload = function(){
//do stuff using jquery
}
document.getElementsByTagName('head')[0].appendChild(jq);

Javascript to dynamically insert plugins and code

I'm trying to provide my users with a single <script> tag that will add some plugins to the page and execute some javascript code. I'm providing my users with a code snippet like this, and asking them to add it anywhere within the body of their website:
<script type="text/javascript" src="//my-domain/code?s=1a2b3c4d&t=faq&cb=1408412749" async></script>
In the response, I have the following Javascript code:
//add jquery to page
var script = document.createElement('script');
script.src = 'http://my-domain/assets/js/jquery.min.js';
document.body.appendChild(script);
//move jquery to our own namespace
var script = document.createElement('script');
script.innerText = "var SB = {};SB.$ = jQuery.noConflict(true);";
document.body.appendChild(script);
As you can see, I'm trying to add Jquery to the page, and then namespace it in case Jquery already exists. The problem is that when the code executes, I'm receiving this error:
Uncaught ReferenceError: jQuery is not defined
So, clearly jQuery is not loaded yet when the namespacing code executes, but I don't understand why. Shouldn't jQuery be defined at this point?
The script.onload function seems to have solved the problem:
//add jquery to page
var script = document.createElement('script');
script.src = 'http://my-domain/assets/js/jquery.min.js';
script.onload = function(){
//move jquery to our own namespace
var script = document.createElement('script');
script.innerText = "var SB = {};SB.$ = jQuery.noConflict(true);";
document.body.appendChild(script);
}
document.body.appendChild(script);

Can't insert js programmatically if it uses document.write

I am trying to insert js files programmatically, using jquery and something like this:
var script = document.createElement( 'script' );
script.type = 'text/javascript';
script.src = 'http://someurl/test.js';
$('body').append(script);
It works fine, if test.js contains an alert or some simple code it works fine, but if the file test.js contains document.write, and the file including the js is hosted on another domain than test.js (or localhost), nothing happens and firebug shows the error :
A call to document.write() from an asynchronously-loaded external
script was ignored.
If the test.js and the file that include it are hosted on the same domain, on chrome it still wont work but on firefox the document.write gets executed fine but the page stays "loading" forever and sniffer show request to all the files with "pending" status.
What other methods to include js files programmatically could I try?
use innerHTML instead of using document,write.
and use following code to register script,
(function() {
var jq = document.createElement('script');
jq.type = 'text/javascript';
jq.async = true;
jq.src = 'http://someurl/test.js';
var s = document.body.getElementsByTagName('script')[0];
s.parentNode.insertBefore(jq, s);
})();
Document.write is ONLY for synchronous tasks when the html is loaded (for the very first time), never for asynchronous tasks like the one you are trying to do.
What you want to do is dynamically insert a <script> DOM element into the HEAD element. I had this script sitting around. As an example, it's a race condition, but you get the idea. Call load_js with the URL. This is done for many modern APIs, and it's your best friend for cross-domain JavaScript.
<html>
<head>
<script>
var load_js = function(data, callback)
{
var head = document.getElementsByTagName("head")[0];
var script = document.createElement("script");
script.type = "text/javascript";
script.src = data;
head.appendChild(script);
if(callback != undefined)
callback();
}
load_js("http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js");
setTimeout(function() {
$('body').html('loaded');
}, 1000);
</script>
</head>
<body></body>
</html>
There isn't anything wrong with your approach to inserting JavaScript. document.write just sucks a little bit. It is only for synchronous tasks, so putting a document.write in a separate script file is asking for trouble. People do it anyway. The solution I've seen most often for this is to override document.write.

Reference JS file in JS file

I have a Js function that I would like to:
Reference another js file
Pull a function out.
I would like to do this JS side and not reference on the actual page as I need this process to happen dynamically.
var h = document.getElementsByTagName('head')[0],
s = document.createElement('script');
s.type = 'text/javascript';
s.onload = function () { document.getElementById('hello').innerText = h.innerText; };
s.src = 'http://html5shiv.googlecode.com/svn/trunk/html5.js';
h.appendChild(s);
see: http://jsbin.com/uhoger
If you're working with the browser, jQuery has an helper function for it, $.getScript.
The only option I can think of is to dynamically insert a new script tag into the page targeting your desired script from your initial javascript. Just have your initial script insert the new <script> tag on load, or upon request and then test for availability.

Categories

Resources