I am loading Mootools dynamically in the scripting part of an app (AutoWWW) because it does not allow direct HTML usage.
I am using Request.HTML and want to get the html of a page but it returns an 'undefined' message. How can i fix this?
My code:
function loadScript(url, callback) {
// Adding the script tag to the head as suggested before
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
// Then bind the event to the callback function.
// There are several events for cross browser compatibility.
script.onreadystatechange = callback;
script.onload = callback;
// Fire the loading
head.appendChild(script);
}
var mootools = new Request({
url: 'http://google.com',
method: 'get',
onSuccess: function(responseText){
alert(responseText);
}
});
loadScript("https://ajax.googleapis.com/ajax/libs/mootools/1.6.0/mootools.min.js", mootools);
There are 2 things you should take into account. One is possible CORS limitations, the other is that when you do head.appendChild(script); it will load the script asynchronously.
This means MooTools will be loaded but it will not be available until the callback function is called. To fix this you should have the callback internally inside the loadScript function, and from inside that callback call the other callback that was passed as function argument.
function loadScript(url, callback) {
// Adding the script tag to the head as suggested before
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.onreadystatechange = callback;
script.onload = function() {
new Request({
url: 'https://jsonplaceholder.typicode.com/posts/1',
method: 'get',
onSuccess: callback
}).send();
};
script.src = url;
head.appendChild(script);
}
loadScript("https://ajax.googleapis.com/ajax/libs/mootools/1.6.0/mootools.min.js", function(text) {
alert(text);
});
Related
I don't understand why it is not working.
Open link https://www.google.com/recaptcha/api2/demo
Inject jquery in this webpage
Given ReCAPTCHA, select checkbox for “I’m not a robot” and choose photos
Open Chrome console and run code:
$('iframe[src*="frame"]').contents().find('#recaptcha-verify-button').click();
I don't understand why click function (on verify button from js) not working (nothing happens, no error, nothing).
Edit:
Inject jQuery:
if (typeof jQuery == 'undefined') {
loadScript('https://code.jquery.com/jquery-1.11.3.min.js', jQueryReady);
}
function loadScript(url, callback){
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
if(!callback) callback = function(){};
if(script.addEventListener) {
script.addEventListener("load", callback, false); // IE9+, Chrome, Firefox
}
else if(script.readyState) {
script.onreadystatechange = callback;
}
head.appendChild(script);
}
Click on “I’m not a robot” working perfect:
$('iframe[src*="anchor"]').contents().find('.recaptcha-checkbox-checkmark').click();
Edit2:
//https://www.google.com/recaptcha/api2/demo
if (typeof jQuery == 'undefined') {
loadScript('https://code.jquery.com/jquery-1.11.3.min.js', jQueryReady);
}
function loadScript(url, callback) {
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
if (!callback) callback = function() {};
if (script.addEventListener) {
script.addEventListener("load", callback, false); // IE9+, Chrome, Firefox
} else if (script.readyState) {
script.onreadystatechange = callback;
}
head.appendChild(script);
}
function jQueryReady() {
//working perfect
//$('iframe[src*="anchor"]').contents().find('.recaptcha-checkbox-checkmark').click();
//not working
$('iframe[src*="frame"]').contents().find('#recaptcha-verify-button').click();
}
As Jaromanda X mentions in the comments, it would obviously not work because the jQuery library isn't loaded on that page.
Following your edit, your code throws a security error:
if (typeof jQuery == 'undefined') {
loadScript('https://code.jquery.com/jquery-1.11.3.min.js', jQueryReady);
}
function loadScript(url, callback) {
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
if (!callback) callback = function() {};
if (script.addEventListener) {
script.addEventListener("load", callback, false); // IE9+, Chrome, Firefox
} else if (script.readyState) {
script.onreadystatechange = callback;
}
head.appendChild(script);
}
function jQueryReady() {
$('iframe[src*="anchor"]').contents().find('.recaptcha-checkbox-checkmark').click();
}
jquery-1.11.3.min.js:2 Uncaught SecurityError: Failed to read the 'contentDocument' property from 'HTMLIFrameElement': Blocked a frame
with origin "http://www.google.com" from accessing a frame with origin
"https://www.google.com". The frame requesting access has a protocol
of "http", the frame being accessed has a protocol of "https".
Protocols must match.
The iframe is the secure https, whereas the actual demo is on a http location.
I want to trigger a function to run as quickly as possible, but it needs to wait for another (third party) script to finish loading, else the proper variable will not be defined yet.
Can I listen for a specific script to finish loading and bind a function to that event?
I need code, so:
When this loads:
<script src="https://www.officeball.biz/socket.io/socket.io.js"></script>
run this:
function(){ console.log('socket ready!'}`
It would seem that I could just mutate the third party script to call the function, but not in this case: socket.io is a dynamically generated script which I have no control over the source of.
The alternative would be to wait for the document to load; this question is an attempt to run the script as soon as possible instead.
You can create a script and add to the head:
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'https://www.officeball.biz/socket.io/socket.io.js';
document.getElementsByTagName('head')[0].appendChild(script);
script.onload = function() {
console.log( 'loaded' );
}
This example can be wrapped into a function and added to the document head:
<script>
function load_script( src, callback ) {
var script = document.createElement('script');
script.src = src;
document.getElementsByTagName('head')[0].appendChild(script);
script.onload = callback;
}
</script>
And, it can be later used like this:
load_script( 'https://www.officeball.biz/socket.io/socket.io.js', function() {
console.log( 'socket ready!' );
});
Furthermore, as a response to your comment, there is also a possibility to create a script tag with id and data attributes:
<script id="socket-io" data-src="https://www.officeball.biz/socket.io/socket.io.js" type="text/javascript"></script>
And to add the src attribute later, the script begins to load the moment the src attribute is set:
var script = document.getElementById( 'socket-io' );
script.src = script.getAttribute( "data-src" );
script.onload = function() {
console.log( 'socket ready!' );
}
And this can be, of course, wrapped in a function, for example:
<script>
function load_script( id, callback ) {
var script = document.getElementById( id );
script.src = script.getAttribute( "data-src" );
script.onload = callback;
}
</script>
And, finally:
load_script( 'socket-io', function() {
console.log( 'socket ready!' );
});
This question already has answers here:
Load jQuery with Javascript and use jQuery
(9 answers)
Closed 8 years ago.
Try the following code in your browser's console:
var script= document.createElement('script');
script.type= 'text/javascript';
script.src= 'http://code.jquery.com/jquery-2.1.1.min.js';
script.async = true;
document.body.appendChild(script);
console.log($);
Then wait a few seconds and do this again:
console.log($);
So it takes a while for jQuery to load. I tried this suggestion, which seems to be the consensus of all related questions:
+function loadScript(url, callback)
{
// Adding the script tag to the head as suggested before
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
// Then bind the event to the callback function.
// There are several events for cross browser compatibility.
script.onreadystatechange = callback;
script.onload = callback;
// Fire the loading
head.appendChild(script);
}("http://code.jquery.com/jquery-1.7.1.min.js", function(){console.log($);});
And once again it doesn't work ...
The first console.log($) should give the correct result. What can I do to execute a function as soon as jQuery has loaded and executed?
(Background: I'm writing a Chrome extension to fix formatting on a page that doesn't use jQuery.)
function loadScript(url, callback){
var foo1 = document.createElement('script');
foo1.type = 'text/javascript';
foo1.setAttribute('src', url);
foo1.onreadystatechange = callback;
foo1.onload = callback;
var head = document.getElementsByTagName('head')[0];
head.appendChild(foo1, head);
}
loadScript(('https:' == document.location.protocol ? 'https://' : 'http://') +'code.jquery.com/jquery-1.11.0.min.js', function(){
console.log($);
});
I am trying to use GoogleMaps.InfoBox on my project, but before load this script, the GoogleMaps API has to be loaded.
Right now I have this code to load everything:
/**
* Load scripts asynchronously
*/
function loadScript() {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "http://maps.googleapis.com/maps/api/js?key=-MY-KEY-&sensor=true&callback=initialize";
document.body.appendChild(script);
var scriptInfoBox = document.createElement("script");
scriptInfoBox.type = "text/javascript";
scriptInfoBox.src = "http://google-maps-utility-library-v3.googlecode.com/svn/trunk/infobox/src/infobox_packed.js";
document.body.appendChild(scriptInfoBox);
}
But not always the GoogleMaps API is loaded before than GoogleMaps.InfoBox one.
How can I load JS sorted, waiting for complete the previous one?
You can use the load event of the scripts:
function loadScript(callback) {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "http://maps.googleapis.com/maps/api/js?key=-MY-KEY-&sensor=true&callback=initialize";
document.body.appendChild(script);
script.onload = function() {
var scriptInfoBox = document.createElement("script");
scriptInfoBox.type = "text/javascript";
scriptInfoBox.src = "http://google-maps-utility-library-v3.googlecode.com/svn/trunk/infobox/src/infobox_packed.js";
document.body.appendChild(scriptInfoBox);
scriptInfoBox.onload = callback;
};
}
However, you will need to adapt the code a bit to make it crossbrowser-safe like this.
Just use regular script tags right before </body>.
<script src="http://maps.googleapis.com/maps/api/js?key=-MY-KEY-&sensor=true&callback=initialize"></script>
<script src="http://google-maps-utility-library-v3.googlecode.com/svn/trunk/infobox/src/infobox_packed.js"></script>
By default, browsers will execute scripts in the order they appear.
So if I have the following:
<script type="text/javascript" src="offsite file I am referencing"></script>
and I simply want to delay the execution of calling that file using settimeout, how would I go about that?
Very strange in that I would have no problem using settimeout on a simple function, but I am kind of stumped in this seemingly more simple situation.
My thought would be I could just make a function that calls that file after x amount of time, but calling the file in the function seems to be escaping me.
you are almost there.
in your settimeout callback function do the following:
var script = document.createElement('script');
script.src = "http://whatever.com/the/script.js";
document.getElementsByTagName('head')[0].appendChild(script);
The simplest way would be to let the script file load normally and just call a main function in it with setTimeout() like this:
<script type="text/javascript" src="offsite file I am referencing"></script>
<script type="text/javascript">
setTimeout(executeMainFunction, 5000); // function in offsite js file
</script>
If you cannot do that for some reason, then you can delay the loading of the external script file like this:
setTimeout(function() {
var headID = document.getElementsByTagName("head")[0];
var newScript = document.createElement('script');
newScript.type = 'text/javascript';
newScript.src = 'http://www.somedomain.com/somescript.js';
headID.appendChild(newScript);
}, 5000);
Here's a reference article on dynamic loading of script files (and other types of resources): http://www.hunlock.com/blogs/Howto_Dynamically_Insert_Javascript_And_CSS.
You can use DOM manipulation to create a new script tag at runtime. Adding it into the document will load the external JS file just as if you had written it into the HTML in the first place.
var loadScript = function(sourceSrc){
var scriptTag = document.createElement('script');
scriptTag.src = scriptSrc;
document.getElementsByTagName('head')[0].appendChild(scriptTag);
}
You can delay the script from loading, until the page finishes loading, using the HTML script defer attribute:
<script src="offsite file I am referencing" defer></script>
If the purpose of this exercise is to delay the loading of external resources to simulate potential real life scenarios (e.g. when loading 3rd party widgets, etc), then I'd go down a very different route.
The following are two different delay proxy implementations that can be used to simulate and test unexpected network conditions:
http://www.deelay.me/
https://www.npmjs.com/package/grunt-connect-delay
They both work by using a prefix like /delay/5000/ to specify the delay simulation period.
Mozilla Developer Network explains various approaches:
MDN Async Script Techniques
<script async src="file.js"></script>
or
var script = document.createElement('script');
script.src = "file.js";
document.body.appendChild(script);
or if your JavaScript is in a String:
var blob = new Blob([codeString]);
var script = document.createElement('script');
var url = URL.createObjectURL(blob);
script.onload = script.onerror = function() { URL.revokeObjectURL(url); };
script.src = url;
document.body.appendChild(script);
There is also good information when async is not async as well as how to get around those cases.
I have created for ReactJS and its worked for me.
1. File: widget.js with promise:
const delayTime = 20000; // loading 20sec delay.
const loadJS = async () => {
return await new Promise(function (resolve, reject) {
var script = document.createElement('script');
script.type = 'text/javascript';
script.async = true;
script.src = 'https://yoururl.com/js/widget.js';
script.onload = resolve;
script.onerror = () => {
reject('Cannot load js')
document.head.removeChild(script);
}
document.head.appendChild(script);
}) }
function initLoadJS() {
loadJS()
.then(()=> console.log('testing'))
.catch((error)=>console.error(error)) }
function delayLoadingJS() {
setTimeout((event)=>initLoadJS(event), delayTime);
}
export default delayLoadingJS;
2. Calling delayLoadingJS() function on the page:
When page loading completed then after 20 sec later initLoadJS() method will trigger and it attach the 3rd party javascript file(https://yoururl.com/js/widget.js) on page.
componentDidUpdate(prevProps, prevState) {
if (this.state.page !== prevState.page) {
delayLoadingJS();
}
}
For a NextJS cript, the code below will work fine:
<script id="sample_id">
setTimeout(function(){
var script = document.createElement('script');
script.src = "https://link_to_load";
document.getElementsByTagName('head')[0].appendChild(script);
},
4000);
</script>