I have a web application in which I have a bunch of iFrame from with source from other tools.
Now the user should have the possibility to open the iframe content in a new window / new tab, normaly I would simply add something like this:
function onButtonClick() { var src = $('#iframe').prop('src');
windows.open(src, "_blank"); }
But his would only open a new version of my iFrame context, e.g. if a user open a page in the iframe or clicked on something and javascript changed something within my iframe, the user would be loosing this value..
So, can I make a iframe Content to a new window content without loosing the dynamic state of the website within my iframe?
You cannot move around iframes between different windows without reloading, because the spec says the attributes must be reevaluated:
When an iframe element is inserted into a document that has a browsing context, the user agent must create a nested browsing context, and then process the iframe attributes for the "first time".
-- https://html.spec.whatwg.org/multipage/embedded-content.html#the-iframe-element
(via https://bugzilla.mozilla.org/show_bug.cgi?id=254144#c97)
Old answer:
// edit: Does not work as expected, since the iframe is reloaded on move and the original src is restored.
It is easy enough if you move the iframe out of the current page:
<button id="example-button">open in new window</button>
<div id="example-container">
<iframe id="example-iframe" src="https://example.com/">
</iframe>
</div>
document.getElementById('example-button').addEventListener('click', function (ev) {
ev.preventDefault();
var win = open('about:blank');
var iframe = document.getElementById('example-iframe');
// the popup might not be immediately available:
setTimeout(function () {
var body = win.document.body;
body.style.padding = 0;
body.style.margin = 0;
body.appendChild(iframe);
iframe.style.position = 'fixed';
iframe.style.padding = 0;
iframe.style.margin = 0;
iframe.style.width = '100%';
iframe.style.height = '100%';
iframe.style.border = 0;
}, 0);
// move the iframe back if the popup in closed
win.addEventListener('beforeunload', function () {
document.getElementById('example-container').appendChild(iframe);
iframe.style.position = '';
iframe.style.padding = '';
iframe.style.margin = '';
iframe.style.width = '';
iframe.style.height = '';
iframe.style.border = '';
});
});
Example: http://jsfiddle.net/cpy2jykv/1/
Related
Today I did a my text editor in iframe. I know that values from iframe doesn't send to database. My first idea relies on sending the values from iframe to the div, and that div data send to DataBase with the respective text formats.
function wlaczTrybEdycji(){
edytorTextowy.document.designMode = "On";
}
function execCmd(command){
edytorTextowy.document.execCommand(command, false, null);
}
function przeniesDane(){
var ramka = document.getElementById("ramka");
var dodiv = document.getElementById("daneIframe");
dodiv == ramka;
}
.textarea2{
width: 700px;
float: left;
height: 240px;
border: 2px solid black;
clear: both;
padding: 5px;
}
<body onload="wlaczTrybEdycji();">
<form action="" method="post">
<div class="EdytorTextowy">
<div class="przyciskiTextEdytor">
<button onclick="execCmd('bold');">BOLD</button>
</div>
<iframe name="edytorTextowy" class="textarea2" id="ramka"></iframe>
<div id="daneIframe">
</div>
<button type="submit" name="wyslijText">WYSLIJ</button><!-- here send from "daneIframe" to DB (PHP)-->
</div>
</form>
</body>
One important thing to understand about what you're doing is that the browser has rules about Cross-document communication.
A page inside an iframe is not allowed to access or modify the DOM of its parent and vice-versa unless both have the same origin. So putting it in a different way: document or script loaded from one origin is prevented from getting or setting properties of a document from another origin.
Here's the docs on Same-Origin Policy from MDN.
If the iframe and the page that loads it are of the same origin you should be able to do exactly what you're trying to do just fine. If not, then these documents need to be made available in the same origin to do so.
Hmm I understand now! You can get elements with ajax or javascript like so :
JavaScript for the Example
The JavaScript displayed here is just an example to show how to access to iframe elements.
// attach handlers once iframe is loaded
document.getElementById('ifrm').onload = function() {
// get reference to form to attach button onclick handlers
var form = document.getElementById('demoForm');
// set height of iframe and display value
form.elements.button1.onclick = function() {
var ifrm = document.getElementById('ifrm');
var ht = ifrm.style.height = '160px';
this.form.elements.display.value = 'The iframe\'s height is: ' + ht;
}
// increment and display counter variable contained in iframed document
form.elements['button2'].onclick = function() {
// get reference to iframe window
var win = document.getElementById('ifrm').contentWindow;
var counter = ++win.counter; // increment
this.form.elements['display'].value = 'counter in iframe is: ' + counter;
}
// reference form element in iframed document
form.elements.button3.onclick = function() {
var re = /[^-a-zA-Z!,'?\s]/g; // to filter out unwanted characters
var ifrm = document.getElementById('ifrm');
// reference to document in iframe
var doc = ifrm.contentDocument? ifrm.contentDocument: ifrm.contentWindow.document;
// get reference to greeting text box in iframed document
var fld = doc.forms['iframeDemoForm'].elements['greeting'];
var val = fld.value.replace(re, '');
// display value in text box
this.form.elements.display.value = 'The greeting is: ' + val;
}
form.elements.button4.onclick = function() {
// get reference to iframe window
var win = document.getElementById('ifrm').contentWindow;
win.clearGreeting(); // call function in iframed document
}
}
Or you can do something like this in jquery :
var content=$("iframe").contents().find('body').html();
//alert elements in iframe or show elements as a response in and div
alert(content);
I would like to record audio and share it without leaving a website.The code works on https://news.ycombinator.com/ which looks like this: http://prntscr.com/etyzgz
But it does not work on the site I want: www.zhihu.com
The button stays at the bottom of the page and the widget does not load after clicking it.
Here is the code:
(function() {
'use strict';
// Your code here...
/*--- Create a button in a container div. It will be styled and
positioned with CSS.
*/
var zNode = document.createElement ('div');
zNode.setAttribute ('id', 'myContainer');
zNode.style.position = 'fixed';
zNode.style.top = 50;
zNode.style.right = 50;
zNode.innerHTML = '<button id="myButton" type="button">use clyp to send voice message</button>';
document.body.appendChild(zNode);
//--- Activate the newly added button.
document.getElementById ("myButton").addEventListener('click',function(){
var iframe = document.createElement ('iframe');
iframe.src = "https://clyp.it/recording-widget";
iframe.style.width = 400;
iframe.style.height = 400;
document.getElementById ("myContainer").appendChild (iframe);
});
})();
I want to know how I can open a series of urls in one tab. I have a list of urls, and I just want to open each one so its contents will be cached, just using one open tab so I don't end up with dozens of open tabs.
Use ** iframes ** one for each URL.
They can be made borderless using CSS if desired.
This is the my solution for your problem:
Html
<button onclick="changeURL()">
Change URL
</button>
Javascript
var listOfURL = ["https://www.google.es",
"https://www.stackoverflow.com",
"https://www.youtube.com"
];
var indexURL = 0;
var iframe = document.createElement("IFRAME");
function changeIndexURL() {
indexURL += 1;
if (indexURL >= listOfURL.length) {
indexURL = 0;
}
}
function changeURL() {
iframe.setAttribute("src", listOfURL[indexURL]);
iframe.style.width = 640 + "px";
iframe.style.height = 480 + "px";
document.body.appendChild(iframe);
changeIndexURL();
}
changeURL();
I'm new to HTML and Javascript. I'm trying to write a Javascript function to print the content of an (hidden) iframe in order to print documents (to the user, seemingly) without opening them.
I based the function on the example I found here: https://developer.mozilla.org/en-US/docs/Printing#Print_an_external_page_without_opening_it
Printing the content works fine but the trouble is removing the iframe from the document after the printing has finished. This is what my code looks like now.
function closePrint () {
var element = document.getElementById("printFrame");
element.parentNode.removeChild(element);
}
function setPrint () {
this.contentWindow.__container__ = this;
this.contentWindow.onbeforeunload = setTimeout(closePrint, 100);
this.contentWindow.onafterprint = setTimeout(closePrint, 100);
this.contentWindow.focus(); // Required for IE
this.contentWindow.print();
}
function printPage (sURL) {
var oHiddFrame = document.createElement("iframe");
oHiddFrame.onload = setPrint;
oHiddFrame.width = 0;
oHiddFrame.height = 0;
oHiddFrame.style.position = "fixed";
oHiddFrame.style.right = "0";
oHiddFrame.style.bottom = "0";
oHiddFrame.id = "printFrame";
oHiddFrame.src = sURL;
document.body.appendChild(oHiddFrame);
}
I changed two lines in the example from
this.contentWindow.onbeforeunload = closePrint;
this.contentWindow.onafterprint = closePrint;
to
this.contentWindow.onbeforeunload = setTimeout(closePrint, 100);
this.contentWindow.onafterprint = setTimeout(closePrint, 100);
As it didn't remove the iframes without the timeout.
This works fine in both IE11 and Chrome, but in IE compitability mode (which I think emulates IE7) it gives me an error "Not implemented" when I try to use setTimeout.
So my question is, is there another way to run the closePrint function after a timeout or some other way to remove the iframe from the document when I've printed the content? Any help is appreciated.
after printing, leave the iframe on document.body. When you need to add your next iframe, first run a check for its presence ~ if its present, remove it then (first two lines).
myfunction() {
const iframe = document.querySelector('iframe');
if (iframe) iframe.parentNode.removeChild(iframe);
const i = document.createElement('iframe');
i.style.display = 'none';
i.src = this.study.DocumentUrl;
document.body.appendChild(i);
document.querySelector('iframe').contentWindow.focus();
document.querySelector('iframe').contentWindow.print();
}
I created a simple bookmarklet to append 3 invisible iframe's to the current document looking like this:
javascript: (function() {
var link = window.location.href;
var desktop = link.replace(".com", ".com/purge");;
var mobile = link.replace(".com", ".com/mpurge");
var tablet = link.replace(".com", ".com/tpurge");
var platforms = [desktop,tablet,mobile];
for (i = 0;i<platforms.length; i++){
ifrm = document.createElement("IFRAME");
ifrm.setAttribute("src", platforms[i]);
ifrm.style.width = 0+"px";
ifrm.style.height = 0+"px";
document.body.appendChild(ifrm);
if(i==platforms.length-1){
ifrm.onload = function(){
location.reload();
}
}
}
})();
what i want to do its to refresh the page im at after the third iframe is loaded but for some reason i cant get this one to work, any idea why?
thx!
i will never be == platforms.length inside of loop, because your loop condition is i<platforms.length.
Make it i == platforms.length - 1 or take reloading outside of the loop