Bind to element within an iframe (same domain) - javascript

I've got an iframe which i'm dynamically inserting into the page. Then I want to bind to a button within that iframe to trigger a page refresh on the parent page.
Is this possible? Both are on the same domain.
$('body').append('<iframe id="cacheBuster" src="http://lol.com/system/page.aspx" style="position: absolute; top:0; right:0; width: 20px; height: 20px; background: #fff" frameborder="0"></iframe>');
var cacheIframe = $('#cacheBuster');
cacheIframe.live('mouseover', function() {
$(this).stop().animate({ width : 300, height : 300});
});
cacheIframe.contents().find('#buttonid').live('click',function() {
alert('cleared!');
window.location.reload();
});

I think if you just make:
window.location.reload(); ==> window.parent.location.reload();
you can achieve the described functionality.
although, if the code is running in the outer window then your code should already work because the window in scope is that of the parent. Have you tried it yet?
EDIT:
ok, this is probably easier to do without jquery.
var ifr = document.createElement('iframe');
ifr.src = "http://google.com/";
document.body.appendChild(ifr);
button = ifr.contentDocument.createElement('a');
button.onclick = "window.parent.location.reload();" //you could prob use jquery here
ifr.contentDocument.body.appendChild(button);

Related

User Manipulated Frame - HTML/CSS/JS

How can I make the below frame, once loaded, to allow for the user to drag and scale the size? Is this possible with HTML/CSS/JS?
<script>
var frame;
function addFrame() {
frame = document.createElement('iframe');
frame.height = "200px";
frame.width = "200px";
frame.setAttribute('id', 'superFrame');
document.body.appendChild(frame);
}
function loadGoogle() {
frame.setAttribute('src','http://www.google.com')
}
</script>
Left is what I have, right is what I want but with the user setting the size via dragging the frame.
Image
src Responsive IFrames — The Right Way!
remove width and height attributes
set up a parent div for the iframe
make the containing div responsive, and the iframe with the following size/positioning rules:
iframe {
position: absolute;
top:0;
left: 0;
width: 100%;
height: 100%;
}

prevent temporary popup from closing onmouseover

I have a text in a table that shows a popup text onmouseover, and this popup disappears 1 second after onmouseout.
I want this popup not to disappear if the mouse is moved over the popup (that is, if the mouse is moved away from the original table text but over the popup). An example of what i want to achieve can be seen in http://www.pnas.org/content/current , scroll down a little bit and place the mouse over an article title.
Can I include a function on the popup to prevent its closing?
I know that almost everything can be achieved, but I'm an newbie amateur, so dont waste your time if the solution is complex.
My code for the popup:
var popup;
function lopen() {
if (this.element == null) {
this.element = document.createElement('div');
this.element.id = "myPopup";
this.element.innerHTML = "new text";
this.element.style = "position: absolute; top: 650px; left: 400px; width: 200px; height: 200px; background-color: #ccc;";
}
document.body.appendChild(this.element);
}
var timeoutID;
function delayedlclose() {
timeoutID = window.setTimeout(lclose, 1000);
}
function lclose () {
document.body.removeChild(this.element);
}
The link for displaying the popup is in a html table:
<tr><td><a onmouseover="lopen()" onmouseout="delayedlclose()">Show</td></tr>
you could move your onmouseout event handler from the <a> to the <div id='myPopup'>

Temporarily disable all onclick events and bind them back

How to disable all onclick events on a page, bind my custom function, and after the execution enable all the previous events?
I'm building a bookmarklet, which should work on any already loaded page and I'm using jQuery to handle my custom logic (the page is jquerified after it is loaded). Note, that I don't have any control which events and when are being bound.
Currently the best stable solution i found is to unbind the events, bind by custom function preventing the default action and then, reload the page. This works, however I want to avoid the reload. A partial workaround would be to reload the page and scroll to the previous position (how to achieve this effect?). Some possible solution would use iframes, but I'd prefer to avoid this.
it's easier to lay a div-element over all... something like
CSS
.noclick {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 9999; /* or maybe higher */
background-color: transparent;
}
jQuery
jQuery(document).ready(function() {
jQuery('body').append('<div class="noclick" />');
});
A nice way I've seen it done, and done it myself is to use a modal 'mask' overlay.
The grayed out transparent mask that covers the entire page, except for the element you're interacting with, eg. modal popup window.
One more way is to use the jQuery BlockUI plugin.
You can reassign the onclick to another property and than override it.
Example with one element
var btn = document.getElementById("button");
btn._onclick = btn.onclick;
btn.onclick = function(){ return false; };
and when you want to transfer it back to the original event
var btn = document.getElementById("button");
if (btn._onclick) {
btn.onclick = btn._onclick;
btn._onclick = null;
}
It depends on whether your onclick event is dependent on the element being clicked (i.e. whether it needs to know which element was clicked):
If it's independent, then you can just add an event handler to the body element or other parent (because the parent event gets called first, then the child, which is what you want):
$('body').click(function() { /* your code here */});
It it is dependent on the the element, then you can access the previous onclick event code that has been registered in the 'click' property of element which is being clicked, so something like this (probably being a little more specific with the selectors):
$('body *').each(function() {
var previousClick = this.click;
this.click = null; // remove previous
$(this).click(function() { /* your code here */});
$(this).click(function() { previousClick();}); // run the code that was already there.
})
Some modification algorhythm's answer.
The idea is to "cover" the link by a transparent element. You can use a pseudo element (e.g. :after).
To prevent "tab key" set tabindex:
<a href="..." tabindex="-1">
Mark link with a class "disabled" on click:
$('a').on('click', function(){ $(this).addClass('disabled') })
Add css:
a.disabled:after {
position: absolute;
content: "";
display: block;
background: white;
opacity: 0.5; // optional
z-index: 999;
left: 0;
top: 0;
bottom: 0;
right: 0;
}
$('a').on('click', function(){ $(this).addClass('disabled') });
a.disabled:after {
position: absolute;
content: "";
display: block;
background: white;
opacity: 0.5; // optional
z-index: 999;
left: 0;
top: 0;
bottom: 0;
right: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a hreh="#" tabindex="-1">The Link</a>

How do I put additional content into fancybox iframe

I am having trouble figuring out how to put some additional content into an iframe I am displaying with fancybox.
My basic setup:
$('.fancybox').fancybox({
'autoScale': false,
'transitionIn': 'none',
'transitionOut': 'none',
'type': 'iframe',
'padding': 0,
'closeClick': false,
helpers: {
overlay: {
closeClick: false
}
}
<a class="fancybox" href ="http://my-iframe.example"/><img src="myimage.jpg" width="x" height="y" /></a>
So I need to put a couple of custom buttons and another javascript widget in under the iframe but on top of the background overlay.
I am just having trouble grasping what might be the best way to do this. I suppose I could put this content in a div and then display that div once the fancybox has completed loading? I am having trouble with the callback function though, so I just need some general direction on the best way to do this.
if using fancybox v2.x try with the call back afterShow to append the additional content to the .fancybox-inner selector like :
afterShow: function(){
var customContent = "<div class='customHTML'>My custom content</div>"
$('.fancybox-inner').append(customContent);
}
use CSS to style and position such additional content, e.g.
.customHTML {
position: absolute;
z-index: 99999; /* this place the content over the fancybox */
bottom: 0px;
right: 0;
background: #f2f2f2;
width: 200px;
height: 100px;
display: block;
}
If the iframe is from same domain then you can access the contents with contents()
$('#fancybox-frame').contents().find('h1').prepend('<a>Button</a>');
This will not be possible for cross domain cases.
If your case also require javascript widgets to be injected, that might be hard for you with injecting into DOM, you can better go for a different div shown along with iframe.
For that just make the div show up on onComplete event or onStart event, and then position it according to fancybox position, height etc.
To make it above overlay, give it some positioning, you should obviously, and give a higher z-index that overlay.
#fancybox-overlay {
display: none;
left: 0;
position: absolute;
top: 0;
width: 100%;
z-index: 1100;
}
#mydiv{
position:absolute;
z-index:1101;
}
You can try data attributes (data-fancybox-title) and initialize fancybox to place it to the top like this:
$(".fancybox-video").fancybox({
helpers : {
title: {
type: 'inside',
position: 'top'
}
}
});
You can find more info here: Fancybox Instructions
I needed a solution for FancyBox 1.3 and in my case I used the onComplete event to update the contents
<a class="iframe" id="fancybox-preview-card" href="about:blank"></a>
$("#fancybox-preview-card").fancybox({
'height': screen.availHeight * 0.9,
'width' : 600,
'onComplete' : updatePreviewContent,
'overlayShow': false
});
...
var contentUpdated = false;
function previewEcardTemplate() {
contentUpdated = false;
$("#fancybox-preview-card").attr("href", "about:blank").trigger("click");
}
function updatePreviewContent() {
// if content has already been updated then back out
if (contentUpdated)
return;
contentUpdated = true;
$.get('/template/mytemplate.htm', function (data) {
// Any mods to the html can go here
var ifrm = document.getElementById('fancybox-frame');
ifrm = (ifrm.contentWindow) ? ifrm.contentWindow : (ifrm.contentDocument.document) ? ifrm.contentDocument.document : ifrm.contentDocument;
ifrm.document.open();
ifrm.document.write(data);
ifrm.document.close();
})
}

make iframe height dynamic based on content inside- JQUERY/Javascript

I am loading an aspx web page in an iframe. The content in the Iframe can be of more height than the iframe's height. The iframe should not have scroll bars.
I have a wrapper div tag inside the iframe which basically is all the content. I wrote some jQuery to make the resize happen :
$("#TB_window", window.parent.document).height($("body").height() + 50);
where
TB_window is the div in which the Iframe is contained.
body - the body tag of the aspx in the iframe.
This script is attached to the iframe content. I am getting the TB_window element from the parent page. While this works fine on Chrome, but the TB_window collapses in Firefox. I am really confused/lost on why that happens.
You can retrieve the height of the IFRAME's content by using:
contentWindow.document.body.scrollHeight
After the IFRAME is loaded, you can then change the height by doing the following:
<script type="text/javascript">
function iframeLoaded() {
var iFrameID = document.getElementById('idIframe');
if(iFrameID) {
// here you can make the height, I delete it first, then I make it again
iFrameID.height = "";
iFrameID.height = iFrameID.contentWindow.document.body.scrollHeight + "px";
}
}
</script>
Then, on the IFRAME tag, you hook up the handler like this:
<iframe id="idIframe" onload="iframeLoaded()" ...
I had a situation a while ago where I additionally needed to call iframeLoaded from the IFRAME itself after a form-submission occurred within. You can accomplish that by doing the following within the IFRAME's content scripts:
parent.iframeLoaded();
A slightly improved answer to Aristos...
<script type="text/javascript">
function resizeIframe(iframe) {
iframe.height = iframe.contentWindow.document.body.scrollHeight + "px";
}
</script>
Then declare in your iframe as follows:
<iframe onload="resizeIframe(this)" ...
There are two minor improvements:
You don't need to get the element via document.getElementById - as you already have it in the onload callback.
There's no need to set the iframe.height = "" if you're going to reassign it in the very next statement. Doing so actually incurs an overhead as you're dealing with a DOM element.
Edit:
If the content in the frame is always changing then call:
parent.resizeIframe(this.frameElement);
from within the iframe after the update. Works for same origin.
Or to auto detect:
// on resize
this.container = this.frameElement.contentWindow.document.body;
this.watch = () => {
cancelAnimationFrame(this.watcher);
if (this.lastScrollHeight !== container.scrollHeight) {
parent.resizeIframeToContentSize(this.frameElement);
}
this.lastScrollHeight = container.scrollHeight;
this.watcher = requestAnimationFrame(this.watch);
};
this.watcher = window.requestAnimationFrame(this.watch);
I found that the accepted answer didn't suffice, since X-FRAME-OPTIONS: Allow-From isn't supported in safari or chrome. Went with a different approach instead, found in a presentation given by Ben Vinegar from Disqus. The idea is to add an event listener to the parent window, and then inside the iframe, use window.postMessage to send an event to the parent telling it to do something (resize the iframe).
So in the parent document, add an event listener:
window.addEventListener('message', function(e) {
var $iframe = jQuery("#myIframe");
var eventName = e.data[0];
var data = e.data[1];
switch(eventName) {
case 'setHeight':
$iframe.height(data);
break;
}
}, false);
And inside the iframe, write a function to post the message:
function resize() {
var height = document.getElementsByTagName("html")[0].scrollHeight;
window.parent.postMessage(["setHeight", height], "*");
}
Finally, inside the iframe, add an onLoad to the body tag to fire the resize function:
<body onLoad="resize();">
Add this to the iframe, this worked for me:
onload="this.height=this.contentWindow.document.body.scrollHeight;"
And if you use jQuery try this code:
onload="$(this).height($(this.contentWindow.document.body).find(\'div\').first().height());"
you could also add a repeating requestAnimationFrame to your resizeIframe (e.g. from #BlueFish's answer) which would always be called before the browser paints the layout and you could update the height of the iframe when its content have changed their heights. e.g. input forms, lazy loaded content etc.
<script type="text/javascript">
function resizeIframe(iframe) {
iframe.height = iframe.contentWindow.document.body.scrollHeight + "px";
window.requestAnimationFrame(() => resizeIframe(iframe));
}
</script>
<iframe onload="resizeIframe(this)" ...
your callback should be fast enough to have no big impact on your overall performance
There are four different properties you can look at to get the height of the content in an iFrame.
document.documentElement.scrollHeight
document.documentElement.offsetHeight
document.body.scrollHeight
document.body.offsetHeight
Sadly they can all give different answers and these are inconsistant between browsers. If you set the body margin to 0 then the document.body.offsetHeight gives the best answer. To get the correct value try this function; which is taken from the iframe-resizer library that also looks after keeping the iFrame the correct size when the content changes,or the browser is resized.
function getIFrameHeight(){
function getComputedBodyStyle(prop) {
function getPixelValue(value) {
var PIXEL = /^\d+(px)?$/i;
if (PIXEL.test(value)) {
return parseInt(value,base);
}
var
style = el.style.left,
runtimeStyle = el.runtimeStyle.left;
el.runtimeStyle.left = el.currentStyle.left;
el.style.left = value || 0;
value = el.style.pixelLeft;
el.style.left = style;
el.runtimeStyle.left = runtimeStyle;
return value;
}
var
el = document.body,
retVal = 0;
if (document.defaultView && document.defaultView.getComputedStyle) {
retVal = document.defaultView.getComputedStyle(el, null)[prop];
} else {//IE8 & below
retVal = getPixelValue(el.currentStyle[prop]);
}
return parseInt(retVal,10);
}
return document.body.offsetHeight +
getComputedBodyStyle('marginTop') +
getComputedBodyStyle('marginBottom');
}
Other answers were not working for me so i did some changes. Hope this will help
$('#iframe').on("load", function() {
var iframe = $(window.top.document).find("#iframe");
iframe.height(iframe[0].ownerDocument.body.scrollHeight+'px' );
});
Just in case this helps anyone. I was pulling my hair out trying to get this to work, then I noticed that the iframe had a class entry with height:100%. When I removed this, everything worked as expected. So, please check for any css conflicts.
I am using jQuery and the code below working for me,
var iframe = $(window.top.document).find("#iframe_id_here");
iframe.height(iframe.contents().height()+'px' );
You can refer related question here - How to make width and height of iframe same as its parent div?
To set dynamic height -
We need to communicate with cross domain iFrames and parent
Then we can send scroll height/content height of iframe to parent window
And codes - https://gist.github.com/mohandere/a2e67971858ee2c3999d62e3843889a8
Rather than using javscript/jquery the easiest way I found is:
<iframe style="min-height:98vh" src="http://yourdomain.com" width="100%"></iframe>
Here 1vh = 1% of Browser window height. So the theoretical value of height to be set is 100vh but practically 98vh did the magic.
All other answers are correct but what if the iframe has some dynamic content like a map that loads later and dynamically changes your iframe scroll height. This is how I achieved it.
var iFrameID = document.getElementById('idIframe');
intval = setInterval(function(){
if(iFrameID.scrollHeight == iFrameID.contentWindow.document.body.scrollHeight){
clearInterval(intval);
}else{
iFrameID.height = iFrameID.contentWindow.document.body.scrollHeight + "px";
}
},500)
I simply wrap the code inside setInterval which matches the iframe scroll height with iframe content scroll height then clear the interval.
in my project there is one requirement that we have make dynamic screen like Alignment of Dashboard while loading, it should display on an entire page and should get adjust dynamically, if user is maximizing or resizing the browser’s window.
For this I have created url and used iframe to open one of the dynamic report which is written in cognos BI.In jsp we have to embed BI report. I have used iframe to embed this report in jsp. following code is working in my case.
<iframe src= ${cognosUrl} onload="this.style.height=(this.contentDocument.body.scrollHeight+30) +'px';" scrolling="no" style="width: 100%; min-height: 900px; border: none; overflow: hidden; height: 30px;"></iframe>
I found the answer from Troy didn't work. This is the same code reworked for ajax:
$.ajax({
url: 'data.php',
dataType: 'json',
success: function(data)
{
// Put the data onto the page
// Resize the iframe
var iframe = $(window.top.document).find("#iframe");
iframe.height( iframe[0].contentDocument.body.scrollHeight+'px' );
}
});
To add to the chunk of window that seems to cut off at the bottom, especially when you don't have scrolling I used:
function resizeIframe(iframe) {
var addHeight = 20; //or whatever size is being cut off
iframe.height = iframe.contentWindow.document.body.scrollHeight + addHeight + "px";
}
This one is useful when you require a solution with no jquery. In that case you should try adding a container and set a padding to it in percentages
HTML example code:
<div class="iframecontainer">
<iframe scrolling="no" src="..." class="iframeclass"width="999px" height="618px"></iframe>
</div>
CSS example code:
.iframeclass{
position: absolute;
top: 0;
width: 100%;
}
.iframecontainer{
position: relative;
width: 100%;
height: auto;
padding-top: 61%;
}
The simple solution is to measure the width and height of the content area, and then use those measurements to calculate the bottom padding percentage.
In this case, the measurements are 1680 x 720 px, so the padding on the bottom is 720 / 1680 = 0.43 * 100, which comes out to 43%.
.canvas-container {
position: relative;
padding-bottom: 43%; // (720 ÷ 1680 = 0.4286 = 43%)
height: 0;
overflow: hidden;
}
.canvas-container iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
A slightly improved answer to BlueFish...
function resizeIframe(iframe) {
var padding = 50;
if (iframe.contentWindow.document.body.scrollHeight < (window.innerHeight - padding))
iframe.height = iframe.contentWindow.document.body.scrollHeight + "px";
else
iframe.height = (window.innerHeight - padding) + "px";
}
This takes in consideration the height of the windows screen(browser, phone) which is good for responsive design and iframes that have huge height.
Padding represents the padding you want above and below the iframe in the case it goes trough whole screen.
jQuery('.home_vidio_img1 img').click(function(){
video = '<iframe src="'+ jQuery(this).attr('data-video') +'"></iframe>';
jQuery(this).replaceWith(video);
});
jQuery('.home_vidio_img2 img').click(function(){
video = <iframe src="'+ jQuery(this).attr('data-video') +'"></iframe>;
jQuery('.home_vidio_img1 img').replaceWith(video);
jQuery('.home_vidio_img1 iframe').replaceWith(video);
});
jQuery('.home_vidio_img3 img').click(function(){
video = '<iframe src="'+ jQuery(this).attr('data-video') +'"></iframe>';
jQuery('.home_vidio_img1 img').replaceWith(video);
jQuery('.home_vidio_img1 iframe').replaceWith(video);
});
jQuery('.home_vidio_img4 img').click(function(){
video = '<iframe src="'+ jQuery(this).attr('data-video') +'"></iframe>';
jQuery('.home_vidio_img1 img').replaceWith(video);
jQuery('.home_vidio_img1 iframe').replaceWith(video);
});
Sample using PHP htmlspecialchars() + check if height exists and is > 0:
$my_html_markup = ''; // Insert here HTML markup with CSS, JS... '<html><head></head><body>...</body></html>'
$iframe = '<iframe onload="if(this.contentWindow.document.body.scrollHeight) {this.height = this.contentWindow.document.body.scrollHeight;}" width="100%" src="javascript: \''. htmlspecialchars($my_html_markup) . '\'"></iframe>';
Script
<script type="text/javascript" language="javascript">
$(document).ready(function(){
var height = $(window).height();
$('.myIframe').css('height', height - 200);
});
</script>
iframe
<iframe class="myIframe" width="100%"></iframe>
It's working in my case.
$(document).height() // - $('body').offset().top
and / or
$(window).height()
See Stack Overflow question How to get the height of a body element.
Try this to find the height of the body in jQuery:
if $("body").height()
It doesn't have a value if Firebug. Perhaps that's the problem.
just make iframe container position:absolute and iframe will automatically change its height according to its content
<style>
.iframe-container {
display: block;
position: absolute;
/*change position as you need*/
bottom: 0;
left: 0;
right: 0;
top: 0;
}
iframe {
margin: 0;
padding: 0;
border: 0;
width: 100%;
background-color: #fff;
}
</style>
<div class="iframe-container">
<iframe src="http://iframesourcepage"></iframe>
</div>

Categories

Resources