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);
Related
How to identify document content which is created under dynamic iframe
code structure
<div id="test" data-parent-url="/test.html" data-iframe-src="/test-header.html" class="sample-header">
// dynamically created iframe element
<iframe style="border-style: none; width: 100%; height: 105px; display: block;" scrolling="no" id="V1__header" src="/test-header.html">
// dynamically loaded document content
</iframe>
</div>
tried:
var ifrme = document.getElementById('V1__header');
var iframeContent = ifrme.contentWindow.document;
var iframeObj = $(iframeContent);
var contentheight = $(iframeObj.find(selector)[0]).height();
ifrme returns null intermittently, Couldnot find the id. Is there any alternative to find the id and the document content which is creted dynamically in code.
if you cant be sure the iframe is loaded, you could wait by testing at time interval:
var timer = setInterval(function(){
if($('#V1__header').length !=0){
clearIntervall(timer);
Identifydoc();
}
},400);
function idnetifyDoc(){
var ifrme = document.getElementById('V1__header');
var iframeContent = ifrme.contentWindow.document;
var iframeObj = $(iframeContent);
var contentheight = $(iframeObj.find(selector)[0]).height();
}
You can use onload callback:
const ifrme = document.getElementById('V1__header');
ifrme.onload = iframeLoaded;
function iframeLoaded() {
//--> logic
}
Add the script inside the body tag.
I'm writing a code which fills dynamically an iframe content. The sample below relies on the document object of the iframe:
function createIFrame() {
var iframe = document.createElement("iframe");
iframe.onload = function() {fillIFrame(iframe);};
}
function fillIFrame(iframe) {
// Creating an "header" element with the embedded Document object.
var ifdocument = iframe.contentDocument;
var header = ifdocument.createElement("header");
header.appendChild(ifdocument.createTextNode("Header."));
ifdocument.body.appendChild(header);
}
If I rewrite the iframe filling this way, using the parent document object:
function fillIFrame(iframe) {
// Using the parent Document object
var header = document.createElement("header");
header.appendChild(document.createTextNode("Header."));
iframe.contentDocument.body.appendChild(header);
}
It still works. Is there any relevant difference between these two approaches?
Objective: Copy a chunk of HTML and send it to a website on another domain.
My problem: The website I'm working on and the website in the iframe are on different domains. I own both of them and have set the Access-Control-Allow-Origin to allow the websites to communicate to each other. However, I can't seem to pass the HTML chunk to the parent window.
I've tried parent.window.postMessage(chunk, http://www.parent-page.com) (chunk is the chunk of HTML code) but I get this error:
Uncaught DataCloneError: Failed to execute 'postMessage' on 'Window': An object could not be cloned.
I have also tried to use ajax to send a PUT request to the parent window but, I get a 404 error that it cannot find the parent window. *I am running the parent window from my local server.
My Question: Can anyone tell me the best way to send an object, containing HTML code, from an iframe to the parent window given that the two websites are NOT on the same domain?
EDIT: I removed the stuff about a skeleton object as that was out of the scope of the question I was really trying to ask.
Here is what I wrote to solve this. Any constructive criticism is welcome.
Code on parent window's website:
//send a message to the website in the iframe
$("#frame").on("load", function (event) {
var viewContainer = $('#element-highlight');
var iframe = document.querySelector('iframe');
var receiver = iframe.contentWindow;
var location = 'http://www.child-website.com';
event.preventDefault();
receiver.postMessage("sendStructure",location);
});
//listen for a response
window.addEventListener('message', function(event) { //event = onmessage event object
if (~event.origin.indexOf('http://ccook.oegllc.com')) { //indexOf returns a -1 if the searchValue is not found
var structure = event.data;
var container = document.getElementById("element-highlight");
container.innerHTML = structure;
}
}
<script src="../jquery/3.0.0/jquery.min.js"></script>
<body>
<div id="frame-container">
<iframe id="frame" src="http://www.main-site.com" frameborder="0"></iframe>
<div id="element-highlight">
<!-- Store Skeleton Copies here -->
</div>
</div>
</body>
Code on the website that is shown in the iframe:
I can't get the case statement below to look any better.
//listen for command from main-site.com
window.addEventListener('message', function(event) { //event = onmessage event object
if (~event.origin.indexOf('http://www.main-site.com')) { //indexOf returns a -1 if the searchValue is not found
switch(event.data){
case "sendStructure":
var structure = getStructure(),
tempNode = document.createElement("div");
structure.appendTo(tempNode); //appends structure to html document
var str = tempNode.innerHTML; //creates a serilized version of the structure
parent.window.postMessage(str, event.origin); //send structure string to main-site.com
break;
//I reccomend using a case statement if the two sites will be sending more than one message to each other
default:
sendError();
}
}
});
function getStructure(){
//this method creates a skeleton of the course page you are on
//returns a skeleton object
console.log("compiling structure");
var viewFrame = $('body').contents(); //<-change 'body' to whatever element you want to copy
var visible = viewFrame.find('*:not(html body)').filter(':visible');
var overlayElements = visible.map(function (i, el) {
var el = $(el);
var overlayEl = $('<div>');
overlayEl.addClass('highlight').css($.extend({
position: 'absolute',
width: el.outerWidth(),
height: el.outerHeight(),
'z-index': el.css('z-index')
}, el.offset()));
return overlayEl.get();
});
return overlayElements;
}
function sendError(){
console.log("main-website's request could not be understood");
}
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/
I am having an iframe inside a div element which is hidden/display none, I want to get the href attribute of a tag using javascript my code is
HTML
<div id="questions" style="display: none;">
<iframe id="article_frame" width="100%" height="100%">
Click here
</iframe>
</div>
JS
window.onload = function() {
alert("Hello " + window.document.getElementById("article_frame"));
}
But I am getting alert as "Hello null" any solution
Thanks
Thanks All,
I have got the answer with javascript it just simple code
var anchor = document.getElementById('en_article_link').firstChild;
var newLink = anchor.getAttribute("href")+"sid="+sidvalue;
anchor.setAttribute("href", newLink);
Ok i feel this may be a slight overkill but it will get you what you require (the href value of the anchor tag inside the iframe) :
window.onload = function() {
var frame = window.document.getElementById("article_frame");
var myString = frame.childNodes[0].textContent
, parser = new DOMParser()
, doc = parser.parseFromString(myString, "text/xml");
var hrefValue = doc.firstChild.getAttribute('href');
alert("Hello " + hrefValue);
}
I guess it depends on your requirements but another way would be to create a string and then using functions: substring and indexof you could get your value. Here is how you would get the string:
window.onload = function() {
var frame = window.document.getElementById("article_frame");
var elementString = frame.childNodes[0].textContent;
//then perform your functions on the string here
}
Note that you can only access the contents of an iframe that contains a page on the same domain due to the Same-Origin Policy (Wikipedia).
I recommend using jQuery for this. The tricks here are:
Wait for the iframe to finish loading $("#article_frame").ready()
Access the iframe's document $("#article_frame").contents()
From there you're just handling the task at hand:
$("#article_frame").ready(function() {
alert("Hello " + $("#article_frame").contents().find("#en_link").href);
});