Move DOM Node to Popup Window - javascript

I am trying to move a DOM node from the "root" page to a new pop-up that is created via window.open(). Here is the code I am using.
var win = window.open('/Search/Print', 'printSearchResults'),
table = $('#printTable');
win.document.close();
setTimeout(function () {
var el = win.document.createElement("table");
el.innerHTML = table.html();
win.document.body.appendChild(el);
}, 40);
It works in Chrome, but in IE8, I receive the following error: "Unknown runtime error."
I've also tried it this way:
var p = window.open('/Search/Print', 'printSearchResults'),
table = $('#printTable');
setTimeout(function () {
p.document.body.appendChild(table.clone(false)[0]);
}, 100);
Doing it this way, I receive "No such interface supported" in IE8. Again, Chrome works fine.
Does anyone have a way to do what I'm trying to achieve?
Here is the HTML for the pop-up window just for the sake of completeness:
<!DOCTYPE html>
<html>
<head>
<title>Print Results</title>
</head>
<body>
</body>
</html>

I tested your code on IE9 ( and IE8/7 browser mode).
Instead of el.innerHTML = table.html();
using jquery $(el).html(table.html()); fixed the issue.

To be able to use iframes and new windows, you should initialise them with addres: about:blank, before you write() to them. Also note that loading/opening the window/frame takes time, so you cannot write to them at right away. set a timeout, or check onload.
Please see this answer for more info.
Good luck!

Related

afterprint not detected while hidden printing in an iFrame

I've spent nearly 2 days googling and trying lots of example (even here in StackOverflow), and I don't find any way to fire the event "afterprint". It seems dead. I've found some fiddle, where it works, and when I try to reproduce on my system, it doesn't.
I am not sure what I'm doing wrong.
Here is the code I want to use:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>PDF Printing</title>
</head>
<body>
<button id="myButton2" onClick="printPage('http://localhost/~user/testPDF.pdf')">Print Me 2</button><br>
<script type="text/javascript">
function closePrint () {
console.log("Ciao");
document.body.removeChild(this.__container__);
}
function printPage (sURL) {
var myButton = document.getElementById("myButton2");
myButton.disabled=true;
var printFrame = document.createElement("iframe");
printFrame.id = "printPDF2";
printFrame.style.display = 'none';
printFrame.src = sURL;
printFrame.onload = function() {
printFrame.contentWindow.addEventListener('afterprint', function(evt) {
console.log("yellow");
document.body.removeChild(iframe)
});
this.contentWindow.__container__ = this;
this.contentWindow.onbeforeunload = closePrint;
this.contentWindow.onafterprint = closePrint;
this.contentWindow.focus(); // Required for IE
this.contentWindow.print();
}
document.body.appendChild(printFrame);
}
</script>
</body>
</html>
I've tried also with the MediaDetect. And it doesn't work... (I used these links for inspiration: https://jsfiddle.net/5qbc1pzj/ and https://jsfiddle.net/anhhnt/nj851e52/) the JS console is empty... I get no "Ciao" or "yellow"...
I'm using a simple Apache server, and using the latest IE Edge (103.0.1264.62).
I am out of idea, could someone give me an idea, where to look at?
Thank you in advance.
Kind regards,
Alessandro
It doesn't work because detecting the print events only work for HTML-documents. The MIME type for PDF windows is application/pdf so it doesn't work. The events that are available on the window are not available to the <embed> like tags, as they are handled by the browser's default application for the type. Although the event occurs here, it is not bubbled back to the window. For more information, you can refer to this answer.
The only solution to this seems to create your own PDF viewer. For example, you can use PDF.js.

Can Zombie.js/Phantom.js be used to get HTML of newly open window by window.open?

I am trying to get html of newly open window after activating a link that uses javascript by zombie.js.
Here is the html code
<html>
<head>
<script type="text/javascript">
function newin(id)
{
var url="page.php?id="+id;
window.open(url,id,"toolbar=no,location=top,directories=no,status=no,scrollbars=yes,hscroll=no,resizable=yes,copyhistory=no,width=1025,height=1250");
}
</script>
</head>
<body>
<div>
123<br/>
234<br/>
345<br/>
</div>
</body>
The Script I am using is:
var Browser = require("zombie");
var browser = new Browser();
browser.visit("http://localhost:8000/testpage.html", function () {
browser.wait(function(){
var selector = "a[href*='newin']";
var elements = browser.queryAll(selector);
for (var e=0;e<elements.length;e++){
browser.clickLink(elements[e],function(){
browser.wait(function(){
console.log(browser.html());
});
});
}
});
});
I am not able to get HTML of any window.Any ideas what is wrong in this code ? Or is this possible with phantomjs??
Finally I come to know that if a link contains JavaScript directly in the href or action, Zombie seems to understand that as opening a new page like a normal hyperlink would. While the JavaScript is still executed correctly, the DOM is lost as a result of Zombie trying to load the invalid target as a new page.
A problematic link would be e.g.
test
There’s no support for javascript:links, it is still an open issue:
https://github.com/assaf/zombie/issues/700

JavaScript Code is not working in IE8

The below piece of code is not working in IE8, but, it is working perfectly on FireFox and Google Chorome, Even, there is no error thrown by IE8, but, output is not coming. Any Idea? What is the actual problem?
<html>
<head/>
<body>
<script type="text/javascript">
(function(){
var inpEle = document.createElement("div");
inpEle.setAttribute("id", "div1");
var texEle = document.createTextNode("This is my Sample Para. I am testing it again my own level that prove How i am capable of.");
inpEle.appendChild(texEle);
document.body.appendChild(inpEle);
})();
(function(){
var inpEle1 = document.createElement("input");
inpEle1.setAttribute("type", "button");inpEle1.setAttribute("value", "Show");inpEle1.setAttribute("onclick", "Show()");
document.body.appendChild(inpEle1);
var inpEle2 = document.createElement("input");
inpEle2.setAttribute("type", "button");inpEle2.setAttribute("value", "Hide");inpEle2.setAttribute("onclick", "Hide()");
document.body.appendChild(inpEle2);
})();
</script>
<script type="text/javascript">
window.onload= function(){
document.getElementById('div1').style.display="none";
}
Show = function (){
document.getElementById('div1').style.border="2pt solid green";
document.getElementById('div1').style.display="";
}
Hide = function(){
document.getElementById('div1').style.border="";
document.getElementById('div1').style.display="none";
}
</script>
</body>
</html>
You may not be able to use document.body.appendChild() in IE8 before the </body> tag has been parsed and your code is trying to append to the body while it is still being parsed. Early versions of IE like IE6 might just abort (e.g. literally crash) when you did this. Later versions (like IE8) will just simply ignore your request.
You can use document.write() to add content while the body is being parsed.
You can postpone calling your code until after the body has finished loading and parsing (such a <body onload="xxx()"> handler) or when an event such as window.onload fires.
You can appendChild() to an element that has finished parsing (something that is before your script).
The simplest solution is probably to put a <div id="container"></div> in the body before your script and append to that instead of the body or put your code in a function and have the body onload event call your function.
See this article for description of the issue.
don't use setattribute use anonymous function for events
inpEle1.onclick = function() {
Show();
};
Also it works in IE tester in IE8, but not IE7, do you have it using IE7 compatibility
Go to Internet Options - Security Tab - Internet - click on the "Custom" button then scroll down to the Miscellaneous section."Allow script-initiated windows without size or position constraints" Find "Active Scripting" then check enable.
I noticed than element.style.display doesn't always work with IE8.
Here is a method to improve compatibility :
if (element.style.setAttribute)
element.style.setAttribute("display", value);
else
element.style.display = value;
Best regards,

Javascript Print iframe contents only

This is my code
<script>
var body = "dddddd"
var script = "<script>window.print();</scr'+'ipt>";
var newWin = $("#printf")[0].contentWindow.document;
newWin.open();
newWin.close();
$("body",newWin).append(body+script);
</script>
<iframe id="printf"></iframe>
This works but it prints the parent page, how do I get it to print just the iframe?
I would not expect that to work
try instead
window.frames["printf"].focus();
window.frames["printf"].print();
and use
<iframe id="printf" name="printf"></iframe>
Alternatively try good old
var newWin = window.frames["printf"];
newWin.document.write('<body onload="window.print()">dddd</body>');
newWin.document.close();
if jQuery cannot hack it
Live Demo
document.getElementById("printf").contentWindow.print();
Same origin policy applies.
Easy way (tested on ie7+, firefox, Chrome,safari ) would be this
//id is the id of the iframe
function printFrame(id) {
var frm = document.getElementById(id).contentWindow;
frm.focus();// focus on contentWindow is needed on some ie versions
frm.print();
return false;
}
an alternate option, which may or may not be suitable, but cleaner if it is:
If you always want to just print the iframe from the page, you can have a separate "#media print{}" stylesheet that hides everything besides the iframe. Then you can just print the page normally.
You can use this command:
document.getElementById('iframeid').contentWindow.print();
This command basically is the same as window.print(), but as the window we would like to print is in the iframe, we first need to obtain an instance of that window as a javascript object.
So, in reference to that iframe, we first obtain the iframe by using it's id, and then it's contentWindow returns a window(DOM) object. So, we are able to directly use the window.print() function on this object.
I had issues with all of the above solutions in IE8, have found a decent workaround that is tested in IE 8+9, Chrome, Safari and Firefox. For my situation i needed to print a report that was generated dynamically:
// create content of iframe
var content = '<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">'+
'<head><link href="/css/print.css" media="all" rel="stylesheet" type="text/css"></head>'+
'<body>(rest of body content)'+
'<script type="text/javascript">function printPage() { window.focus(); window.print();return; }</script>'+
'</body></html>';
Note the printPage() javascript method before the body close tag.
Next create the iframe and append it to the parent body so its contentWindow is available:
var newIframe = document.createElement('iframe');
newIframe.width = '0';
newIframe.height = '0';
newIframe.src = 'about:blank';
document.body.appendChild(newIframe);
Next set the content:
newIframe.contentWindow.contents = content;
newIframe.src = 'javascript:window["contents"]';
Here we are setting the dynamic content variable to the iframe's window object then invoking it via the javascript: scheme.
Finally to print; focus the iframe and call the javascript printPage() function within the iframe content:
newIframe.focus();
setTimeout(function() {
newIframe.contentWindow.printPage();
}, 200);
return;
The setTimeout is not necessarily needed, however if you're loading large amounts of content i found Chrome occasionally failed to print without it so this step is recommended. The alternative is to wrap 'newIframe.contentWindow.printPage();' in a try catch and place the setTimeout wrapped version in the catch block.
Hope this helps someone as i spent a lot of time finding a solution that worked well across multiple browsers. Thanks to SpareCycles.
EDIT:
Instead of using setTimeout to call the printPage function use the following:
newIframe.onload = function() {
newIframe.contentWindow.printPage();
}
At this time, there is no need for the script tag inside the iframe. This works for me (tested in Chrome, Firefox, IE11 and node-webkit 0.12):
<script>
window.onload = function() {
var body = 'dddddd';
var newWin = document.getElementById('printf').contentWindow;
newWin.document.write(body);
newWin.document.close(); //important!
newWin.focus(); //IE fix
newWin.print();
}
</script>
<iframe id="printf"></iframe>
Thanks to all answers, save my day.
If you are setting the contents of IFrame using javascript document.write() then you must close the document by newWin.document.close(); otherwise the following code will not work and print will print the contents of whole page instead of only the IFrame contents.
var frm = document.getElementById(id).contentWindow;
frm.focus();// focus on contentWindow is needed on some ie versions
frm.print();
I was stuck trying to implement this in typescript, all of the above would not work. I had to first cast the element in order for typescript to have access to the contentWindow.
let iframe = document.getElementById('frameId') as HTMLIFrameElement;
iframe.contentWindow.print();
Use this code for IE9 and above:
window.frames["printf"].focus();
window.frames["printf"].print();
For IE8:
window.frames[0].focus();
window.frames[0].print();
I am wondering what's your purpose of doing the iframe print.
I met a similar problem a moment ago: use chrome's print preview to generate a PDF file of a iframe.
Finally I solved my problem with a trick:
$('#print').click(function() {
$('#noniframe').hide(); // hide other elements
window.print(); // now, only the iframe left
$('#noniframe').show(); // show other elements again.
});

Giving a child window focus in IE8

I'm trying to launch a popup window from a Javascript function and ensure it has focus using the following call:
window.open(popupUrl, popupName, "...").focus();
It works in every other browser, but IE8 leaves the new window in the background with the flashing orange taskbar notification. Apparently this is a feature of IE8:
http://msdn.microsoft.com/en-us/library/ms536425(VS.85).aspx
It says that I should be able to focus the window by making a focus() call originating from the new page, but that doesn't seem to work either. I've tried inserting window.focus() in script tags in the page and the body's onload but it has no effect. Is there something I'm missing about making a focus() call as the page loads, or another way to launch a popup that IE8 won't hide?
The IE8 is not allowing this feature because of security issues
Windows Internet Explorer 8 and later. The focus method no longer brings child windows (such as those created with the open method) to the foreground. Child windows now request focus from the user, usually by flashing the title bar. To directly bring the window to the foreground, add script to the child window that calls the focus method of its window object
http://msdn.microsoft.com/en-us/library/ms536425%28VS.85%29.aspx
You might try this. Not sure if it will work though>
var isIE = (navigator.appName == "Microsoft Internet Explorer");
var hasFocus = true;
var active_element;
function setFocusEvents() {
active_element = document.activeElement;
if (isIE) {
document.onfocusout = function() { onWindowBlur(); }
document.onfocusin = function() { onWindowFocus(); }
} else {
window.onblur = function() { onWindowBlur(); }
window.onfocus = function() { onWindowFocus(); }
}
}
function onWindowFocus() {
hasFocus = true;
}
function onWindowBlur() {
if (active_element != document.activeElement) {
active_element = document.activeElement;
return;
}
hasFocus = false;
}
Yeah I can't test this on IE8 at the moment either but have a play with this document.ready method instead of the body.onload:
test1.html:
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript">
function openNewWindow()
{
window.open("test2.html", null, "height=200, width=200");
}
</script>
</head>
<body>
<a onclick="openNewWindow()">Open</a>
</body>
</html>
test2.html:
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){ window.focus(); });
</script>
</head>
<body>
<div id="container" style="background:blue;height:200px;width:300px">
</div>
</body>
</html>
I figured out what the issue was - turns out the reason running window.focus() in the onload wasn't working was because the first window.open().focus() call caused it to start flashing in the background, and after that any subsequent focus calls wouldn't work. If I don't try to focus it from the calling window but only from the popup it comes to the front normally. What an annoying "feature"...
The problem is the Window.focus method does not work in Internet Explorer 8 (IE 8). It's not a pop up blocker or any settings in IE 8 or above; it's due to some security I believe to stop annoying pop-ups being brought back up to the top.
after a lot of hair pulling and googling i found the following:
Microsoft suggest updates but this doesn't appear to work plus how do they seriously expect me to ask all of the users my site to update their machines!
so I've come up with this work around or fix.
What i do with the window is:
first I check if the window is open
if it's open, close it
open a new fresh version of the window on top.
javascript code to include at header or in separate file:
function nameoflink()
{
var nameofwindow = window.open('pagetolinkto.htm','nameofwindow','menubar=1,resizable=1,width=350,height=250');
if (nameofwindow) {
nameofwindow.close();
}
window.open('pagetolinkto.htm','nameofwindow,'menubar=1,resizable=1,width=350,height=250');
return false;
}
link on the page:
Click Here to go to name of link
Tested in MS Windows 7 with IE8 not sure of exact version.

Categories

Resources