How to get a dom element in a new window? - javascript

A simple task in JavaScript is to open a new window and writing inside. But I need to write in a dom element, a div with an ID.
var novoForm = window.open("somform.html", "wFormx", "width=800,height=600,location=no,menubar=no,status=no,titilebar=no,resizable=no,");
Than I try something...
var w = novoForm.innerWidth;
var h = novoForm.innerHeight;
novoForm.document.getElementById("monitor").innerHTML = 'Janela: '+w+' x '+h;
I did it to see if the object "novoForm" is valid. But nothing is written in "monitor" div. I also try using onload event with no success. I'm wondering if it's some security restriction or am I missing something...

You've done it right, but you do need to be sure to use onload (or poll), because it takes a moment for the page to get loaded in the new window.
Here's a full working example: Live Copy | Source
(function() {
document.getElementById("theButton").onclick = function() {
var novoForm = window.open("http://jsbin.com/ugucot/1", "wFormx", "width=800,height=600,location=no,menubar=no,status=no,titilebar=no,resizable=no,");
novoForm.onload = function() {
var w = novoForm.innerWidth;
var h = novoForm.innerHeight;
novoForm.document.getElementById("monitor").innerHTML = 'Janela: '+w+' x '+h;
};
};
})();
I'm wondering if it's some security restriction or am I missing something...
Not in your example as shown, no, because the page is clearly being loaded from the same origin. If the URL were from a different origin, then yes, you'd be running into the Same Origin Policy, which prohibits cross-origin scripting. You can relax that via the document.domain property, having both the window containing the code above and the window being loaded setting document.domain to the same value. From the link above:
If two windows (or frames) contain scripts that set domain to the same value, the same-origin policy is relaxed for these two windows, and each window can interact with the other. For example, cooperating scripts in documents loaded from orders.example.com and catalog.example.com might set their document.domain properties to “example.com”, thereby making the documents appear to have the same origin and enabling each document to read properties of the other.
More about document.domain can be found on MDN. Note that it only works where both documents share a common parent domain, e.g., so it works for app1.example.com and app2.example.com if they both set to example.com, but not for example1.com and example2.com because they have not common value they can set.

Alternatively, this is a solution:
var novoForm = window.open("somform.html", "wFormx", "width=800,height=600,location=no,menubar=no,status=no,titilebar=no,resizable=no,");
var teste = function(){
var mon = novoForm.document.getElementById("monitor");
if(typeof(mon)!="undefined"){
//novoForm.alert("Achei!");
var h = novoForm.innerHeight;
var strh = String(h - 40 - 30)+'px';
novoForm.document.getElementById("pagina").style.height = strh;
novoForm.document.getElementById("monitor").innerHTML = '<p class="legenda">© NetArts | gustavopi</p>';
clearInterval(id);
}
}
var id = setInterval(teste, 100);
This will do the job. Not a "pretty" solution to me, but it works!

Depends on what url you try to load into the new window. #T.J is right on that. Also note that if you just want to load a blank document you can load "about:blank" into the url. The only difference is that you would use outerWidth since you haven't loaded an actual document.
var novoForm = window.open("about:blank", "wFormx", "width=800,height=600,location=no,menubar=no,status=no,titilebar=no,resizable=no,");
var w = novoForm.outerWidth;
var h = novoForm.outerHeight;
novoForm.document.body.innerHTML = 'Janela: '+w+' x '+h;

Related

How to open a url from static html page and automatically fill the form values using javascript? [duplicate]

A simple task in JavaScript is to open a new window and writing inside. But I need to write in a dom element, a div with an ID.
var novoForm = window.open("somform.html", "wFormx", "width=800,height=600,location=no,menubar=no,status=no,titilebar=no,resizable=no,");
Than I try something...
var w = novoForm.innerWidth;
var h = novoForm.innerHeight;
novoForm.document.getElementById("monitor").innerHTML = 'Janela: '+w+' x '+h;
I did it to see if the object "novoForm" is valid. But nothing is written in "monitor" div. I also try using onload event with no success. I'm wondering if it's some security restriction or am I missing something...
You've done it right, but you do need to be sure to use onload (or poll), because it takes a moment for the page to get loaded in the new window.
Here's a full working example: Live Copy | Source
(function() {
document.getElementById("theButton").onclick = function() {
var novoForm = window.open("http://jsbin.com/ugucot/1", "wFormx", "width=800,height=600,location=no,menubar=no,status=no,titilebar=no,resizable=no,");
novoForm.onload = function() {
var w = novoForm.innerWidth;
var h = novoForm.innerHeight;
novoForm.document.getElementById("monitor").innerHTML = 'Janela: '+w+' x '+h;
};
};
})();
I'm wondering if it's some security restriction or am I missing something...
Not in your example as shown, no, because the page is clearly being loaded from the same origin. If the URL were from a different origin, then yes, you'd be running into the Same Origin Policy, which prohibits cross-origin scripting. You can relax that via the document.domain property, having both the window containing the code above and the window being loaded setting document.domain to the same value. From the link above:
If two windows (or frames) contain scripts that set domain to the same value, the same-origin policy is relaxed for these two windows, and each window can interact with the other. For example, cooperating scripts in documents loaded from orders.example.com and catalog.example.com might set their document.domain properties to “example.com”, thereby making the documents appear to have the same origin and enabling each document to read properties of the other.
More about document.domain can be found on MDN. Note that it only works where both documents share a common parent domain, e.g., so it works for app1.example.com and app2.example.com if they both set to example.com, but not for example1.com and example2.com because they have not common value they can set.
Alternatively, this is a solution:
var novoForm = window.open("somform.html", "wFormx", "width=800,height=600,location=no,menubar=no,status=no,titilebar=no,resizable=no,");
var teste = function(){
var mon = novoForm.document.getElementById("monitor");
if(typeof(mon)!="undefined"){
//novoForm.alert("Achei!");
var h = novoForm.innerHeight;
var strh = String(h - 40 - 30)+'px';
novoForm.document.getElementById("pagina").style.height = strh;
novoForm.document.getElementById("monitor").innerHTML = '<p class="legenda">© NetArts | gustavopi</p>';
clearInterval(id);
}
}
var id = setInterval(teste, 100);
This will do the job. Not a "pretty" solution to me, but it works!
Depends on what url you try to load into the new window. #T.J is right on that. Also note that if you just want to load a blank document you can load "about:blank" into the url. The only difference is that you would use outerWidth since you haven't loaded an actual document.
var novoForm = window.open("about:blank", "wFormx", "width=800,height=600,location=no,menubar=no,status=no,titilebar=no,resizable=no,");
var w = novoForm.outerWidth;
var h = novoForm.outerHeight;
novoForm.document.body.innerHTML = 'Janela: '+w+' x '+h;

Check if specific text exists in iframe using javascript

I got this iframe:
<iframe id="frami" src="http://192.168.178.22/file.html"></iframe>
which contains the text:
var m1_enable="1"; var m1_x="0"; var m1_y="570"; var m1_w="1920"; var m1_h="510"; var m1_sensitivity="50"; var m1_threshold="0";
How can I check if m1_enable="1" exists in the iframe?
I tried this now:
iframe_html = document.getElementById('frami').contentWindow.document.body.innerHTML;
if(iframe_html.includes("var")){
alert();
}
else{
}
iframe tag has a property called contentDocument that returns the document object generated by an iframe and another called contentWindow that returns the window object generated by an iframe. You can check if "m1_enable="1" by
var x = document.getElementById("frami");
var y = (x.contentWindow || x.contentDocument);
if (y.document) y = y.document;
if (y.body.textContent.indexOf('m1_enable="1"')>-1){
alert('found the phrase'
}
You can get the HTML from iframe with:
iframe_html = document.getElementById('iframe').contentWindow.document.body.innerHTML
And check if it includes m1_enable="1" with:
iframe_html.includes("m1_enable='1'")
This will work only if the frame source is on the same domain. If it is from a different domain, cross-site-scripting (XSS) protection will kick in.
If your iframe is on the same domain it is document.getElementById('frami').contentWindow['m1_enable'] (if this isn't null, compare with 1 with ==1).
otherwise, look at window.postMessage
https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage

JavaScript changing iframe src causes http request conflict and iframe doesn't reload

I am new to web dev and have done a lot of research on my problem, but I still feel stuck:
What I am trying to achieve:
Pass data via URL parameters to an iframe src to be used in the iframe document. The parent page and the iframe are on different domains.
Setup:
I can have one or multiple iframe(s) with a src=”www.example.com”. After the DOM is fully loaded, I try to change the iframe(s) src in order to append some query parameters.
I am using pure JS to get the initial iframe(s) src > concatonate it with the query parameters > save the new URL in variable > change the iframe(s) src to the URL from the variable.
Problem:
Sometimes the iframe src doesn’t change – seems to be related to the internet connection. Every few refreshes javascript will not succeed changing the src, but doesn’t throw any errors.
My troubleshooting:
If I inspect the page and go to Network (Chrome), I can see there are 2 HTTP requests for the iframe: first with the initial src and second with the new src (even if the JS dones’t succeed changing it).
From here I encountered 3 scenarios:
First http request is cancelled and the second is finished – everything is fine – src is changed and data is passed.
both http requests remain in ‘pending’ status – the src is change and data is passed.
first http request is finished before the second one is started. The second one remains in ‘pending’ status – this is the problem – the src doesn’t change, it remains to the old one even though JS seems to have executed properly.
I understand that when the src of an iframe is changed it should cause the iframe to reload, thus triggering the second http request. However, when scenario 3 happens the iframe doesn’t reload. It’s like an http request ‘conflict’ (not sure if it's the correct way to put it).
Why changing the src would not properly reload the iframe consistently?
I appreciate any suggestions, best practices or possible alternatives to make this work.
Here is my code. I've put comments to describe what I intend to do:
paramToPass = ['parma1', 'param2', 'param3']
if (paramToPass) {
var myIframe = 'myIframeClass'; // define what iframes to find
var iframes = document.getElementsByClassName(myIframe); // get all iframes from the page with desired class
var paramStr = paramToPass.join('&'); // create the query parameter string
var iframesElm;
for (iframesElm = 0; iframesElm < iframes.length; iframesElm++) {
var initialSrc = iframes[iframesElm].getAttribute('src'); // find the initial src of the iframe
if(initialSrc.indexOf("?") > -1) { // if initialSrc already contains parameters
var newSrc = initialSrc + '&' + paramStr; // concatonate initial src with parameters
iframes[iframesElm].src = newSrc; // change the iframe src
// iframes[iframesElm].setAttribute('src', newSrc); // alternative to change iframe src
} else { // if initialSrc doesn't contain parameters
var newSrc = initialSrc + '?' + paramStr; // concatonate initial src with parameters
iframes[iframesElm].src = newSrc; // change iframe src
// iframes[iframesElm].setAttribute('src', newSrc); // alternative to change iframe src
};
};
};
Thank you!
EDIT:
New, working code. For wider browser compatibility, I've included polyfill for Array.from() and forEach():
paramToPass = ['parma1', 'param2', 'param3']
if (paramToPass.length > 0) {
var iframes = document.getElementsByClassName(myIframe);
var paramToPassStr = paramToPass.join('&');
Array.from(iframes).forEach(function(iframe) {
iframe.onload = function() { // execute after the iframe is loaded. Prevents http request conflict
var initialSrc = iframe.src;
var sep = initialSrc.indexOf("?") > -1 ? "&" : "?"; // choose separator based on whether or not params already exist in the initialSrc
var newSrc = initialSrc + sep + paramToPassStr;
iframe.src = newSrc;
console.log('iframe reload');
iframe.onload = null; // stops the infinite reload loop
};
});
} else { // paramToPass array is empty, throw error
console.log('no paramToPassStr to pass found')
};
You should probably put the code to reload the iframe into its onload handler, so it runs after the iframe successfully loaded the first time. Then there won't be any conflict.
Array.from(iframes).forEach(iframe => iframe.onload = () => {
var initialSrc = this.src;
var sep = initialSrc.indexOf("?") > -1 ? "&" : "?";
var newSrc = initialSrc + sep + paramStr;
this.src = newSrc;
this.onload = null;
});

Get DOM element in an iframe in JavaScript

I have two documents, one of which is embedded into the other with an iframe. I'm trying to use this code to access the img tag inside the iframe, however, I cannot use the document.getElementById function on the iframe element:
iframes = document.getElementsByTagName("iframe")
spaces = iframes[0].contentWindow.document;
spaces = spaces.getElementsByTagName("img")
for (var i=0, max=spaces.length; i < max; i++) {
alert(spaces[i].innerHTML)
}
alert(spaces)
var x = document.getElementById("frame");
var y = (x.contentWindow || x.contentDocument);
if (y.document)y = y.document;
alert(y.body.innerHTML)
spaces returns [object HTMLCollection] and y returns [object HTMLDocument]
So, if you're on the same domain as your iframe content, you can use
document.getElementById('my-iframe').contentWindow.document.getElementById(...)
If you're not on the same domain, you can't access/manipulate iframe content for security reasons. Otherwise malicious folks could throw up an iframe that looks like Facebook or something and steal other folk's info.
If you're not on the same domain but own both domains you're using, you can set up messaging between the two frames. And use the parent to message the child for information/manipulation.

Jquery function works in Firefox but does not work in IE 9

i have this function written in jquery.
var str1 = "This is a sample text";
var url = "data:text/csv;charset=utf-8," + str1;
self.downloadURL(url);
here is the 'downloadUrl' function definition:
self.downloadURL = function (url) {
var iframe = $("#hiddenDownloader");
if (iframe.length == 0) {
iframe = $('<iframe/>', {
id: "hiddenDownloader",
style: {
display: 'none'
}
}).appendTo(document.body);
}
$(iframe).attr("src", url); // i guess this line is the culprit.
}
This functionality works fine in Firefox, by opening a "Open/Save" dialog box to open/save the given text in the local machine.
But, it does not work in IE 9, No error, No response. just keeps quiet.
Checking on SO it appears that you should probably be trying to modify the location directly, rather than the attribute or the iframe.
Like so:
iframe[0].contentWindow.location.href = url;
EDIT
Not a bug, but a security feature apparently: http://msdn.microsoft.com/en-us/library/cc848897(v=vs.85).aspx
Look at the 3rd comment on that page:
The restriction that DATA URIs cannot be navigated to (e.g. cannot be
used as the source of an IFRAME) remains in place.
The simple answer is that data URIs are not allowed to populate iframes in IE, due to security restrictions. Also, IE can behave weirdly when you insert iframes into the DOM without setting a src attribute first. Try this, from http://sparecycles.wordpress.com/2012/03/08/inject-content-into-a-new-iframe/:
var newIframe = document.createElement('iframe');
newIframe.width = '200';newIframe.height = '200';
newIframe.src = 'about:blank';
document.body.appendChild(newIframe);
var myContent = '<!DOCTYPE html>'
+ '<html><head><title>My dynamic document</head>'
+ '<body><p>Hello world</p></body></html>';
newIframe.contentWindow.document.open('text/html', 'replace');
newIframe.contentWindow.document.write(myContent);
newIframe.contentWindow.document.close();

Categories

Resources