iframe contents disappear when manipulated by mootools - javascript

I've got a third party (mootools) library creating tabs and I've got google double click for publishers (dfp) creating ads. dfp creates the ads in an iframe then the tabs script grabs an anchestor of the iframe and 'messes' with it to create the tabs. The contents of the iframe gets lost in the process.
I'm looking for a way of coping with this (tried firing the dfp stuff after the tabs had loaded but then the google scripts crashed).
The iframe is from a different domain to the parent window so anything which tries to do stuff to elements within the iframe is going to fail.
addTab: function(text, title, content) {
var grab = $(content);
var container = (grab || new Element('div'))
.setStyle('display', 'none')
.addClass(this.options.classContainer);
this.wrapper.adopt(container);
var pos = this.tabs.length;
var evt = (this.options.hover) ? 'mouseenter' : 'click';
var tab = {
container: container,
toggle: new Element('li').grab(new Element('a', {
href: '#',
title: title
}).grab(
new Element('span', {html: text})
)).addEvent(evt, this.onClick.bindWithEvent(this, [pos])).inject(this.menu)
};
if (!grab && $type(content) == 'string') tab.url = content;
this.tabs.push(tab);
return this.fireEvent('onAdded', [tab.toggle, tab.container, pos]);
},

Whenever an iframe or an ancestor of it are disconnected from the DOM, the iframe's contents will be cleared and the iframe will reload when it or its ancestor is reinserted back. This anoying behaviour occurs in Firefox and Webkit, but I think the iframes won't reload on IE.
As a workaround, you will need to find a way to reorder your code so that the iframe is only added after the tab script is done doing its thing to the container.
Chrome also apparently has an option that causes the iframe to not reload if you move it with adoptNode instead of apendChild but I do not believe it is cross-browser.
for more, see this similar question: How to move an iFrame in the DOM without losing its state?

Related

Adjusting the height of multiple iframes on the same page

I have multiple textboxes on a seperate page, which I intend to display on another page, together, each with an iframe.
I found a script in an older post, which made that possible.
However: Only the first iframe on a page is targeted by my script. Which means I have 3 more iframes with scrollbars. Once I reload the page, I can see the other iframes for a split second in their inteded height, before the site is fully loaded and they change back to those ugly scrollbars.
On the source page I use this script next to my textblock:
window.addEventListener('load', function() { let message = { height: document.body.scrollHeight, width: document.body.scrollWidth };
// window.top refers to parent window
window.top.postMessage(message, "*");
});
On the final page I inserted the script in the same HTML box as the iframe:
<iframe src="https://whateverpage.com/" id="someid"></iframe>
<script>
let iframe = document.querySelector("#someid");
window.addEventListener('message', function(e) {
// message that was passed from iframe page
let message = e.data;
iframe.style.height = message.height + 'px';
iframe.style.width = message.width + 'px';
} , false);
</script>
I'm not the brightest when it comes to javascript. That's why I use Elementor for most of the stuff I do ;)
So I have changed the ID in each iframe to be unique. Still, there is always only the first iframe element which displays as intended. I swapped the iframes around and played with different layouts of columns, but it is alway the first element which is affected by the scripts.
I'm thinking about having the two scripts appear only once on my pages, but I don't know how to do that. I'd appreciate other ideas to make that work...

How to trigger iframe load event more than once when changing iframe source

I have an iframe that links to another internal web application.
There's a side panel with a list of links that changes the src of the iframe. Sometimes if there's a lot of data, the iframe site takes a while to load. I want to put a spinner icon when a link is clicked and hide it when the frame is loaded.
I change the src using $('#myiframe').attr('src', urlVar) in a click function for the links. I can show the spinner on click.
The problem is, how do I hide it? How do I find out that the iframe has finished loading?
I tried using $('#myiframe').load(function() { }) but that only works on the initial load (i.e. for the first link I click), not for subsequent loads (if I click on another link).
This javascript works for me :
function loadNewUrl (url){
if(url === undefined) url = 'http://example.com?v=' + Math.random();
var ifr = document.getElementById('myiframe');
ifr.setAttribute('src',url);
ifr.onload = function() {
alert('loaded');
};
}

MutationObserver doesn't work on cross-domain for Iframe src change detection

I am coding an app for mobile that uses iframe to show our shopping site, iframe part is like that;
<div id="loadImg"><div></div><img src="images/loading2.gif"/></div>
<iframe id="frame-content" src="www.siteadress.com"/>
with above structure I would like to show a preloader image to customers while page is being loaded then hide the loader after iframe content is loaded fully (because connection speed issues)
I am trying to make a preloader image for an iframe and i need to catch the click event (src is changed - but i cannot use onload() because it only fires when the content is fully loaded) of iframe while one of the link is clicked in it.
To make it, i am trying to using MutationObserver method like that;
var mut_elem = document.querySelector('#frame-content');
//MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.attributeName == 'src') document.getElementById('loadImg').style.display='block';
});
});
observer.observe(mut_elem, {attributes: true,attributeFilter:['src']});
but while above code works for same-domain, it doesn't work on cross-domain.
So i would like to learn that;
Can MutationObserver technique be used on cross-domain site? (if yes, how?)
If cross-domain is not possible with MutationObserver, Is there any way to make it possible (showing a loading image over iframe[cross-domain] and hide this image on main page when iframe content is loaded) with another way?
Thanks, right now..

Use parent jquery library in child Iframe

I have a two Iframe in my HTML page. I want to use one single jquery file which is loaded on parent page. The code give below is working fine every browser but it has one issue with chrome with ctrl+f5 key. When page is loading first time and when we are pressing ctrl+f5 the it is giving error in chrome otherwise it is working fine. Here is some snapshot. Parent page and iframe are in same domain.
if (typeof(jQuery) == "undefined") {
var iframeBody = document.getElementsByTagName("body")[0];
var jQuery = function (selector) { return parent.jQuery(selector, iframeBody); };
var $ = jQuery;
}
Add the jQuery script in both pages to avoid race condition. When one is loaded, the other will be retrieved from the browser cache.

Get hosting XULDocument for a ContentWindow or HTMLDocument in Firefox extension?

I have an Firefox Extension with a XUL overlay containing some Javascript with some event handlers. Among those is an EventListener for DOMContentLoaded. I have a second overlay I only want to load when visiting a certain website.
Here's some of the code I have so far:
var appcontent = document.getElementById("appcontent"); // browser
if (appcontent) appcontent.addEventListener("DOMContentLoaded", onPageLoad, true);
function onPageLoad(event) {
var doc = iEvent.originalTarget; // doc is document that triggered "onload" event
var win = doc.defaultView;
if (doc.nodeName != 'document') return; // only documents
if (win != win.top) return; //only top window.
if (win.frameElement) return; // skip iframes/frames
if(doc.location.href.search('http://somewebsite.com/') > -1) {
//Find XULDocument somehow
//var xulDoc = ??????;
xulDoc.loadOverlay('chrome://myextension/content/secondoverlay.xul', null);
}
}
How can I retrieve the XULDocument hosting the DOM, given the DOMContentLoaded event data?
Well, the XUL window is just window, aka. the global scope.
So the following two lines should both work and should be the same:
window.document.loadOverlay(...);
document.loadOverlay(...);
However, this most is not really what you want, because the XUL window is still the main browser.xul which hosts all content windows. There is no dedicated XUL window per content window!
Loading the second overlay will overlay the whole browser window, not just the "tab" (or whatever) and will stay once you close the tab (content window) or navigate away.
Now, the question is: What do you really want to achieve?
Display some UI (toolbar button, menu, whatever) only for certain pages? Then usually you'd overlay all your stuff once (on the initial load, i.e. in the "first" overlay) and just hide/show your UI according to your rules. See Tabbed Browser for some code snippets when dealing with tab switching and/or page loads.
Or you really want to apply something to the content window itself. Then you'd usually just modify the DOM of the content window directly.

Categories