Load jQuery in an iframe - javascript

I'm writing a script which requires some stuff to be carried out in an iframe. It's a userscript for a site which I do not own, so because of cross-domain issues, I cannot just set the src of the iframe to a page with my own code. Instead, I am dynamically building the iframe.
To do this, I have
function childScripts(){
//Stuff that must be injected into the iframe.
//Needs jQuery
}
//because I'm lazy:
var iframeWin=$('#my-iframe')[0].contentWindow;
//Load jQuery:
var script = iframeWin.document.createElement("script");
script.type = "text/javascript";
script.src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"
iframeWin.document.head.appendChild(script);
//Inject script
var script = iframeWin.document.createElement("script");
script.type = "text/javascript";
script.textContent="("+childScripts.toString()+")()";
iframeWin.document.body.appendChild(script);
Now, the injected script needs jQuery, but for some reason, jQuery isn't loaded when the injected script runs--even though jQuery is in <head> and the injected script is in <body>.
I've tried other workarounds--making the injected script run onload. I don't like the idea of setting a timeout and checking for the existence of jQuery, I'd prefer a more elegant solution.
I've also tried copying the $ object to iframeWin.$, but of course that doesn't work, since it just backreferences to the parent $ and manipulates the parent document.

It's easier to manipulate iframes using jQuery. Please try:
$('<iframe id="my-iframe"/>').load(function(){
$('#my-iframe').contents().find('body').append('asd').end()
.find('body').append('<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"><\/script>').end()
.find('body').append('<script>$(function() {alert("hello from jquery");console.log("hello from jquery"); })<\/script>');
}).appendTo("body");
Placement:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script>
$('<iframe id="my-iframe"/>').load(function(){.....
</script>
</body>
</html>

Related

How to remove inline styles added by external script?

I have a <script> that generates a both <style> and inline style attributes with !important tags. I'd like to remove all this styling.
My plan was to use a javascript onload callback (and some jQuery) to remove the <style> block and all inline style attributes — but I can't seem to select any of these elements. Here's what I've been toying with:
var script = document.createElement("script");
script.src = "//script.path.js";
script.onload = function(){
$(this).parent().find("style").remove();
$(this).parent().find("[style]").removeAttr("style");
};
$(target).append(script);
UPDATE
It seems that the elements generated by the <script> just aren't available in the DOM right away. If I use setInterval to check if the elements exist first, I can get this to work. I imagine there's a better way to do this though...
According to this other question, you must append the script tag to the DOM before setting onload.
var script = document.createElement("script");
$(target).append(script);
script.src = "//script.path.js";
script.onload = function(){
$(this).parent().find("style").remove();
$(this).parent().find("[style]").removeAttr("style");
};
https://jsbin.com/minoyeyicu/edit?html,js,output
UPDATE: Having clarified that the issue is that the style tag/attributes haven't yet been applied to the DOM until after the downloaded script has executed, one alternative (depending on whether the loaded script is under your control), is to pass a callback parameter to the loaded script and have the loaded script execute the callback when it finishes executing (which is how the Google Maps API works). E.g.
script.src = '//script.path.js?callback=removeStyles'
In order to use the callback parameter from within script.path.js, something like this could be done.

Reload iFrame (same-domain) without changing `src=`

I am dynamically creating iframe , which just contains content (no src attribute).
var iframe = document.createElement('iframe');
iframe.contentWindow.document.body.innerHTML= my_page_content;
....
however, JS scripts (<script src="....." inside my_page_content) are not being loaded and I have to re-load scripts.
these methods wont help me to reload frame:
//this one emptyfies the iframe at all
iframeElement.src = iframeElement.src
//this one is not possible, because the `<script>` links are embedded in the content already.
var script = doc.createElement('script'); script.src = "jquery.min.js";
framebody.appendChild(script);
what are the solutions to force the iframe to load the included scripts in its html content? maybe I am attaching the content in a wrong way?
The only way I've solved this was to write the body inside iframe using write() command:
var ifr = iframeElement.contentWindow.document;
ifr.open(); ifr.write("<body>"+ my_page_content +"</body>"); ifr.close();
neither appendChild() nor .innerHTML helped me.

Script doesn't run after load a div with ajax

I have the script audiojs for changing the style of audios tag in html when I go to my page it work without problems, but when I click a button to reload div (this div contain audios tags) with function load jQuery the style of audiojs removed, I tried to get script after load the div with jQuery getScript, but the script load many times that caused to stop of my browser.
this is the function to call the audiojs
audiojs.events.ready(function() {
audiojs.createAll();
});
I want a solution to call this function one time no more, thanks
Try to adding a new script tag to with the script to re-load in your code something like below:
<script language="text/javascript">
function audiojs()
{
var div= document.getElementsByTagName('head')[0];
var script= document.createElement('script');
script.type= 'text/javascript';
script.src= 'audiojs.js';
div.appendChild(script);
}
audiojs();
</script>
I hope you will get some ideas now. Also check your caching.
It's hard to know without any link to the audio.js library, but most API's or libraries will give some indication that they are loaded. I would use an if statement to create something like:
(function () {
function checkForLoaded(){
if (audiojs.state !== null) { //or something similar
audiojs.createAll();
}
}
})();
Thanks everyone,
i found the solution,
after loading the div with ajax i added this code to remove the class audiojs
$("audio").removeClass("audiojs");

loading a backup copy of jQuery when CDN is down

I have this code in a script we use for initializing all of our applications, it loads the jQuery from the google CDN amongst several other things that all of our applications require. Then when we load the specific program functionality we check to make sure that jquery has loaded, in case the CDN is down. The problem I am running into is it is still loading the second one. If I add a simple alert("Test"); after the line headTag.appendChild(jqTag); it works perfectly, but if I remove the alert it uses the second one. What gives?
They are loaded like so:
<script type="text/javascript" src="i-initializer.js"></script>
<script type="text/javascript" src="i-program.js"></script>
initializer script:
if(typeof jQuery=='undefined'){
var headTag = document.getElementsByTagName("head")[0];
var jqTag = document.createElement('script');
jqTag.type = 'text/javascript';
jqTag.src = 'http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js';
headTag.appendChild(jqTag);
}
Then in another script we have the following:
if(typeof jQuery=='undefined'){
var header = document.getElementsByTagName("head")[0];
var qtag = document.createElement('script');
qtag.type = 'text/javascript';
qtag.src = 'http://feedback.oursite.com/scripts/jquery-1.8.3.min.js';
qtag.onload = checkjQueryUI;
header.appendChild(qtag);
}
else
{
jQCode();
}
jQCode() {
...
}
This is the technique used by HTML5 Boilerplate. First it loads the Google CDN script, then immediately checks if the global jQuery object exists -- if it doesn't, the CDN failed and a local copy is loaded instead.
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="js/vendor/jquery-1.8.3.min.js"><\/script>')</script>
Your fallback code loads jQuery asynchronously.
That means that the rest of your scripts run before jQuery loads.
Adding an alert() call forces the rest of your code to wait (until you click OK); by the time that happens, jQuery will have loaded.
Instead, you can emit a new <script> tag using document.write() to load it synchronously.
Alternatively, you could wrap the rest of your code in a callback and call the callback(s) after jQuery loads.
If you do it this way, you should use a script loader library, which will handle all of that for you.

Run Javascript code from external .js file on button click

Here is what i want to do.
Normally we can call javascript functions on different event, button clicks within the page provided that script is already in the page (may be in head section) or it has been loaded in the head section from external js file on load time.
Is it possible to load an external js file not when the page loads but at a later stage when (say) a button is clicked.
I know this is easily possible in JQuery:
$.getScript("url to js file", function(){});
But i want to know how can we do the same using simple javascript within the page without JQuery?
Dynamically create the script element :
<script>
var oHead = document.getElementsByTagName('HEAD').item(0);
var oScript= document.createElement("script");
oScript.type = "text/javascript";
oScript.src="other.js";
oHead.appendChild( oScript);
</script>
You do it like this:
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'helper.js';
head.appendChild(script);
<script language="javascript">
document.write("<script src='other.js'><\/script>");
</script>
other options are here

Categories

Resources