I have an old javascript code to print images, if a user clicks on the thumbnail. It used to work just fine, but lately (only in Chrome!) there is a blank page in preview.
Here is a demonstration in JsBin: http://jsbin.com/yehefuwaso/7
Click the printer icon. Now try it in Firefox; it will work as expected.
Chrome: 41.0.2272.89 m
Firefox: 30.0, 36.0.1
function newWindow(src){
win = window.open("","","width=600,height=600");
var doc = win.document;
// init head
var head = doc.getElementsByTagName("head")[0];
// create title
var title = doc.createElement("title");
title.text = "Child Window";
head.appendChild(title);
// create script
var code = "function printFunction() { window.focus(); window.print(); }";
var script = doc.createElement("script");
script.text = code;
script.type = "text/javascript";
head.appendChild(script);
// init body
var body = doc.body;
//image
doc.write('<img src="'+src+'" width="300">');
//chrome
if (navigator.userAgent.toLowerCase().indexOf('chrome') > -1) {
win.printFunction();
} else {
win.document.close();
win.focus();
win.print();
win.close();
}
}
It looks like it's attempting to print before the <img> has loaded, move the call to print inside an event handler for the load event of window by opening the link as a data URI or Blob, for example
var code = '\
<html>\
<head>\
<title></title>\
<script>\
function printFunction() {\
window.focus();\
window.print();\
window.close();\
}\
window.addEventListener(\'load\', printFunction);\
</script>\
</head>\
<body><img src="'+src+'" width="300"></body>\
</html>';
window.open('data:text/html,' + code, '_blank', 'width=600,height=600');
Don't forget you may need to HTML encode the tags in code
You could probably just listen for load on the <img> instead, but if you ever do anything more complicated than tring to print a single image you may find it breaks again in future
doc.write('<img onload="printFunction();" src="'+src+'" width="300">');
Where printFunction is the print function for all browsers
I encountered the same problem in Chrome. You can try these approaches, the first one worked for me. setTimeout didn't work for me (had to edit this later).
function printDiv(divName) {
var printContents = document.getElementById(divName).innerHTML;
w = window.open();
w.document.write(printContents);
w.document.write('<scr' + 'ipt type="text/javascript">' + 'window.onload = function() { window.print(); window.close(); };' + '</sc' + 'ript>');
w.document.close(); // necessary for IE >= 10
w.focus(); // necessary for IE >= 10
return true;
}
setTimeout:
<div id="printableArea">
<h1>Print me</h1>
</div>
<input type="button" onclick="printDiv('printableArea')" value="print a div!" />
function printDiv(divName) {
var printContents = document.getElementById(divName).innerHTML;
w = window.open();
w.document.write(printContents);
w.document.close(); // necessary for IE >= 10
w.focus(); // necessary for IE >= 10
setTimeout(function () { // necessary for Chrome
w.print();
w.close();
}, 0);
return true;
}
You need to wait for the image to finish loading:
var img = new Image();
img.src = src;
img.style.width = '300px';
img.onload = function(){
doc.write(img);
};
Related
I'm getting the "Permission Denied" error on Edge and IE when creating an iframe in the script with some delay (setTimeout) and trying to access the window object.
It works on all other browsers, and works without the delay on IE and Edge.
<script>
function createIframe(win) {
console.log('foo', win.foo);
var width = 300;
var height = 250;
var id = 'ifr';
var src = '';
var iframeTemplate = '<iframe id="'+id+'" src="'+src+'" width="'+width+'" height="'+
height+'" marginheight="0" marginwidth="0" scrolling="NO" frameborder="0"></iframe>';
win.document.write(iframeTemplate);
var iframe = win.document.getElementById(id);
console.log('foo', win.foo);
if (iframe) {
var doc = iframe.contentWindow.document;
doc.write('<html><head></head><body><script>console.log("foo on parent", window.parent.foo);</scr'+ 'ipt></body></html>');
doc.close();
} else {
console.log('Failed to create an iframe');
}
}
window.foo = 'bar';
setTimeout(function() {
createIframe(window);
}, 3000);
</script>
This code should print:
foo bar
foo bar
foo on parent bar
But it throws the error "Permission Denied" on the second console.log on Edge and IE.
Works fine without setTimeout.
If I remove the second console.log, and acess window.parent.foo from within an iframe, it is undefined on Edge and IE
Snippets:
Doesn't work on Edge and IE: https://jsfiddle.net/vo2yrjft/
Works on Edge and IE: https://jsfiddle.net/6cbfk1yr/
Any workaround for that?
document.write is a "bad practice", it will block the page, you could refer to this thread for detailed information.
As a workaround, you could use createElement('iframe') to create an iframe and then use appendChild() to insert the element. Below is the sample code, it can run well in IE & Edge:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<script>
function prepareFrame(win) {
console.log('foo', win.foo);
var id = 'ifr';
var ifrm = document.createElement('iframe');
ifrm.setAttribute('src', '');
ifrm.setAttribute('id', id);
ifrm.setAttribute('marginheight', 0);
ifrm.setAttribute('marginwidth', 0);
ifrm.setAttribute('scrolling', 'NO');
ifrm.setAttribute('frameborder', 0);
ifrm.style.width = '300px';
ifrm.style.height = '250px';
document.body.appendChild(ifrm);
var iframe = win.document.getElementById(id);
console.log('foo', win.foo);
if (iframe) {
var doc = iframe.contentWindow.document;
doc.write('<html><head></head><body><script>console.log("foo on parent", window.parent.foo);</scr' + 'ipt></body></html>');
doc.close();
} else {
console.log('Failed to create an iframe');
}
}
window.foo = 'bar';
setTimeout(function() {
prepareFrame(window);
}, 3000);
</script>
</body>
</html>
I have one page where I use java script and css to show graph.When I try to print graph using div content and opening new window it does not work.
Below is screenshot of graph page and print window
I have tried to put css before printing and also added bootstrap js but stil not work.
Below is code that I copy form stackoverflow and modify as I require.Thanks.
function printDiv() {
debugger;
var printContents = $('body').clone().find('script').remove().end().html();
// get all <links> and remove all the <script>'s from the header that could run on the new window
var allLinks = $('head').clone().find('script').remove().end().html();
var js = "";
js += "#Html.Raw(string.Format("<script src='/SkillsAssessmentModule/Scripts/bootbox.min.js'/>"))";
// open a new window
var popupWin = window.open('', '_blank');
// ready for writing
popupWin.document.open();
// -webkit-print-color-adjust to keep colors for the printing version
var keepColors = '<style>body {-webkit-print-color-adjust: exact !important; }</style>';
// writing
// onload="window.print()" to print straigthaway
popupWin.document.write('<html><head>' + keepColors + allLinks + '</head><body>' + document.getElementById("lProgress").innerHTML + js + '</body></html>');
popupWin.print();
// close for writing
popupWin.document.close();
setTimeout(function () { popupWin.close(); }, 1);
}
</script>
}
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 want to open a print dialog for a file(docx,pdf,...) via a SharePoint Workflow. There I call a URL with GET and pass the URL of the file after the ? like this:
http://www.sharepoint_intranet.com/print.html?link-to-file.pdf
EDIT: I also tried:
<script type="text/javascript">
//Get the URL of the file
var urlOfFile = window.location.search.replace("?", "");
document.write("<iframe id=" + "printDocument" + " src=" + "'" + urlOfFile + "'" + " width=" + "600" + " height=" + "400" + "></iframe>");
window.frames['printDocument'].focus();
window.frames['printDocument'].print();
</script>
The Print Dialog is opening and in the print options there is the Point "Only selected Frame" selected but when I press the print button nothing will happen.
Thanks for any help!
you can put in the body of the html
<body onLoad="window.print();">
so the page is opened already prints the document.
The issue is that the new url doesn't start loading until the current script block has finished executing. Therefore when you call w.print(), the new window is currently blank.
Try:
<script type="text/javascript">
//Get the URL of the file
var urlOfFile = window.location.search.replace("?", "");
//print
var w = window.open(urlOfFile);
w.onload = function() {
w.print();
}
</script>
EDIT: I didn't read the question properly! The above technique only works for html. The way to solve this is to use an iframe and if we are using an iframe we might as well dispense with the popups entirely. The following code creates an iframe with a source set to the desired document, attaches the iframe to the page (but keeps it invisible), prints the contents of the iframe and finally removes the iframe once we've finished with it. Only tested in Chrome but I'm fairly confident that it'll work in other browsers.
<script type="text/javascript">
//Get the URL of the file
var urlOfFile = window.location.search.replace("?", "");
//print
var iframe = document.createElement('iframe');
iframe.src = urlOfFile;
iframe.style.display = "none";
var iFrameLoaded = function() {
iframe.contentWindow.print();
iframe.parentNode.removeChild(iframe);
};
if (iframe.attachEvent) iframe.attachEvent('onload', iFrameLoaded); // for IE
else if(iframe.addEventListener) iframe.addEventListener('load', iFrameLoaded, false); // for most other browsers
else iframe.onload = iFrameLoaded; // just in case there's a browser not covered by the first two
window.onload = function() {
document.body.appendChild(iframe);
};
</script>
where we can give the path of the file like("abc.doc"/"abc.xls")
var urlOfFile = window.location.search.replace("?", "");
So I am fairly new to Javascript (a lot of experience in PHP), but I have this basic script that checks a link that redirects to a URL to see what the image height is. If it is a certain height then it adds one to a variable, otherwise nothing. I would easily do this in PHP but the images are on other servers and not my own so it doesn't work.
Anyways, ehre is the script. Let me know if you have any tips. Works well and tested in Chrome, Safari, Opera, and IE.
<script language='JavaScript'>
window.onload = function() {
var nstar = 0, urls = [];
urls[0] = "http://optout.imiclk.com/cgi/nai_status.cgi?nocache=";
urls[1] = "http://www.adbrite.com/mb/nai_optout_check.php?nocache=";
urls[2] = "http://events.adchemy.com/visitor/auuid/nai-status?nocache=";
function getImgSize(imgSrc){
var newImg = new Image();
newImg.src = imgSrc;
return{height:newImg.height, width:newImg.width}
}
for(i=0,length=urls.length;i<length;i++){
if(getImgSize(urls[i]).height==43){nstar++;}
}
document.getElementById('tracknum').innerHTML = "<b>" + nstar + "</b>";
}
</script>
Maybe the image isn't loaded yet?
Try :
image.onload=function() {
alert('W:'+image.width+', H:'+image.height)
}