Target an iframe with only the src attribute provided - javascript

We have a page rendering some affiliate scripts at the bottom. One of the scripts renders an iframe which is breaking our page in some browsers. We would like to keep this iframe from showing, but the only attribute that it is offering me is the src attribute. I cannot broadly target iframes with my CSS as the other generated iframes are necessary for various partners.
Until they get a chance to diagnose their bad code, is there a way for us target this one iframe by its src or something with CSS or JavaScript/jQuery and keep it from showing on the page?
The bad iframe:
<iframe src="https://someurl.net/p.ashx?a=9879&b=3541" height="1" width="1" frameborder="0">
Inside of this iframe the document tree goes:
<html>
<head><head>
<body>
<pre style="word-wrap:break-word; white-space:pre-wrap;">NF</pre>
</body>
</html>

This should do the trick:
$('iframe[#src*="someurl.net/p.ashx"]').hide();

The css method would be:
iframe[src*="someurl.net"] {
display: none;
}
*= means that the attribute must contain the value. In this case, src must contain someurl.net to match. (see doc)

Related

Chrome 75 - setting iFrame src attribute causes iFrame parent to load the iFrame content

Chrome v75 appears to have introduced a bug whereby if you replace an iFrame's src programatically, it will replace the entire page instead of the iFrame.
This didn't happen on v74 and I can't get a test case to work (yet), it just fails in our site. (The site hasn't changed since going from v74 to v75, only Chrome has changed)
It appears to work fine the first time but then when you change it again (in our case viewing report drill downs) it causes the entire page (i.e. the iFrame's Parent) to load the src you were trying to load into the iFrame.
It also doesn't matter if you use pure Javascript or (in our case) JQuery, both cause the same issue.
EDIT: After a few hours detective work, I've found the bug. Setting the tag in the iFrame's content causes Chrome to load the iFrame's content into it's parent rather than the iFrame itself.
I've setup a Plunker account with a demo: https://plnkr.co/edit/UQ0gBY?plnkr=legacy&p=info
Just so I can post the link to Plunker, here is the code for the main file & the iframe content
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
function onLoaded() {
// find element
let button = document.getElementById("button");
button.addEventListener("click",function(e){
// Add a random number on the end as a cache buster
document.getElementById('frame-finance-custom').src = 'test2.html?rnd=' + Math.random();
},false);
};
document.addEventListener('DOMContentLoaded', onLoaded, false);
</script>
</head>
<body>
<div>IFrame Src Changing Test</div>
<div>
<div id="div-frame-finance-custom" style="float:left;width:33%">
<iframe id="frame-finance-custom" name="frame-finance-custom" class="iframe"
style="border:1px solid black; width: 100%; height: 350px; overflow-y: scroll; vertical-align: top;">
no data
</iframe>
</div>
<div style="float:left;margin-left:1em;">
Detail: Loading an iframe page with a <Base> tag in it with target set to "_parent" will cause any refresh of that frame to replace the parent document<BR>
<BR>Instruction: <UL><LI>Click the 'Update Frame' Button, this will load test2.html into the frame. <LI>Click it again & it will replace the iframe's parent with the content of the iFrame.</UL>
<BR>Confirmation: Remove the <Base> tag from the header of test2.html & reload, it will work as expected.
</div>
</div>
<br clear=both>
<div>
<button id="button">
Update Frame
</button>
</div>
</body>
</html>
IFrame Content (test2.html):
<!DOCTYPE html>
<html lang="en">
<head>
<base target="_parent"/>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>This is the frame content</div>
</body>
</html>
Note, using their new layout it doesn't work, but using their legacy layout it does. Feel free to save the files locally and use chrome directly too.
Ok, so this turned out to be a bug in Chrome rather than anything else, so yes, strictly not a SO question, but seeing as SO ranks so well in Google (other search engines are available), I thought it better to leave it here as a solution rather than simply delete it, just incase anyone else has a similar problem.
The reason is outlined as an edit in my question, the solution is to remove the <base target="_parent"> tag from the iFrame and programatically add the 'target="_parent"' attribute to any links in the iFrame.
We do this via jQuery, I'm sure its just as easy via vanilla Javascript.
$('a').attr('target','_parent');
Add that to the javascript that runs when a page has loaded and it'll replace add target="_parent" to any links on the page.
e.g.
<script>
function onLoaded() {
// find all links and add the target attribute
$('a').attr('target','_parent');
};
document.addEventListener('DOMContentLoaded', onLoaded, false);
</script>
As #Kaiido says in his comment, its apparently fixed in Chrome v77, but this isn't the current (as of June 2019) stable release, so we've had to add the workaround into production so that our CRM works with Chrome v75. Thanks to #Kaiido for confirming that.

Remove style of html tag of iFrame

I've got a iFrame on my page which is coming in from an external source and when the iFrame is loaded it's coming in with it's 'own' styling classes and I'm trying to remove one of the classes what it has. So when the iFrame loads the HTML looks like this:
<iframe style="background-color:#fff !important" id="myFrame" src="http://salonspy.co.uk/widget?i=72108" frameborder="0" height="270" width="320">
#document
<html> <!---THIS IS THE TAG I'M TRYING TO GET A HANDLE ON!-->
<head>...</body>
<body>...</body>
</html>
</iframe>
The html tag has a background color applied to it (by the external css) and I'm trying to remove this background-color (or apply a transparent one) but I can't seem to get 'hold' of this tag.
I've got some jQuery that waiting for the iFrame to load but I don't know what to enter to apply this new style.
$(function() {
$("#myFrame").bind("load",function(){
//$(this).contents().find("[tokenid=" + token + "]").html();
alert("iFrame loaded");
//$(this).contents().find("html").css("background-color","white");
var src = $('#myFrame>html').html();
alert(src);
});
});
Could someone assist please?
Thanks.
Moving from comment to answer.
If you are accessing salonspy.co.uk from within the same origin, you may access the HTML contents by calling the inner HTML:
Plain JavaScript
document.getElementById('myFrame').contentWindow.document.bo‌​dy.innerHTML
jQuery
$('#myFrame').contents().find("html").html();

Jquery get iframe document and set another iframe

I am attempting to create some functionality which will get and set the document of an iframe. I have been unsucessful at performing this with jquery.
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js" ></script></head>
<body>
<iframe sandbox="allow-same-origin allow-scripts" id='a' height="700" width="700" src="http://localhost:8181/website"></iframe>
<iframe sandbox="allow-same-origin allow-scripts" id='b' height="700" width="700" src="http://localhost:8181/website"></iframe>
</body>
</html>
When the page loads I need to navigate around in iframe a. At which point I will use javascript or jquery to take the doucment of A and replace B's document with it. Is this even possible? I don't necessarily need to use iframes if there are other options.
Scenario:
1. Page loads, iframe a & b are rendered
2. User navigates inside iframe A to different pages
**below this is functionality I cannot figure out
3. User clicks button to take DOM from iframe a and replace the DOM for Iframe b
This will essentially set the content of iframe b to be where the user had navigated in iframe a
There is a question about jquery and iframe.
The .contents() method can be used to get the content document of an iframe, if the iframe is on the same domain as the main page.
This should work:
var theHtmlStringToSet = $('#frameA').contents().find('body').html();
$('#frameB').contents().find('body').html(theHtmlStringToSet);

dynamic IFRAME content - how to get the access to that IFRAME?

I'm loading a content dynamically to the <iframe>
<iframe style='border:none;' id='abc' src="http://localhost:39217/Home/GetContent/some_dynamic_code"></iframe>
after a success response, in that iframe is that content
<html>
<head>
<script type="text/javascript">
function onPageLoad() {
if (document.readyState === "complete") {
var cont = document.getElementById("abc");
alert(cont);
}
}
</script>
</head>
<body onload='onPageLoad()'>
<a target="_blank" href='http://lorem'>
<img class='abc' style='max-width:300px; max-height: 38px;' alt='' src='/Images/image.png' />
</a>
</body>
</html>
That iframe will be using outside my site (by users), but I want to have the ability to change the <img> src. But, I need also to change the width/height of the iframeafter I change the image. So, how can I get the access to that iframe using JS ? That code above alerts me null
I made an example for you here: http://jsfiddle.net/KRaWU/2/
I use jQuery to achieve that and I suggest you do the same.
// this will find a button within an iframe
var obj = $('iframe').contents().find('.actionButton').find('input[type="submit"]');
// this will change the value of the button, and you can see that the text is changed.
obj.attr('value', 'LOG ME IN');
You can analogically find an img and change its src.
JS interaction between iFrames and their parents is for what I know impossible or at least troublesome. I know there is somewhere a property window.frames and maybe even frame.parent but in general, JS interaction like that is impossible. I think you should consider another type of solution (like an ajaxcall maybe, if that could satisfy your needs).

How do I change the URL of the "parent" frame?

I have a website which I host myself. I do not have a static IP address so I have all traffic for my domain forwarded with masking to my DDNS account. The resulting page looks like this...
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>mydomianname.com</title>
</head>
<frameset rows="100%,*" border="0">
<frame src="http://myddns.dyndns.org/mydomainname" frameborder="0" />
<frame frameborder="0" noresize />
</frameset>
</html>
How can I update the URL of the "parent" frame as users navigate within the "child" frame?
UPDATE: Success?
I have tried doing this with javascript but had an issue getting the correct href to my javascript function with out having adverse side effects (having two windows open up, having my main window go to the wrong location, or making it so the back button didn't work right). All I needed was an attribute of my a tag to hold a value that I could use in my javascript, but would do nothing else at all. Adding the attributed value event though it is not a native attribute to the a tag works great.
The a tag...
<a onclick="url_update(this);" value="test/test.html" href="javascript:void(0);">test link</a>
and the javascript function...
function url_update(element){
base_url = 'http://mydomain.com/';
window.parent.location.href = base_url + element.getAttribute('value');
}
the resulting updated URL is...
http://mydomain.com/test/test.html
... and there are none of the previously mentioned side effects.
The only "side effect" that I would like to fix is display of the link in the info bar at the bottom of a browser window. Right now it says javascript:void(0); because that is what is written in my href attribute, but I would like it to show the updated URL when the link is hovered over... any thoughts?
It would be even better if I could scrap all of this javascript and use IIS 7 URL Rewrite 2.0 to do this instead... but I have yet to master the black art of URL rewriting.
javascript:
window.top.location = 'anther url'
--UPDATE to your updated question
use element.getAttribute('value') instead of element.value
--UPDATE #2
Use the href attribute, however, add a return false; to the onclick function:
<a onclick="url_update(this);return false;" value="test/test.html" href="test/test.html">test link</a>
Once you are doing that, you might aswell skip the value attribute and just use the href property, update your url_update function to use element.href instead of element.value
It's hard to tell from your question exactly which frames are doing what, but if The Scrum Meister's solution works for you, than you can easily implement what you want by adding this to each of your A tags.
target="_top"
Your example modified.
test link
You could also do this with jquery...
On the page where all A tags should have target="_top" you can implement the following jquery code on the page and it will dynamically add the target to all links.
<script language="javascript" type="text/javascript">
$(function()
{
$("A").attr("target","_top");
});
</script>
That is assuming that you have normail A tags with the href attribute, you can get rid of the onclick all together, no other javascript is required with the target solution.
First you need to be on the same domain... otherwise for security reasons you can not change it.
Declare and call this function in your child frame
function change(theUrl){
window.parent.reloadContent(theUrl);
}
In your parent have the following function :
function reloadContent(theUrl){
if (theUrl != ""){
document.getElementById("frameID").src= theUrl ;
}
}

Categories

Resources