How do I access jQuery from a new window? - javascript

In my app I open a new window with var w = window.open(). I access the CanvasJS API with:
var canvas = w.document.createElement('script');
canvas.type = "text/javascript";
canvas.src = "https://canvasjs.com/assets/script/canvasjs.min.js";
w.document.head.appendChild(canvas);
This works perfectly fine. I did the same thing with jQuery and made sure to append it before my own script yet I get this error: ReferenceError: $ is not defined
Here is what my code looks like:
var w = window.open('','_blank',width,height);
w.document.body.innerHTML = '<body> //create chart container here </body>';
var jQuery = w.document.createElement('script');
var canvas = w.document.createElement('script');
var script = w.document.createElement('script');
canvas.type = "text/javascript";
canvas.src = "https://canvasjs.com/assets/script/canvasjs.min.js";
jQuery.type = "text/javascript";
jQuery.src = "https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js";
script.textContent = "//my script content here, this is where I use the '$' jQuery object";
w.document.head.appendChild(jQuery);
w.document.head.appendChild(canvas);
w.document.head.appendChild(script);

Even though you have inserted the script tag in the head but this does not mean that the script have been downloaded completely. You code runs before the browser is able to download jQuery. Dynamically inserted script tags perform async operation.
I suggest that you setup an interval and check if jQuery is available. Once it is available execute your code. Name the script element created for jQuery something else as it will interfere with checking for jquery within your interval.
var jqueryCheck = setInterval(function() {
if(window.jQuery) {
clearInterval(jqueryCheck);
// execute your code
}
}, 100);

Related

How to include dynamic Javascript file in the DOM without repeating same file

I want to load <div> content dynamically by using AJAX in a specific div. After the AJAX call I want to load a JS file in the footer. I loaded content by clicking menu without page loading by using URL hash. My problem is when I click the same link multiple times, the JS file is loading multiple times because the JS file is appended. That's why every event occurs multiple times. I want to load the JS file before checking if the file is already loaded into the DOM. If the file is not loaded in the DOM, I will append a JS file in the DOM.
As the answer suggested by this URL, here is my code:
var Utils = {
loadjs: function(url){
var footer = document.getElementsByTagName('body')[0];
var script = document.createElement( 'script' );
script.type = 'text/javascript';
script.src = url;
footer.appendChild(script);
},
}
Utils.loadjs(url);
You can read the script tags to search for a particular script is there or not. Something like below:
var Utils = {
loadjs: function(url) {
var me = document.querySelectorAll('script[src="' + url + '"]');
if (me && me.length >= 1) {
return null;
}
var footer = document.getElementsByTagName('body')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
footer.appendChild(script);
},
}
Utils.loadjs(url);
You can use dynamic import() syntax to load modules, even from regular scripts.
This has the benefit of loading those scripts as modules, which are always in strict mode and have module scope.
Read more about dynamic import
So, instead of Utils.loadjs(url), just import(url)

Javascript - Passing a script to innerHTML on older browsers

I'm trying to pass a script into an iframe dynamically so it will run there (content in the example comes from the server) using this snippet:
content = '<script type="text/javascript">document.write("bla"");</script>';
el = document.getElementById('iframeName');
iframeDoc = el.contentWindow.document;
tempEl = iframeDoc.createElement('div');
tempEl.innerHTML = content;
It runs great on new browsers but when I try to run it on IE8 and lower, the innerHTML comes up null.
I tried different approaches but the inner HTML is the only option i can think of that can run the script i'm passing in to tempEl. Any ideas on how to pass content into tempEl.innerHTML so it will run the script and also work on IE8-?
Have you tried injecting the script element into the head of the document?
I am not to sure about script tags, but you must inject link and style elements into the head of a document for it to be interpreted correctly by older IE browsers.
var script = document.createElement('script');
script.type = 'text/javascript';
script.rel = 'JavaScript';
script.innerHTML = 'document.write("bla");';
var el = document.getElementById('iframeName');
iframeDoc = el.contentWindow.document;
iframeDoc.head.appendChild(script);
The solution I went with is:
el = document.getElementById('iframeName');
iframeDoc = el.contentWindow.document;
iframeDoc.write(content);
it's a lot shorter and is cross-browser (instead of using innerHTML).

How to prevent cross domain javascript loading with .htaccess?

The company which developped my website just added this javascript code on the Zend Guard encrypted index.php file (I saw it with "View source") :
(function ()
{
var smrs = document.createElement("script");
smrs.type = "text/javascript";
smrs.async = true;
smrs.src = document.location.protocol + "//www.domain.com/file.js";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(smrs, s);
})();
It injects a very agressive javascript code which adds a image link to their website (with a SetInterval each 10sec), at the bottom of the page.
The problem ? A local competitor, which is currently being accused of significant fraud, have the same CMS and the same image link.
Being associated with that competitor is prejudicial for me. I would like to know if there is a way to block the "www.domain.com/file.js" loading with a .htaccess.
Thanks.
You can't (using htaccess). This javascript creates a script tag to load the external javascript. The call never passes through the server. So apache (htaccess) can't block that.
The easiest way is to search in the source code and remove the script (if you have access).
UPDATE:
I see the script is encrypted... If you can insert a script at the very beginning (before the code gets executed you can create a hook on the insertBefore method. Here is a working fiddle
var ALLOWED_DOMAINS = ['www.klaartjedevoecht.be', 'jsfiddle.net'];
function creatHook(){
function getDomain(url) {
return url.match(/:\/\/(.[^/]+)/)[1];
}
var insertBefore = Element.prototype.insertBefore;
Element.prototype.insertBefore = function(new_node,existing_node){
if(new_node.tagName.toLowerCase() === 'script' && ALLOWED_DOMAINS.indexOf(getDomain(new_node.src)) > -1){
insertBefore.call(this, new_node, existing_node);
}
}
}
creatHook();
//TESTING CODE:
var smrs = document.createElement("script");
smrs.type = "text/javascript";
smrs.async = true;
smrs.src = document.location.protocol + "//www.klaartjedevoecht.be/test.js";
//var smrs = document.createElement("img");
// smrs.src= "http://img52.imageshack.us/img52/7653/beaverl.gif";
var s = document.getElementsByTagName("div")[0];
s.parentNode.insertBefore(smrs, s);
​I agree it's a bit hacking, but at least its cleaner then the timer solution. If you can't remove it, there is no clean solution.

making reddit's buttons asynchronous

I'm trying to add Reddit buttons to my site, but they are not asynchronous, and Reddit tends to lag, slowing down page loads. When I look at what the script returns, I get something like this:
(function () {
var write_string = ...
document.write(write_string);
})()
I try to inject it into my page after a page load. I've tried both these methods in javascript after page load to no avail:
placeholder.innerHTML = '<script type="text/javascript" src="http://www.reddit.com/buttonlite.js?i=5"></script>'
var js = document.createElement('script');
js.type = 'text/javascript';
js.src = 'http://www.reddit.com/buttonlite.js?i=5';
placeholder.appendChild(js);
where placeholder is a DOM element <div class="reddit-button"></div>. Any ideas on how I could go about this?
You can "override" the document.write method:
window.onload = function() {
var oScript = document.createElement("script");
document.write = function(text) {
document.getElementById("placeholder").innerHTML += text;
};
oScript.src = "http://www.reddit.com/buttonlite.js?i=0";
document.body.appendChild(oScript);
};
This way the external code can call document.write as much as it wants to and you push the HTML to the proper place in your document.
Live test case - Tested OK under Chrome, Firefox and IE9 so guess it should be enough.

Dynamically loading an external JavaScript response

I'm using this code to include dynamically js file in run-time:
var headID = document.getElementsByTagName("head")[0];
var script = document.createElement('script');
script.type='text/javascript';
script.src="js-debug/"+record.getId()+".js";
script.onload = function() {
inizializeComponent();
}
For every node of menu, I include a different js file.
Now I need to intercept the event triggered when the page does not exist to show a messagebox!
How can I get it?
Use script.onerror = function () { ....

Categories