iFrame call JS file

I tried quite a few “tricks” but it seems the browser doesn’t want to pull in the added src no matter what I tried.

Yet the browser does run added code.

The only thing I can think of that might work is adding in the actual jQuery code instead of as a src.

Unfortunately it includes both single and double quotes, and being so large it would take quite some time (if even possible) to change it so it would work as a string to use in a textContent =

If you don’t need that much of the jQuery library it might be easier to write a “mini library” to use in it’s place.

EDIT
another idea, maybe instead of trying to add a src to the iframe page content, the iframe page’s script could be put into the outer page where jQuery is defined.

I have to winterize a window now, but I’ll try that approach ASAP

Thank you.

Overall, this isn’t a huge deal because I can still do vanilla JS, but this is still curious to me. I appreciate your help.

Where is it you are trying to use jQuery?

You can run jQuery both in the iframe and in the main page with the one copy loaded in the main page - you just need to reference it from the iFrame as parent.$

The iframe page is where I need the jQuery

Thank you for this advice about parent.$. So this should logically work?

parent.$('#form_43').each( function() {
  $(this).contents().find('input').attr("required", "true");
});

I even tried putting this within a parent.$(window) load function, but neither seem to be working.
http:// aid an.f ina lsit e. c om/

On the right, there is a blue tab. If jQuery is working, it should show a “hacked” version of a placeholder when you click it and the form opens up (I say hacked because if you saw how I implemented it).

Thanks Stephen, that got my thoughts focused on the right area before I got off into a hack hell.

An interesting set of problems that was fun to solve.

There seems to be a scope thing or something going on as the code in the iframe content needs to reference elements from the containing page’s viewpoint. (where the jQuery lives)

Because the iframe content was loaded before the the jQuery was inserted into it, I needed to copy it, remove it, then replace it with a modified version of it so that jQuery could use it

Not the best what with hard-coded indexes and a dubious regex pattern, but the example files work

iframe-take2.html

<!DOCTYPE HTML>
<html lang="en">
<head>
<title>Iframe Take2</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<style type="text/css">
</style>
<script type="text/javascript">
// script needed before the DOM is loaded here
</script>
<script src="jquery-1.11.3.min.js"></script>
</head>
<body>
<h1>Iframe Take2</h1>
<iframe id="test_iframe" src="jquery-defined-test.html" width="1100" height="500"></iframe>
<script type="text/javascript">
// script that needs the DOM to be loaded here
function  modify_iframe_script(script_str) {
  var regex_pattern = /\$\(/g;
  var new_string = script_str.replace(regex_pattern, '$("#test_iframe").contents().find(');
  return new_string;
}

function init() {
var my_iframe = parent.document.getElementById("test_iframe");
var iframe_head = my_iframe.contentWindow.document.getElementsByTagName("head")[0];
var iframe_body = my_iframe.contentWindow.document.getElementsByTagName("body")[0];
var iframe_script =  my_iframe.contentWindow.document.getElementsByTagName("script")[1];

var assign_script_elem = document.createElement('script');
var script_elem = document.createElement('script');

var iframe_script_markup = iframe_script.innerHTML;
iframe_body.removeChild(iframe_script);

assign_script_elem.innerHTML = 'if (typeof window.parent.top.$ == "function"){ var $ = window.parent.top.$; alert("YAY"); } else { alert("BAH"); }';
script_elem.innerHTML = modify_iframe_script(iframe_script_markup);

iframe_head.appendChild(assign_script_elem);
iframe_body.appendChild(script_elem);
}

window.onload = function() {
   init();
};
</script>
</body>
</html>

jquery-defined-test.html (in honor of how often I saw “undefined” lol)

<!DOCTYPE HTML>
<html lang="en">
<head>
<title>jQuery Defined Test</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<style type="text/css">
</style>
<script type="text/javascript">
// script needed before the DOM is loaded here
</script>
</head>
<body>
<h1>jQuery Defined Test</h1>
<div>
<p id="cat_ipsum">Hide head under blanket so no one can see ears back wide eyed and thug cat chase dog then run away, or stand in front of the computer screen, stretch knock over christmas tree. Tuxedo cats always looking dapper all of a sudden cat goes crazy. Immediately regret falling into bathtub human give me attention meow. Sleep on dog bed, force dog to sleep on floor jump around on couch, meow constantly until given food, hack up furballs for spread kitty litter all over house or white cat sleeps on a black shirt so curl into a furry donut for play time. Lounge in doorway chase mice cat is love, cat is life so make meme, make cute face or chase after silly colored fish toys around the house. Claw drapes leave dead animals as gifts scratch the furniture but knock dish off table head butt cant eat out of my own dish immediately regret falling into bathtub for cough furball but sleep nap. Mark territory ears back wide eyed or stretch, thinking longingly about tuna brine but make meme, make cute face. Love to play with owner's hair tie stare at the wall, play with food and get confused by dust chew foot where is my slave? I'm getting hungry purr while eating, and rub face on owner. Chew on cable chirp at birds, meow all night having their mate disturbing sleeping humans for cat is love, cat is life leave hair everywhere. Run in circles tuxedo cats always looking dapper so human give me attention meow. If it smells like fish eat as much as you wish scratch leg; meow for can opener to feed me. Ignore the squirrels, you'll never catch them anyway jump launch to pounce upon little yarn mouse, bare fangs at toy run hide in litter box until treats are fed chase laser wake up human for food at 4am so play time, or stand in front of the computer screen throwup on your pillow.</p>
</div>
<script type="text/javascript">
$( "#cat_ipsum" ).on( "mouseover", function() {
  $( this ).css( "color", "red" );
});
</script>
</body>
</html>

Thank you very much Mitt, but is there any way this can be modified so that the parent page has 0 code in reference to the iframe? I only ask because of how this setup is that I’m using. Looking at it, it looks like it is exactly what I need (iframe calling jQuery), but the parent has some jQuery it looks like to convert the iframe code into something that will run?

Let me backup a bit to make sure I understand the situation

  • all pages that have iframes pass the same origin rules
  • not all pages will have iframes
  • the pages that are in iframes may or may not have jQuery code in them
  • for whatever reason the pages that are in iframes and have jQuery code do not call in the jQuery library (this in particular puzzles me)

Anyway, because the examples are contrived, they should be modified to work under different conditions. This is where, ermm, conditionals come in handy.

For example, if not all pages will have iframes, the code could be changed to

function init(the_iframe) {
//function init() {
//var my_iframe = parent.document.getElementById("test_iframe");
var my_iframe = the_iframe;
...
window.onload = function() {
  var the_iframe = parent.document.getElementsByTagName('iframe')[0];
  if (the_iframe) {
   init(the_iframe);
//   init();
  }
};

This way it would skip the init function entirely if there wasn’t an iframe, and if there was one the iframe object would be passed to the function eliminating the need to hard-code the selector.

As for the indexes, it is hopeful that pages will have only one head and one body tag, so [0] should be safe for those.
(though I have seen pages where this wasn’t so, I hope your pages do)

The hard-coded script selector index [1] is likely more problematic. Odds are the script tags in a page will vary in both number and position, and not all of them will have jQuery code.

By leaving off the index the “get” will return a collection that can be looped through.
Then a conditional could check the string for “$(” and if found, then do further processing.

Similarly, if there might be more than one iframe in a page, the collection could be looped through and each passed to the function

  1. ALl pages do pass the same origin rules
  2. Not all pages have iframes because not all pages will run the forms manager. If people want to use a form, they use forms manager and iframe the form in.
  3. The pages may or may not have jQuery code in the iframe page depending on if custom enhancements are needed. Aka in my case. All pages in this do not call jQuery library in the iframe. The iframe is a barebones page, more or less. I want jQuery to be able to be ran here because not all of my fellow developers may know vanilla JS.
  4. Puzzling, but yes that is exactly true.

I implemented your code:

function init(the_iframe) {
console.log("yo");
}
window.onload = function() {
  var the_iframe = parent.document.getElementsByTagName('iframe')[0];
  if (the_iframe) {
   init(the_iframe);
  }
};

Question though, what is this supposed to accomplish? Like, where were you going with this? Load jQuery? Somehow get parent.$ working like felgall mentioned?

When felgall mentioned parent.$, I assumed something like this would work and would be infinitely easier to accomplish rather than doing all this loop logic

parent.$('#form_43').each( function() {
  $(this).contents().find('input').attr("required", "true");
});

As did I. Unless I missed something(s) though, no matter what I tried I kept getting “undefined” or there was no error but the script failed to do what was hoped it would do.

If there is a better way I would definitely like to see how.

Exactly.

Can @felgall chime in here? I did google on this but google kept coming up with the parent() function, and not parent.$.

I’m lost. If you can post a complete example with the error and explanation of what you’re wanting to do I’ll take a look. What you’re doing seems really obscure and I’m confused by statements like “Our setup blocks the JS once we go live”.

If all of this is running on your domain doesn’t that mean you have complete control over the parent pages html and the iframe’s html?

The parent page HTML I can control for the most part.

The iframe page I cannot control because it’s generated via our forms manager. I can, however, add JS files and CSS files that will run in the page.

All this is for naught though; it appears that our product developers are going to link to jQuery for us in the iframe page, so I don’t have to do this workaround.

Still curious how this would work though via parent.$

Most defnitely not, considering the iframe is generated in our product.

@felgall is correct, you can access the parent pages jQuery and $ functions via parent.$

index.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Parent</title>
</head>
<body>
<script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<iframe src="child.html" width="500" height="300" />
</body>
</html>

The problem with running jquery via this context is that parent.$(selector) is searching in parents document context, the $ function takes a second parameter for the context object which you can set to the iframes document like this:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Child</title>
</head>
<body>
<div id="root">Root</div>

<script type="text/javascript">
parent.$('#root', document).html('Huzzah!');
</script>
</body>
</html>

This makes sense when you think about it, a naive $ function could look something like this

$ = function(selector, context) {
  context = context || document;
  return context.querySelectorAll(selector);
}

It will search in the document that the function is defined in unless you specify something else.

If it’s your product then yes, you definitely should be able to control what it generates.

It’s not MY product, it’s the companies product. It’s not like I can willy nilly go in there. I’m not even part of the product team. Only a handful of people have access and I’m not one of htem.

If I did have access, I would have added jQuery from the getgo.

[quote=“markbrown4, post:33, topic:210325”]
@felgall is correct, you can access the parent pages jQuery and $ functions via parent.$
[/quote]That makes sense. Thanks for the example!

No worries, I’m just always skeptical about statements that people can’t change existing code.

There’s always a way.

Yeah perhaps my explanation was poor. Code can obviously always be changed but there’s the matter of access, and changing the product to match my needs. It’s a weird situation here overall with our infrastructure.

Thanks for the help!

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.