How do I print the indicated div (without manually disabling all other content on the page)?
I want to avoid a new preview dialog, so creating a new window with this content is not useful.
The page contains a couple of tables, one of them contains the div I want to print - the table is styled with visual styles for the web, that should not show in print.
Here is a general solution, using CSS only, which I have verified to work.
#media print {
body * {
visibility: hidden;
}
#section-to-print, #section-to-print * {
visibility: visible;
}
#section-to-print {
position: absolute;
left: 0;
top: 0;
}
}
Alternative approaches aren't so good. Using display is tricky because if any element has display:none then none of its descendants will display either. To use it, you have to change the structure of your page.
Using visibility works better since you can turn on visibility for descendants. The invisible elements still affect the layout though, so I move section-to-print to the top left so it prints properly.
I have a better solution with minimal code.
Place your printable part inside a div with an id like this:
<div id="printableArea">
<h1>Print me</h1>
</div>
<input type="button" onclick="printDiv('printableArea')" value="print a div!" />
Then add an event like an onclick (as shown above), and pass the id of the div like I did above.
Now let's create a really simple javascript:
function printDiv(divName) {
var printContents = document.getElementById(divName).innerHTML;
var originalContents = document.body.innerHTML;
document.body.innerHTML = printContents;
window.print();
document.body.innerHTML = originalContents;
}
Notice how simple this is? No popups, no new windows, no crazy styling, no JS libraries like jquery. The problem with really complicated solutions (the answer isn't complicated and not what I'm referring to) is the fact that it will NEVER translate across all browsers, ever! If you want to make the styles different, do as shown in the checked answer by adding the media attribute to a stylesheet link (media="print").
No fluff, lightweight, it just works.
All the answers so far are pretty flawed - they either involve adding class="noprint" to everything or will mess up display within #printable.
I think the best solution would be to create a wrapper around the non-printable stuff:
<head>
<style type="text/css">
#printable { display: none; }
#media print
{
#non-printable { display: none; }
#printable { display: block; }
}
</style>
</head>
<body>
<div id="non-printable">
Your normal page contents
</div>
<div id="printable">
Printer version
</div>
</body>
Of course this is not perfect as it involves moving things around in your HTML a bit...
With jQuery it's as simple as this:
w=window.open();
w.document.write($('.report_left_inner').html());
w.print();
w.close();
Could you use a print stylesheet, and use CSS to arrange the content you wanted printed? Read this article for more pointers.
I didn't really like any of these answers as a whole. If you have a class (say printableArea) and have that as an immediate child of body, then you can do something like this in your print CSS:
body > *:not(.printableArea) {
display: none;
}
//Not needed if already showing
body > .printableArea {
display: block;
}
For those looking for printableArea in another place, you would need to make sure the parents of printableArea are shown:
body > *:not(.parentDiv),
.parentDiv > *:not(.printableArea) {
display: none;
}
//Not needed if already showing
body > .printableArea {
display: block;
}
Using the visibility can cause a lot of spacing issues and blank pages. This is because the visibility maintains the elements space, just makes it hidden, where as display removes it and allows other elements to take up its space.
The reason why this solution works is that you are not grabbing all elements, just the immediate children of body and hiding them. The other solutions below with display css, hide all the elements, which effects everything inside of printableArea content.
I wouldn't suggest javascript as you would need to have a print button that the user clicks and the standard browser print buttons wouldn't have the same effect. If you really need to do that, what I would do is store the html of body, remove all unwanted elements, print, then add the html back. As mentioned though, I would avoid this if you can and use a CSS option like above.
NOTE: You can add whatever CSS into the print CSS using inline styles:
<style type="text/css">
#media print {
//styles here
}
</style>
Or like I usually use is a link tag:
<link rel="stylesheet" type="text/css" media="print" href="print.css" />
Give whatever element you want to print the id printMe.
Include this script in your head tag:
<script language="javascript">
var gAutoPrint = true;
function processPrint(){
if (document.getElementById != null){
var html = '<HTML>\n<HEAD>\n';
if (document.getElementsByTagName != null){
var headTags = document.getElementsByTagName("head");
if (headTags.length > 0) html += headTags[0].innerHTML;
}
html += '\n</HE' + 'AD>\n<BODY>\n';
var printReadyElem = document.getElementById("printMe");
if (printReadyElem != null) html += printReadyElem.innerHTML;
else{
alert("Error, no contents.");
return;
}
html += '\n</BO' + 'DY>\n</HT' + 'ML>';
var printWin = window.open("","processPrint");
printWin.document.open();
printWin.document.write(html);
printWin.document.close();
if (gAutoPrint) printWin.print();
} else alert("Browser not supported.");
}
</script>
Call the function
Print
Step 1: Write the following javascript inside your head tag
<script language="javascript">
function PrintMe(DivID) {
var disp_setting="toolbar=yes,location=no,";
disp_setting+="directories=yes,menubar=yes,";
disp_setting+="scrollbars=yes,width=650, height=600, left=100, top=25";
var content_vlue = document.getElementById(DivID).innerHTML;
var docprint=window.open("","",disp_setting);
docprint.document.open();
docprint.document.write('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"');
docprint.document.write('"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">');
docprint.document.write('<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">');
docprint.document.write('<head><title>My Title</title>');
docprint.document.write('<style type="text/css">body{ margin:0px;');
docprint.document.write('font-family:verdana,Arial;color:#000;');
docprint.document.write('font-family:Verdana, Geneva, sans-serif; font-size:12px;}');
docprint.document.write('a{color:#000;text-decoration:none;} </style>');
docprint.document.write('</head><body onLoad="self.print()"><center>');
docprint.document.write(content_vlue);
docprint.document.write('</center></body></html>');
docprint.document.close();
docprint.focus();
}
</script>
Step 2: Call the PrintMe('DivID') function by an onclick event.
<input type="button" name="btnprint" value="Print" onclick="PrintMe('divid')"/>
<div id="divid">
here is some text to print inside this div with an id 'divid'
</div>
<script type="text/javascript">
function printDiv(divId) {
var printContents = document.getElementById(divId).innerHTML;
var originalContents = document.body.innerHTML;
document.body.innerHTML = "<html><head><title></title></head><body>" + printContents + "</body>";
window.print();
document.body.innerHTML = originalContents;
}
</script>
The Best way to Print particular Div or any Element
printDiv("myDiv");
function printDiv(id){
var printContents = document.getElementById(id).innerHTML;
var originalContents = document.body.innerHTML;
document.body.innerHTML = printContents;
window.print();
document.body.innerHTML = originalContents;
}
hm ... use the type of a stylsheet for printing ... eg:
<link rel="stylesheet" type="text/css" href="print.css" media="print" />
print.css:
div { display: none; }
#yourdiv { display: block; }
Without CSS clowning, html and pure javascript with iframe does its work best. Then simply click the text, you want to print. Current example for id elements with text content;
html body:
<div id="monitor" onclick="idElementPrint()">text i want to print</div>
pure javascript:
//or: monitor.textContent = "click me to print textual content";
const idElementPrint = () => {
let ifram = document.createElement("iframe");
ifram.style = "display:none";
document.body.appendChild(ifram);
pri = ifram.contentWindow;
pri.document.open();
pri.document.write(monitor.textContent);
pri.document.close();
pri.focus();
pri.print();
}
printDiv(divId): A generalized solution to print any div on any page.
I had a similar issue but I wanted (a) to be able to print the whole page, or (b) print any one of several specific areas. My solution, thanks to much of the above, allows you to specify any div object to be printed.
The key for this solution is to add an appropriate rule to the the print media style sheet so that the requested div (and its contents) will be printed.
First, create the needed print css to suppress everything (but without the specific rule to allow the element you want to print).
<style type="text/css" media="print">
body {visibility:hidden; }
.noprintarea {visibility:hidden; display:none}
.noprintcontent { visibility:hidden; }
.print { visibility:visible; display:block; }
</style>
Note that I have added new class rules:
noprintarea allows you to suppress the printing of elements within your div- both the content and the block.
noprintcontent allows you to suppress the printing of elements within your div- the content is suppressed but and the allocated area is left empty.
print allows you to have items that show up in the printed version but
not on the screen page. These will normally have "display:none" for the screen style.
Then insert three JavaScript functions. The first merely toggles the print media style sheet on and off.
function disableSheet(thisSheet,setDisabled)
{ document.styleSheets[thisSheet].disabled=setDisabled; }
The second does the real work and the third cleans up afterward. The second (printDiv) activates the print media style sheet, then appends a new rule to allow the desired div to print, issues the print, and then adds a delay before the final housekeeping (otherwise the styles can be reset before the print is actually done.)
function printDiv(divId)
{
// Enable the print CSS: (this temporarily disables being able to print the whole page)
disableSheet(0,false);
// Get the print style sheet and add a new rule for this div
var sheetObj=document.styleSheets[0];
var showDivCSS="visibility:visible;display:block;position:absolute;top:30px;left:30px;";
if (sheetObj.rules) { sheetObj.addRule("#"+divId,showDivCSS); }
else { sheetObj.insertRule("#"+divId+"{"+showDivCSS+"}",sheetObj.cssRules.length); }
print();
// need a brief delay or the whole page will print
setTimeout("printDivRestore()",100);
}
The final functions deletes the added rule and sets the print style again to disabled so the whole page can be printed.
function printDivRestore()
{
// remove the div-specific rule
var sheetObj=document.styleSheets[0];
if (sheetObj.rules) { sheetObj.removeRule(sheetObj.rules.length-1); }
else { sheetObj.deleteRule(sheetObj.cssRules.length-1); }
// and re-enable whole page printing
disableSheet(0,true);
}
The only other thing to do is to add one line to your onload processing so that the print style is initially disabled thereby allowing whole page printing.
<body onLoad='disableSheet(0,true)'>
Then, from anywhere in your document, you can print a div. Just issue printDiv("thedivid") from a button or whatever.
A big plus for this approach it provides a general solution to printing selected content from within a page. It also allows use of existing styles for elements that are printed - including the containing div.
NOTE: In my implementation, this must be the first style sheet. Change the sheet references (0) to the appropriate sheet number if you need to make it later in the sheet sequence.
With CSS 3 you could use the following:
body *:not(#printarea) {
display: none;
}
Sandro's method works great.
I tweaked it to allow for allowing multiple printMe links, particularily to be used in tabbed pages and expanding text.
function processPrint(printMe){ <-- calling for a variable here
var printReadyElem = document.getElementById(printMe); <-- removed the quotes around printMe to ask for a variable
Print <-- passing the div ID to be printed on to the function to turn the printMe variable into the div ID. single quotes are needed
#Kevin Florida
If you have multiple divs with same class, you can use it like this:
<div style="display:none">
<div id="modal-2" class="printableArea">
<input type="button" class="printdiv-btn" value="print a div!" />
</div>
</div>
i was using Colorbox inner content type
$(document).on('click', '.printdiv-btn', function(e) {
e.preventDefault();
var $this = $(this);
var originalContent = $('body').html();
var printArea = $this.parents('.printableArea').html();
$('body').html(printArea);
window.print();
$('body').html(originalContent);
});
In my case I had to print a image inside a page. When I used the solution voted, I had 1 blank page and the other one showing the image. Hope it will help someone.
Here is the css I used:
#media print {
body * {
visibility: hidden;
}
#not-print * {
display: none;
}
#to-print, #to-print * {
visibility: visible;
}
#to-print {
display: block !important;
position: absolute;
left: 0;
top: 0;
width: auto;
height: 99%;
}
}
My html is:
<div id="not-print" >
<header class="row wrapper page-heading">
</header>
<div class="wrapper wrapper-content">
<%= image_tag #qrcode.image_url, size: "250x250" , alt: "#{#qrcode.name}" %>
</div>
</div>
<div id="to-print" style="display: none;">
<%= image_tag #qrcode.image_url, size: "300x300" , alt: "#{#qrcode.name}" %>
</div>
One more approch without affecting current page and it also persist the css while printing. Here selector must be specific div selector which content we need to print.
printWindow(selector, title) {
var divContents = $(selector).html();
var $cssLink = $('link');
var printWindow = window.open('', '', 'height=' + window.outerHeight * 0.6 + ', width=' + window.outerWidth * 0.6);
printWindow.document.write('<html><head><h2><b><title>' + title + '</title></b></h2>');
for(var i = 0; i<$cssLink.length; i++) {
printWindow.document.write($cssLink[i].outerHTML);
}
printWindow.document.write('</head><body >');
printWindow.document.write(divContents);
printWindow.document.write('</body></html>');
printWindow.document.close();
printWindow.onload = function () {
printWindow.focus();
setTimeout( function () {
printWindow.print();
printWindow.close();
}, 100);
}
}
Here provided some time out show that external css get applied to it.
Best css to fit space empty height:
#media print {
body * {
visibility: hidden;
height:0;
}
#section-to-print, #section-to-print * {
visibility: visible;
height:auto;
}
#section-to-print {
position: absolute;
left: 0;
top: 0;
}
}
All answers have trade-offs and cannot be used for all cases. They fall into 3 categories:
Use a printing style sheet. This requires building the whole website to be print-aware.
Hide all elements in <body> and only show the printable element. This works nicely for simple pages, but it is tricky for complex pages.
Open a new window with the content of the printable element or replace the <body> content with the content of the element. The first will lose all styles, and the second is messy and can break events.
There is no one solution that will work well for all cases, so it is good to have all those choices and I'm adding another solution that works much better in some cases. This solution is a hybrid of two categories: hide all content of <body>, then copy the content of the printable element to a new <div> and append it to <body>. After printing, remove the newly added <div> and show the content of <body> back. This way, you won't lose the styles or events, and you don't mess up with opening a new window. But like all other solutions, it won't work well for all cases. If your printable element's styles depends on its parents, you'll lose those styles. It is still much easier to style your printable elements independently from its parents than having to style the entire website for printing.
The only hurdle is figuring out how to select all content of <body>. For simple pages, the generic style body>* will do the trick. However, complex pages usually have <script> tags at the end of body' and also some `s that are used for dialogs, etc. Hiding all those is fine, but you don't want to show them after printing.
In my case, I build all may websites with three sections inside <body>: <header>, <footer>, and between them <div id="Content">. Adjust the first line of the function below for your case:
function PrintArea(selector) {
//First hide all content in body.
var all = $("body > header, body > #Content, body > footer")
all.hide();
//Append a div for printing.
$("body").append('<div id="PrintMe">');
//Copy content of printing area to the printing div.
var p = $("#PrintMe");
p.html($(selector).html());
//Call the print dialog.
window.print();
//Remove the printing div.
p.remove();
//Show all content in body.
all.show();
}
I used jQuery because it's cleaner and simpler, but you can easily convert it to vanilla JavaScript if you like. And of course, you can change var to let as recommended for the local variables.
It's better solution. You can use it Angualr/React
Html
<div class="row" id="printableId">
Your html
</div>
Javascript
function printPage(){
var printHtml = window.open('', 'PRINT', 'height=400,width=600');
printHtml.document.write('<html><head>');
printHtml.document.write(document.getElementById("printableId").innerHTML);
printHtml.document.write('</body></html>');
printHtml.document.close();
printHtml.focus(); = 10*/
printHtml.print();
printHtml.close();
return true;
}
I picked up the content using JavaScript and created a window that I could print in stead...
The printDiv() function came out a few times, but in that case, you loose all your binding elements and input values. So, my solution is to create a div for everything called "body_allin" and another one outside the first one called "body_print".
Then you call this function:
function printDiv(divName){
var printContents = document.getElementById(divName).innerHTML;
document.getElementById("body_print").innerHTML = printContents;
document.getElementById("body_allin").style.display = "none";
document.getElementById("body_print").style.display = "";
window.print();
document.getElementById("body_print").innerHTML = "";
document.getElementById("body_allin").style.display = "";
document.getElementById("body_print").style.display = "none";
}
You could use a separate CSS style which disables every other content except the one with the id "printarea".
See CSS Design: Going to Print for further explanation and examples.
I tried many of the solutions provided.None of them worked perfectly. They either lose CSS or JavaScript bindings. I found a perfect and easy solution that neither losses CSS nor JavaScript bindings.
HTML:
<div id='printarea'>
<p>This is a sample text for printing purpose.</p>
<input type='button' id='btn' value='Print' onclick='printFunc();'>
</div>
<p>Do not print.</p>
Javascript:
function printFunc() {
var divToPrint = document.getElementById('printarea');
var htmlToPrint = '' +
'<style type="text/css">' +
'table th, table td {' +
'border:1px solid #000;' +
'padding;0.5em;' +
'}' +
'</style>';
htmlToPrint += divToPrint.outerHTML;
newWin = window.open("");
newWin.document.write("<h3 align='center'>Print Page</h3>");
newWin.document.write(htmlToPrint);
newWin.print();
newWin.close();
}
I'm very late to this party, but I'd like to pitch in with yet another approach. I wrote a tiny JavaScript module called PrintElements for dynamically printing parts of a webpage.
It works by iterating through selected node elements, and for each node, it traverses up the DOM tree until the BODY element. At each level, including the initial one (which is the to-be-printed node’s level), it attaches a marker class (pe-preserve-print) to the current node. Then attaches another marker class (pe-no-print) to all siblings of the current node, but only if there is no pe-preserve-print class on them. As a third act, it also attaches another class to preserved ancestor elements pe-preserve-ancestor.
A dead-simple supplementary print-only css will hide and show respective elements. Some benefits of this approach is that all styles are preserved, it does not open a new window, there is no need to move around a lot of DOM elements, and generally it is non-invasive with your original document.
See the demo, or read the related article for further details.
I found the solution.
#media print {
.print-area {
background-color: white;
height: 100%;
width: auto;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index:1500;
visibility: visible;
}
#page{
size: portrait;
margin: 1cm;
}
/*IF print-area parent element is position:absolute*/
.ui-dialog,
.ui-dialog .ui-dialog-content{
position:unset !important;
visibility: hidden;
}
}
I tried many of the solutions provided.None of them worked perfectly. They either lose CSS or doesn't work in all browsers. I found a perfect and easy solution that neither losses CSS and work perfectly for all browsers.
Html
<div class="row" id="print-div">
Your html
</div>
TYPESCRIPT
let popupWin = window.open('', '_blank', 'width=1080,height=595');
let printContents = document.getElementById("print-div").innerHTML;
let printHead = document.head.innerHTML;
popupWin.document
.write(`<html>
${printHead}
<body onload="window.print();">${printContents}</body></html>`);
popupWin.document.close();
My approach - Simple CSS and JS. Works on React/NextJS too.
const handlePrint = e => {
e.preventDefault();
const bodyElement = document.getElementsByTagName('body')[0];
bodyElement.classList.add('printing');
window.print();
bodyElement.classList.remove('printing');
};
.printing {
visibility:hidden;
}
.printView {
visibility:visible;
}
.printing .printView {
/* You can have any CSS here to make the view better on print */
position:absolute;
top:0;
}
What it does?
Adds .printing class to body element. With CSS we hide all body content with visibility:hidden;
At the same time, we keep CSS ready with .printing .printView to have any kind of view we want for the print area.
Trigger window.print();
Remove .printing class from the body element when the user cancels / prints.
Example:
<button onclick="handlePrint">
Download PDF
</button>
<div>
<h1>Don't print this</h1>
<div class="printView">Print this</div>
</div>
Let me know if this helps anyone :)
Use a special Stylesheet for printing
<link rel="stylesheet" href="print.css" type="text/css" media="print" />
and then add a class i.e. "noprint" to every tag which's content you don't want to print.
In the CSS use
.noprint {
display: none;
}
Related
It's easy to set inline CSS values with javascript. If I want to change the width and I have html like this:
<div style="width: 10px"></div>
All I need to do is:
document.getElementById('id').style.width = value;
It will change the inline stylesheet values. Normally this isn't a problem, because the inline style overrides the stylesheet. Example:
<style>
#tId {
width: 50%;
}
</style>
<div id="tId"></div>
Using this Javascript:
document.getElementById('tId').style.width = "30%";
I get the following:
<style>
#tId {
width: 50%;
}
</style>
<div id="tId" style="width: 30%";></div>
This is a problem, because not only do I not want to change inline values, If I look for the width before I set it, when I have:
<div id="tId"></div>
The value returned is Null, so if I have Javascript that needs to know the width of something to do some logic (I increase the width by 1%, not to a specific value), getting back Null when I expect the string "50%" doesn't really work.
So my question: I have values in a CSS style that are not located inline, how can I get these values? How can I modify the style instead of the inline values, given an id?
Ok, it sounds like you want to change the global CSS so which will effictively change all elements of a peticular style at once. I've recently learned how to do this myself from a Shawn Olson tutorial. You can directly reference his code here.
Here is the summary:
You can retrieve the stylesheets via document.styleSheets. This will actually return an array of all the stylesheets in your page, but you can tell which one you are on via the document.styleSheets[styleIndex].href property. Once you have found the stylesheet you want to edit, you need to get the array of rules. This is called "rules" in IE and "cssRules" in most other browsers. The way to tell what CSSRule you are on is by the selectorText property. The working code looks something like this:
var cssRuleCode = document.all ? 'rules' : 'cssRules'; //account for IE and FF
var rule = document.styleSheets[styleIndex][cssRuleCode][ruleIndex];
var selector = rule.selectorText; //maybe '#tId'
var value = rule.value; //both selectorText and value are settable.
Let me know how this works for ya, and please comment if you see any errors.
Please! Just ask w3 (http://www.quirksmode.org/dom/w3c_css.html)!
Or actually, it took me five hours... but here it is!
function css(selector, property, value) {
for (var i=0; i<document.styleSheets.length;i++) {//Loop through all styles
//Try add rule
try { document.styleSheets[i].insertRule(selector+ ' {'+property+':'+value+'}', document.styleSheets[i].cssRules.length);
} catch(err) {try { document.styleSheets[i].addRule(selector, property+':'+value);} catch(err) {}}//IE
}
}
The function is really easy to use.. example:
<div id="box" class="boxes" onclick="css('#box', 'color', 'red')">Click Me!</div>
Or:
<div class="boxes" onmouseover="css('.boxes', 'color', 'green')">Mouseover Me!</div>
Or:
<div class="boxes" onclick="css('body', 'border', '1px solid #3cc')">Click Me!</div>
Oh..
EDIT: as #user21820 described in its answer, it might be a bit unnecessary to change all stylesheets on the page. The following script works with IE5.5 as well as latest Google Chrome, and adds only the above described css() function.
(function (scope) {
// Create a new stylesheet in the bottom
// of <head>, where the css rules will go
var style = document.createElement('style');
document.head.appendChild(style);
var stylesheet = style.sheet;
scope.css = function (selector, property, value) {
// Append the rule (Major browsers)
try { stylesheet.insertRule(selector+' {'+property+':'+value+'}', stylesheet.cssRules.length);
} catch(err) {try { stylesheet.addRule(selector, property+':'+value); // (pre IE9)
} catch(err) {console.log("Couldn't add style");}} // (alien browsers)
}
})(window);
Gathering the code in the answers, I wrote this function that seems running well on my FF 25.
function CCSStylesheetRuleStyle(stylesheet, selectorText, style, value){
/* returns the value of the element style of the rule in the stylesheet
* If no value is given, reads the value
* If value is given, the value is changed and returned
* If '' (empty string) is given, erases the value.
* The browser will apply the default one
*
* string stylesheet: part of the .css name to be recognized, e.g. 'default'
* string selectorText: css selector, e.g. '#myId', '.myClass', 'thead td'
* string style: camelCase element style, e.g. 'fontSize'
* string value optionnal : the new value
*/
var CCSstyle = undefined, rules;
for(var m in document.styleSheets){
if(document.styleSheets[m].href.indexOf(stylesheet) != -1){
rules = document.styleSheets[m][document.all ? 'rules' : 'cssRules'];
for(var n in rules){
if(rules[n].selectorText == selectorText){
CCSstyle = rules[n].style;
break;
}
}
break;
}
}
if(value == undefined)
return CCSstyle[style]
else
return CCSstyle[style] = value
}
This is a way to put values in the css that will be used in JS even if not understood by the browser. e.g. maxHeight for a tbody in a scrolled table.
Call :
CCSStylesheetRuleStyle('default', "#mydiv", "height");
CCSStylesheetRuleStyle('default', "#mydiv", "color", "#EEE");
I don't know why the other solutions go through the whole list of stylesheets for the document. Doing so creates a new entry in each stylesheet, which is inefficient. Instead, we can simply append a new stylesheet and simply add our desired CSS rules there.
style=document.createElement('style');
document.head.appendChild(style);
stylesheet=style.sheet;
function css(selector,property,value)
{
try{ stylesheet.insertRule(selector+' {'+property+':'+value+'}',stylesheet.cssRules.length); }
catch(err){}
}
Note that we can override even inline styles set directly on elements by adding " !important" to the value of the property, unless there already exist more specific "!important" style declarations for that property.
I don't have rep enough to comment so I'll format an answer, yet it is only a demonstration of the issue in question.
It seems, when element styles are defined in stylesheets they are not visible to getElementById("someElement").style
This code illustrates the issue... Code from below on jsFiddle.
In Test 2, on the first call, the items left value is undefined, and so, what should be a simple toggle gets messed up. For my use I will define my important style values inline, but it does seem to partially defeat the purpose of the stylesheet.
Here's the page code...
<html>
<head>
<style type="text/css">
#test2a{
position: absolute;
left: 0px;
width: 50px;
height: 50px;
background-color: green;
border: 4px solid black;
}
#test2b{
position: absolute;
left: 55px;
width: 50px;
height: 50px;
background-color: yellow;
margin: 4px;
}
</style>
</head>
<body>
<!-- test1 -->
Swap left positions function with styles defined inline.
Test 1<br>
<div class="container">
<div id="test1a" style="position: absolute;left: 0px;width: 50px; height: 50px;background-color: green;border: 4px solid black;"></div>
<div id="test1b" style="position: absolute;left: 55px;width: 50px; height: 50px;background-color: yellow;margin: 4px;"></div>
</div>
<script type="text/javascript">
function test1(){
var a = document.getElementById("test1a");
var b = document.getElementById("test1b");
alert(a.style.left + " - " + b.style.left);
a.style.left = (a.style.left == "0px")? "55px" : "0px";
b.style.left = (b.style.left == "0px")? "55px" : "0px";
}
</script>
<!-- end test 1 -->
<!-- test2 -->
<div id="moveDownThePage" style="position: relative;top: 70px;">
Identical function with styles defined in stylesheet.
Test 2<br>
<div class="container">
<div id="test2a"></div>
<div id="test2b"></div>
</div>
</div>
<script type="text/javascript">
function test2(){
var a = document.getElementById("test2a");
var b = document.getElementById("test2b");
alert(a.style.left + " - " + b.style.left);
a.style.left = (a.style.left == "0px")? "55px" : "0px";
b.style.left = (b.style.left == "0px")? "55px" : "0px";
}
</script>
<!-- end test 2 -->
</body>
</html>
I hope this helps to illuminate the issue.
Skip
You can get the "computed" styles of any element.
IE uses something called "currentStyle", Firefox (and I assume other "standard compliant" browsers) uses "defaultView.getComputedStyle".
You'll need to write a cross browser function to do this, or use a good Javascript framework like prototype or jQuery (search for "getStyle" in the prototype javascript file, and "curCss" in the jquery javascript file).
That said if you need the height or width you should probably use element.offsetHeight and element.offsetWidth.
The value returned is Null, so if I have Javascript that needs to know the width of something to do some logic (I increase the width by 1%, not to a specific value)
Mind, if you add an inline style to the element in question, it can act as the "default" value and will be readable by Javascript on page load, since it is the element's inline style property:
<div style="width:50%">....</div>
This simple 32 lines gist lets you identify a given stylesheet and change its styles very easily:
var styleSheet = StyleChanger("my_custom_identifier");
styleSheet.change("darkolivegreen", "blue");
I've never seen any practical use of this, but you should probably consider DOM stylesheets. However, I honestly think that's overkill.
If you simply want to get the width and height of an element, irrespective of where the dimensions are being applied from, just use element.offsetWidth and element.offsetHeight.
Perhaps try this:
function CCSStylesheetRuleStyle(stylesheet, selectorText, style, value){
var CCSstyle = undefined, rules;
for(var m in document.styleSheets){
if(document.styleSheets[m].href.indexOf(stylesheet) != -1){
rules = document.styleSheets[m][document.all ? 'rules' : 'cssRules'];
for(var n in rules){
if(rules[n].selectorText == selectorText){
CCSstyle = rules[n].style;
break;
}
}
break;
}
}
if(value == undefined)
return CCSstyle[style]
else
return CCSstyle[style] = value
}
I have javascript code that tests if a div has some non whitespace text content.
This works but it cannot differentiate between text content or style tag declarations within the div and the test fails when there is no text content but a style tag with css data.
Question is how to test for empty text content while ignoring the style tag?
HTML:
<div id='test1'>
<div> </div>
</div>
<div id='test2'>
<div> </div>
<style>
.style1{
border:1px;
}
</style>
</div>
Javascript:
// Works
if($('#test1').text().trim().length==0){
alert('test1 has no content!');
}
// Does not work due to style1 declaration within style tag within div
if($('#test2').text().trim().length==0){
alert('test2 has no content!');
}
Test URL:
http://jsfiddle.net/sLDWB/
One option is cloning the element and removing the style tags:
$.fn.isTextless = function() {
var txt = this.first()
.clone()
.find('style')
.remove()
.end()
.text();
return $.trim(txt).length === 0;
}
if ( $('#test2').isTextless() ) {
alert('test2 has no content!');
}
http://jsfiddle.net/5Z3M4/
You can just use a common class for all the elements you need to check, loop through them using each, store the initial HTML, remove the style tag, do your check and restore the initial HTML. Like so :
$('.testdiv').each(function() {
var divHtml = $(this).html();
$(this).find('style').remove();
if($(this).text().trim().length==0){
alert( $(this).attr('id') + ' has no content!');
}
$(this).html(divHtml);
});
http://jsfiddle.net/sLDWB/1/
Subtract the style tag's length with the actual length.
Try,
if($('#test1').text().trim().length==0){
alert('test1 has no content!');
}
if($('#test2').text().trim().length - $('#test2 style').text().trim().length ==0){
alert('test2 has no content!');
}
DEMO
Use following javascript code
document.getElementById('test2').innerText
The style tag is meant to go in the head of a page. Why do you even have .style1 there if no element uses style1? If you want to change the style of a div, either do <div style="border: 1px;"> or make a style declaration in the <head> part of the HTML page.
In short, you shouldn't ever have a <style> tag outside of <head>.
I would like to use the print() function to print the contents of a <div class="pagecontent"></div>
I know you can do something like onClick="window.print()" but this prints the entire window...I only want the contents of .pagecontent to be printed.
What's the easiest way I can go about doing this using JavaScript or jQuery?
Easiest way is to define a stylesheet that applies for #media=print. It would basically have something like:
* {
display: none; /* hide all elements when printing */
}
.pageContent {
display: block; /* make any class="pageContent" elements visible while printing */
}
Of course, this would make the pageContent elements visible, but anything inside them would still be invisible from the * rule. You'll have to play with this and list only the top-level elements that should be hidden.
You can add the contents of an element to an iframe and then print the iframe.
HTML --
<span>Print Just Me.</span> I'll be omitted.<br />
<iframe id="iframe"></iframe>
JS --
$('span').on('click', function () {
$('#iframe').contents().find('body').html($(this).html());
window.frames['iframe'].print();
});
Here is a demo: http://jsfiddle.net/zaF3K/
You can also hide the iframe so this happens behind the scenes:
#iframe {
display : none;
}
Here is a demo: http://jsfiddle.net/zaF3K/1/
There is the jqprint jquery plugin, take a look
http://archive.plugins.jquery.com/project/jqPrint
if you want to using javascript than try this
window.printItn = function() {
var printContent = document.getElementById('pagecontent');
var windowUrl = 'about:blank';
var uniqueName = new Date();
var windowName = 'Print' + uniqueName.getTime();
// you should add all css refrence for your html. something like.
var WinPrint= window.open(windowUrl,windowName,'left=300,top=300,right=500,bottom=500,width=1000,height=500');
WinPrint.document.write('<'+'html'+'><head><link href="cssreference" rel="stylesheet" type="text/css" /></head><'+'body style="background:none !important"'+'>');
WinPrint.document.write(printContent.innerHTML);
WinPrint.document.write('<'+'/body'+'><'+'/html'+'>');
WinPrint.document.close();
WinPrint.focus();
WinPrint.print();
WinPrint.close();
}
See Demo: http://jsfiddle.net/mu8BG/1/
You can get the contents of the div by using innerHTML and storing that as a string, then just print or log that piece by itself.
var string_to_print = $('#pagecontent').html();
http://api.jquery.com/html/
Using pure javascript you can't, but you can use media print CSS type
It's easy to set inline CSS values with javascript. If I want to change the width and I have html like this:
<div style="width: 10px"></div>
All I need to do is:
document.getElementById('id').style.width = value;
It will change the inline stylesheet values. Normally this isn't a problem, because the inline style overrides the stylesheet. Example:
<style>
#tId {
width: 50%;
}
</style>
<div id="tId"></div>
Using this Javascript:
document.getElementById('tId').style.width = "30%";
I get the following:
<style>
#tId {
width: 50%;
}
</style>
<div id="tId" style="width: 30%";></div>
This is a problem, because not only do I not want to change inline values, If I look for the width before I set it, when I have:
<div id="tId"></div>
The value returned is Null, so if I have Javascript that needs to know the width of something to do some logic (I increase the width by 1%, not to a specific value), getting back Null when I expect the string "50%" doesn't really work.
So my question: I have values in a CSS style that are not located inline, how can I get these values? How can I modify the style instead of the inline values, given an id?
Ok, it sounds like you want to change the global CSS so which will effictively change all elements of a peticular style at once. I've recently learned how to do this myself from a Shawn Olson tutorial. You can directly reference his code here.
Here is the summary:
You can retrieve the stylesheets via document.styleSheets. This will actually return an array of all the stylesheets in your page, but you can tell which one you are on via the document.styleSheets[styleIndex].href property. Once you have found the stylesheet you want to edit, you need to get the array of rules. This is called "rules" in IE and "cssRules" in most other browsers. The way to tell what CSSRule you are on is by the selectorText property. The working code looks something like this:
var cssRuleCode = document.all ? 'rules' : 'cssRules'; //account for IE and FF
var rule = document.styleSheets[styleIndex][cssRuleCode][ruleIndex];
var selector = rule.selectorText; //maybe '#tId'
var value = rule.value; //both selectorText and value are settable.
Let me know how this works for ya, and please comment if you see any errors.
Please! Just ask w3 (http://www.quirksmode.org/dom/w3c_css.html)!
Or actually, it took me five hours... but here it is!
function css(selector, property, value) {
for (var i=0; i<document.styleSheets.length;i++) {//Loop through all styles
//Try add rule
try { document.styleSheets[i].insertRule(selector+ ' {'+property+':'+value+'}', document.styleSheets[i].cssRules.length);
} catch(err) {try { document.styleSheets[i].addRule(selector, property+':'+value);} catch(err) {}}//IE
}
}
The function is really easy to use.. example:
<div id="box" class="boxes" onclick="css('#box', 'color', 'red')">Click Me!</div>
Or:
<div class="boxes" onmouseover="css('.boxes', 'color', 'green')">Mouseover Me!</div>
Or:
<div class="boxes" onclick="css('body', 'border', '1px solid #3cc')">Click Me!</div>
Oh..
EDIT: as #user21820 described in its answer, it might be a bit unnecessary to change all stylesheets on the page. The following script works with IE5.5 as well as latest Google Chrome, and adds only the above described css() function.
(function (scope) {
// Create a new stylesheet in the bottom
// of <head>, where the css rules will go
var style = document.createElement('style');
document.head.appendChild(style);
var stylesheet = style.sheet;
scope.css = function (selector, property, value) {
// Append the rule (Major browsers)
try { stylesheet.insertRule(selector+' {'+property+':'+value+'}', stylesheet.cssRules.length);
} catch(err) {try { stylesheet.addRule(selector, property+':'+value); // (pre IE9)
} catch(err) {console.log("Couldn't add style");}} // (alien browsers)
}
})(window);
Gathering the code in the answers, I wrote this function that seems running well on my FF 25.
function CCSStylesheetRuleStyle(stylesheet, selectorText, style, value){
/* returns the value of the element style of the rule in the stylesheet
* If no value is given, reads the value
* If value is given, the value is changed and returned
* If '' (empty string) is given, erases the value.
* The browser will apply the default one
*
* string stylesheet: part of the .css name to be recognized, e.g. 'default'
* string selectorText: css selector, e.g. '#myId', '.myClass', 'thead td'
* string style: camelCase element style, e.g. 'fontSize'
* string value optionnal : the new value
*/
var CCSstyle = undefined, rules;
for(var m in document.styleSheets){
if(document.styleSheets[m].href.indexOf(stylesheet) != -1){
rules = document.styleSheets[m][document.all ? 'rules' : 'cssRules'];
for(var n in rules){
if(rules[n].selectorText == selectorText){
CCSstyle = rules[n].style;
break;
}
}
break;
}
}
if(value == undefined)
return CCSstyle[style]
else
return CCSstyle[style] = value
}
This is a way to put values in the css that will be used in JS even if not understood by the browser. e.g. maxHeight for a tbody in a scrolled table.
Call :
CCSStylesheetRuleStyle('default', "#mydiv", "height");
CCSStylesheetRuleStyle('default', "#mydiv", "color", "#EEE");
I don't know why the other solutions go through the whole list of stylesheets for the document. Doing so creates a new entry in each stylesheet, which is inefficient. Instead, we can simply append a new stylesheet and simply add our desired CSS rules there.
style=document.createElement('style');
document.head.appendChild(style);
stylesheet=style.sheet;
function css(selector,property,value)
{
try{ stylesheet.insertRule(selector+' {'+property+':'+value+'}',stylesheet.cssRules.length); }
catch(err){}
}
Note that we can override even inline styles set directly on elements by adding " !important" to the value of the property, unless there already exist more specific "!important" style declarations for that property.
I don't have rep enough to comment so I'll format an answer, yet it is only a demonstration of the issue in question.
It seems, when element styles are defined in stylesheets they are not visible to getElementById("someElement").style
This code illustrates the issue... Code from below on jsFiddle.
In Test 2, on the first call, the items left value is undefined, and so, what should be a simple toggle gets messed up. For my use I will define my important style values inline, but it does seem to partially defeat the purpose of the stylesheet.
Here's the page code...
<html>
<head>
<style type="text/css">
#test2a{
position: absolute;
left: 0px;
width: 50px;
height: 50px;
background-color: green;
border: 4px solid black;
}
#test2b{
position: absolute;
left: 55px;
width: 50px;
height: 50px;
background-color: yellow;
margin: 4px;
}
</style>
</head>
<body>
<!-- test1 -->
Swap left positions function with styles defined inline.
Test 1<br>
<div class="container">
<div id="test1a" style="position: absolute;left: 0px;width: 50px; height: 50px;background-color: green;border: 4px solid black;"></div>
<div id="test1b" style="position: absolute;left: 55px;width: 50px; height: 50px;background-color: yellow;margin: 4px;"></div>
</div>
<script type="text/javascript">
function test1(){
var a = document.getElementById("test1a");
var b = document.getElementById("test1b");
alert(a.style.left + " - " + b.style.left);
a.style.left = (a.style.left == "0px")? "55px" : "0px";
b.style.left = (b.style.left == "0px")? "55px" : "0px";
}
</script>
<!-- end test 1 -->
<!-- test2 -->
<div id="moveDownThePage" style="position: relative;top: 70px;">
Identical function with styles defined in stylesheet.
Test 2<br>
<div class="container">
<div id="test2a"></div>
<div id="test2b"></div>
</div>
</div>
<script type="text/javascript">
function test2(){
var a = document.getElementById("test2a");
var b = document.getElementById("test2b");
alert(a.style.left + " - " + b.style.left);
a.style.left = (a.style.left == "0px")? "55px" : "0px";
b.style.left = (b.style.left == "0px")? "55px" : "0px";
}
</script>
<!-- end test 2 -->
</body>
</html>
I hope this helps to illuminate the issue.
Skip
You can get the "computed" styles of any element.
IE uses something called "currentStyle", Firefox (and I assume other "standard compliant" browsers) uses "defaultView.getComputedStyle".
You'll need to write a cross browser function to do this, or use a good Javascript framework like prototype or jQuery (search for "getStyle" in the prototype javascript file, and "curCss" in the jquery javascript file).
That said if you need the height or width you should probably use element.offsetHeight and element.offsetWidth.
The value returned is Null, so if I have Javascript that needs to know the width of something to do some logic (I increase the width by 1%, not to a specific value)
Mind, if you add an inline style to the element in question, it can act as the "default" value and will be readable by Javascript on page load, since it is the element's inline style property:
<div style="width:50%">....</div>
This simple 32 lines gist lets you identify a given stylesheet and change its styles very easily:
var styleSheet = StyleChanger("my_custom_identifier");
styleSheet.change("darkolivegreen", "blue");
I've never seen any practical use of this, but you should probably consider DOM stylesheets. However, I honestly think that's overkill.
If you simply want to get the width and height of an element, irrespective of where the dimensions are being applied from, just use element.offsetWidth and element.offsetHeight.
Perhaps try this:
function CCSStylesheetRuleStyle(stylesheet, selectorText, style, value){
var CCSstyle = undefined, rules;
for(var m in document.styleSheets){
if(document.styleSheets[m].href.indexOf(stylesheet) != -1){
rules = document.styleSheets[m][document.all ? 'rules' : 'cssRules'];
for(var n in rules){
if(rules[n].selectorText == selectorText){
CCSstyle = rules[n].style;
break;
}
}
break;
}
}
if(value == undefined)
return CCSstyle[style]
else
return CCSstyle[style] = value
}
How do I print the indicated div (without manually disabling all other content on the page)?
I want to avoid a new preview dialog, so creating a new window with this content is not useful.
The page contains a couple of tables, one of them contains the div I want to print - the table is styled with visual styles for the web, that should not show in print.
Here is a general solution, using CSS only, which I have verified to work.
#media print {
body * {
visibility: hidden;
}
#section-to-print, #section-to-print * {
visibility: visible;
}
#section-to-print {
position: absolute;
left: 0;
top: 0;
}
}
Alternative approaches aren't so good. Using display is tricky because if any element has display:none then none of its descendants will display either. To use it, you have to change the structure of your page.
Using visibility works better since you can turn on visibility for descendants. The invisible elements still affect the layout though, so I move section-to-print to the top left so it prints properly.
I have a better solution with minimal code.
Place your printable part inside a div with an id like this:
<div id="printableArea">
<h1>Print me</h1>
</div>
<input type="button" onclick="printDiv('printableArea')" value="print a div!" />
Then add an event like an onclick (as shown above), and pass the id of the div like I did above.
Now let's create a really simple javascript:
function printDiv(divName) {
var printContents = document.getElementById(divName).innerHTML;
var originalContents = document.body.innerHTML;
document.body.innerHTML = printContents;
window.print();
document.body.innerHTML = originalContents;
}
Notice how simple this is? No popups, no new windows, no crazy styling, no JS libraries like jquery. The problem with really complicated solutions (the answer isn't complicated and not what I'm referring to) is the fact that it will NEVER translate across all browsers, ever! If you want to make the styles different, do as shown in the checked answer by adding the media attribute to a stylesheet link (media="print").
No fluff, lightweight, it just works.
All the answers so far are pretty flawed - they either involve adding class="noprint" to everything or will mess up display within #printable.
I think the best solution would be to create a wrapper around the non-printable stuff:
<head>
<style type="text/css">
#printable { display: none; }
#media print
{
#non-printable { display: none; }
#printable { display: block; }
}
</style>
</head>
<body>
<div id="non-printable">
Your normal page contents
</div>
<div id="printable">
Printer version
</div>
</body>
Of course this is not perfect as it involves moving things around in your HTML a bit...
With jQuery it's as simple as this:
w=window.open();
w.document.write($('.report_left_inner').html());
w.print();
w.close();
Could you use a print stylesheet, and use CSS to arrange the content you wanted printed? Read this article for more pointers.
I didn't really like any of these answers as a whole. If you have a class (say printableArea) and have that as an immediate child of body, then you can do something like this in your print CSS:
body > *:not(.printableArea) {
display: none;
}
//Not needed if already showing
body > .printableArea {
display: block;
}
For those looking for printableArea in another place, you would need to make sure the parents of printableArea are shown:
body > *:not(.parentDiv),
.parentDiv > *:not(.printableArea) {
display: none;
}
//Not needed if already showing
body > .printableArea {
display: block;
}
Using the visibility can cause a lot of spacing issues and blank pages. This is because the visibility maintains the elements space, just makes it hidden, where as display removes it and allows other elements to take up its space.
The reason why this solution works is that you are not grabbing all elements, just the immediate children of body and hiding them. The other solutions below with display css, hide all the elements, which effects everything inside of printableArea content.
I wouldn't suggest javascript as you would need to have a print button that the user clicks and the standard browser print buttons wouldn't have the same effect. If you really need to do that, what I would do is store the html of body, remove all unwanted elements, print, then add the html back. As mentioned though, I would avoid this if you can and use a CSS option like above.
NOTE: You can add whatever CSS into the print CSS using inline styles:
<style type="text/css">
#media print {
//styles here
}
</style>
Or like I usually use is a link tag:
<link rel="stylesheet" type="text/css" media="print" href="print.css" />
Give whatever element you want to print the id printMe.
Include this script in your head tag:
<script language="javascript">
var gAutoPrint = true;
function processPrint(){
if (document.getElementById != null){
var html = '<HTML>\n<HEAD>\n';
if (document.getElementsByTagName != null){
var headTags = document.getElementsByTagName("head");
if (headTags.length > 0) html += headTags[0].innerHTML;
}
html += '\n</HE' + 'AD>\n<BODY>\n';
var printReadyElem = document.getElementById("printMe");
if (printReadyElem != null) html += printReadyElem.innerHTML;
else{
alert("Error, no contents.");
return;
}
html += '\n</BO' + 'DY>\n</HT' + 'ML>';
var printWin = window.open("","processPrint");
printWin.document.open();
printWin.document.write(html);
printWin.document.close();
if (gAutoPrint) printWin.print();
} else alert("Browser not supported.");
}
</script>
Call the function
Print
Step 1: Write the following javascript inside your head tag
<script language="javascript">
function PrintMe(DivID) {
var disp_setting="toolbar=yes,location=no,";
disp_setting+="directories=yes,menubar=yes,";
disp_setting+="scrollbars=yes,width=650, height=600, left=100, top=25";
var content_vlue = document.getElementById(DivID).innerHTML;
var docprint=window.open("","",disp_setting);
docprint.document.open();
docprint.document.write('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"');
docprint.document.write('"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">');
docprint.document.write('<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">');
docprint.document.write('<head><title>My Title</title>');
docprint.document.write('<style type="text/css">body{ margin:0px;');
docprint.document.write('font-family:verdana,Arial;color:#000;');
docprint.document.write('font-family:Verdana, Geneva, sans-serif; font-size:12px;}');
docprint.document.write('a{color:#000;text-decoration:none;} </style>');
docprint.document.write('</head><body onLoad="self.print()"><center>');
docprint.document.write(content_vlue);
docprint.document.write('</center></body></html>');
docprint.document.close();
docprint.focus();
}
</script>
Step 2: Call the PrintMe('DivID') function by an onclick event.
<input type="button" name="btnprint" value="Print" onclick="PrintMe('divid')"/>
<div id="divid">
here is some text to print inside this div with an id 'divid'
</div>
<script type="text/javascript">
function printDiv(divId) {
var printContents = document.getElementById(divId).innerHTML;
var originalContents = document.body.innerHTML;
document.body.innerHTML = "<html><head><title></title></head><body>" + printContents + "</body>";
window.print();
document.body.innerHTML = originalContents;
}
</script>
The Best way to Print particular Div or any Element
printDiv("myDiv");
function printDiv(id){
var printContents = document.getElementById(id).innerHTML;
var originalContents = document.body.innerHTML;
document.body.innerHTML = printContents;
window.print();
document.body.innerHTML = originalContents;
}
hm ... use the type of a stylsheet for printing ... eg:
<link rel="stylesheet" type="text/css" href="print.css" media="print" />
print.css:
div { display: none; }
#yourdiv { display: block; }
Without CSS clowning, html and pure javascript with iframe does its work best. Then simply click the text, you want to print. Current example for id elements with text content;
html body:
<div id="monitor" onclick="idElementPrint()">text i want to print</div>
pure javascript:
//or: monitor.textContent = "click me to print textual content";
const idElementPrint = () => {
let ifram = document.createElement("iframe");
ifram.style = "display:none";
document.body.appendChild(ifram);
pri = ifram.contentWindow;
pri.document.open();
pri.document.write(monitor.textContent);
pri.document.close();
pri.focus();
pri.print();
}
printDiv(divId): A generalized solution to print any div on any page.
I had a similar issue but I wanted (a) to be able to print the whole page, or (b) print any one of several specific areas. My solution, thanks to much of the above, allows you to specify any div object to be printed.
The key for this solution is to add an appropriate rule to the the print media style sheet so that the requested div (and its contents) will be printed.
First, create the needed print css to suppress everything (but without the specific rule to allow the element you want to print).
<style type="text/css" media="print">
body {visibility:hidden; }
.noprintarea {visibility:hidden; display:none}
.noprintcontent { visibility:hidden; }
.print { visibility:visible; display:block; }
</style>
Note that I have added new class rules:
noprintarea allows you to suppress the printing of elements within your div- both the content and the block.
noprintcontent allows you to suppress the printing of elements within your div- the content is suppressed but and the allocated area is left empty.
print allows you to have items that show up in the printed version but
not on the screen page. These will normally have "display:none" for the screen style.
Then insert three JavaScript functions. The first merely toggles the print media style sheet on and off.
function disableSheet(thisSheet,setDisabled)
{ document.styleSheets[thisSheet].disabled=setDisabled; }
The second does the real work and the third cleans up afterward. The second (printDiv) activates the print media style sheet, then appends a new rule to allow the desired div to print, issues the print, and then adds a delay before the final housekeeping (otherwise the styles can be reset before the print is actually done.)
function printDiv(divId)
{
// Enable the print CSS: (this temporarily disables being able to print the whole page)
disableSheet(0,false);
// Get the print style sheet and add a new rule for this div
var sheetObj=document.styleSheets[0];
var showDivCSS="visibility:visible;display:block;position:absolute;top:30px;left:30px;";
if (sheetObj.rules) { sheetObj.addRule("#"+divId,showDivCSS); }
else { sheetObj.insertRule("#"+divId+"{"+showDivCSS+"}",sheetObj.cssRules.length); }
print();
// need a brief delay or the whole page will print
setTimeout("printDivRestore()",100);
}
The final functions deletes the added rule and sets the print style again to disabled so the whole page can be printed.
function printDivRestore()
{
// remove the div-specific rule
var sheetObj=document.styleSheets[0];
if (sheetObj.rules) { sheetObj.removeRule(sheetObj.rules.length-1); }
else { sheetObj.deleteRule(sheetObj.cssRules.length-1); }
// and re-enable whole page printing
disableSheet(0,true);
}
The only other thing to do is to add one line to your onload processing so that the print style is initially disabled thereby allowing whole page printing.
<body onLoad='disableSheet(0,true)'>
Then, from anywhere in your document, you can print a div. Just issue printDiv("thedivid") from a button or whatever.
A big plus for this approach it provides a general solution to printing selected content from within a page. It also allows use of existing styles for elements that are printed - including the containing div.
NOTE: In my implementation, this must be the first style sheet. Change the sheet references (0) to the appropriate sheet number if you need to make it later in the sheet sequence.
With CSS 3 you could use the following:
body *:not(#printarea) {
display: none;
}
Sandro's method works great.
I tweaked it to allow for allowing multiple printMe links, particularily to be used in tabbed pages and expanding text.
function processPrint(printMe){ <-- calling for a variable here
var printReadyElem = document.getElementById(printMe); <-- removed the quotes around printMe to ask for a variable
Print <-- passing the div ID to be printed on to the function to turn the printMe variable into the div ID. single quotes are needed
#Kevin Florida
If you have multiple divs with same class, you can use it like this:
<div style="display:none">
<div id="modal-2" class="printableArea">
<input type="button" class="printdiv-btn" value="print a div!" />
</div>
</div>
i was using Colorbox inner content type
$(document).on('click', '.printdiv-btn', function(e) {
e.preventDefault();
var $this = $(this);
var originalContent = $('body').html();
var printArea = $this.parents('.printableArea').html();
$('body').html(printArea);
window.print();
$('body').html(originalContent);
});
In my case I had to print a image inside a page. When I used the solution voted, I had 1 blank page and the other one showing the image. Hope it will help someone.
Here is the css I used:
#media print {
body * {
visibility: hidden;
}
#not-print * {
display: none;
}
#to-print, #to-print * {
visibility: visible;
}
#to-print {
display: block !important;
position: absolute;
left: 0;
top: 0;
width: auto;
height: 99%;
}
}
My html is:
<div id="not-print" >
<header class="row wrapper page-heading">
</header>
<div class="wrapper wrapper-content">
<%= image_tag #qrcode.image_url, size: "250x250" , alt: "#{#qrcode.name}" %>
</div>
</div>
<div id="to-print" style="display: none;">
<%= image_tag #qrcode.image_url, size: "300x300" , alt: "#{#qrcode.name}" %>
</div>
One more approch without affecting current page and it also persist the css while printing. Here selector must be specific div selector which content we need to print.
printWindow(selector, title) {
var divContents = $(selector).html();
var $cssLink = $('link');
var printWindow = window.open('', '', 'height=' + window.outerHeight * 0.6 + ', width=' + window.outerWidth * 0.6);
printWindow.document.write('<html><head><h2><b><title>' + title + '</title></b></h2>');
for(var i = 0; i<$cssLink.length; i++) {
printWindow.document.write($cssLink[i].outerHTML);
}
printWindow.document.write('</head><body >');
printWindow.document.write(divContents);
printWindow.document.write('</body></html>');
printWindow.document.close();
printWindow.onload = function () {
printWindow.focus();
setTimeout( function () {
printWindow.print();
printWindow.close();
}, 100);
}
}
Here provided some time out show that external css get applied to it.
Best css to fit space empty height:
#media print {
body * {
visibility: hidden;
height:0;
}
#section-to-print, #section-to-print * {
visibility: visible;
height:auto;
}
#section-to-print {
position: absolute;
left: 0;
top: 0;
}
}
All answers have trade-offs and cannot be used for all cases. They fall into 3 categories:
Use a printing style sheet. This requires building the whole website to be print-aware.
Hide all elements in <body> and only show the printable element. This works nicely for simple pages, but it is tricky for complex pages.
Open a new window with the content of the printable element or replace the <body> content with the content of the element. The first will lose all styles, and the second is messy and can break events.
There is no one solution that will work well for all cases, so it is good to have all those choices and I'm adding another solution that works much better in some cases. This solution is a hybrid of two categories: hide all content of <body>, then copy the content of the printable element to a new <div> and append it to <body>. After printing, remove the newly added <div> and show the content of <body> back. This way, you won't lose the styles or events, and you don't mess up with opening a new window. But like all other solutions, it won't work well for all cases. If your printable element's styles depends on its parents, you'll lose those styles. It is still much easier to style your printable elements independently from its parents than having to style the entire website for printing.
The only hurdle is figuring out how to select all content of <body>. For simple pages, the generic style body>* will do the trick. However, complex pages usually have <script> tags at the end of body' and also some `s that are used for dialogs, etc. Hiding all those is fine, but you don't want to show them after printing.
In my case, I build all may websites with three sections inside <body>: <header>, <footer>, and between them <div id="Content">. Adjust the first line of the function below for your case:
function PrintArea(selector) {
//First hide all content in body.
var all = $("body > header, body > #Content, body > footer")
all.hide();
//Append a div for printing.
$("body").append('<div id="PrintMe">');
//Copy content of printing area to the printing div.
var p = $("#PrintMe");
p.html($(selector).html());
//Call the print dialog.
window.print();
//Remove the printing div.
p.remove();
//Show all content in body.
all.show();
}
I used jQuery because it's cleaner and simpler, but you can easily convert it to vanilla JavaScript if you like. And of course, you can change var to let as recommended for the local variables.
It's better solution. You can use it Angualr/React
Html
<div class="row" id="printableId">
Your html
</div>
Javascript
function printPage(){
var printHtml = window.open('', 'PRINT', 'height=400,width=600');
printHtml.document.write('<html><head>');
printHtml.document.write(document.getElementById("printableId").innerHTML);
printHtml.document.write('</body></html>');
printHtml.document.close();
printHtml.focus(); = 10*/
printHtml.print();
printHtml.close();
return true;
}
I picked up the content using JavaScript and created a window that I could print in stead...
The printDiv() function came out a few times, but in that case, you loose all your binding elements and input values. So, my solution is to create a div for everything called "body_allin" and another one outside the first one called "body_print".
Then you call this function:
function printDiv(divName){
var printContents = document.getElementById(divName).innerHTML;
document.getElementById("body_print").innerHTML = printContents;
document.getElementById("body_allin").style.display = "none";
document.getElementById("body_print").style.display = "";
window.print();
document.getElementById("body_print").innerHTML = "";
document.getElementById("body_allin").style.display = "";
document.getElementById("body_print").style.display = "none";
}
You could use a separate CSS style which disables every other content except the one with the id "printarea".
See CSS Design: Going to Print for further explanation and examples.
I tried many of the solutions provided.None of them worked perfectly. They either lose CSS or JavaScript bindings. I found a perfect and easy solution that neither losses CSS nor JavaScript bindings.
HTML:
<div id='printarea'>
<p>This is a sample text for printing purpose.</p>
<input type='button' id='btn' value='Print' onclick='printFunc();'>
</div>
<p>Do not print.</p>
Javascript:
function printFunc() {
var divToPrint = document.getElementById('printarea');
var htmlToPrint = '' +
'<style type="text/css">' +
'table th, table td {' +
'border:1px solid #000;' +
'padding;0.5em;' +
'}' +
'</style>';
htmlToPrint += divToPrint.outerHTML;
newWin = window.open("");
newWin.document.write("<h3 align='center'>Print Page</h3>");
newWin.document.write(htmlToPrint);
newWin.print();
newWin.close();
}
I'm very late to this party, but I'd like to pitch in with yet another approach. I wrote a tiny JavaScript module called PrintElements for dynamically printing parts of a webpage.
It works by iterating through selected node elements, and for each node, it traverses up the DOM tree until the BODY element. At each level, including the initial one (which is the to-be-printed node’s level), it attaches a marker class (pe-preserve-print) to the current node. Then attaches another marker class (pe-no-print) to all siblings of the current node, but only if there is no pe-preserve-print class on them. As a third act, it also attaches another class to preserved ancestor elements pe-preserve-ancestor.
A dead-simple supplementary print-only css will hide and show respective elements. Some benefits of this approach is that all styles are preserved, it does not open a new window, there is no need to move around a lot of DOM elements, and generally it is non-invasive with your original document.
See the demo, or read the related article for further details.
I found the solution.
#media print {
.print-area {
background-color: white;
height: 100%;
width: auto;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index:1500;
visibility: visible;
}
#page{
size: portrait;
margin: 1cm;
}
/*IF print-area parent element is position:absolute*/
.ui-dialog,
.ui-dialog .ui-dialog-content{
position:unset !important;
visibility: hidden;
}
}
I tried many of the solutions provided.None of them worked perfectly. They either lose CSS or doesn't work in all browsers. I found a perfect and easy solution that neither losses CSS and work perfectly for all browsers.
Html
<div class="row" id="print-div">
Your html
</div>
TYPESCRIPT
let popupWin = window.open('', '_blank', 'width=1080,height=595');
let printContents = document.getElementById("print-div").innerHTML;
let printHead = document.head.innerHTML;
popupWin.document
.write(`<html>
${printHead}
<body onload="window.print();">${printContents}</body></html>`);
popupWin.document.close();
My approach - Simple CSS and JS. Works on React/NextJS too.
const handlePrint = e => {
e.preventDefault();
const bodyElement = document.getElementsByTagName('body')[0];
bodyElement.classList.add('printing');
window.print();
bodyElement.classList.remove('printing');
};
.printing {
visibility:hidden;
}
.printView {
visibility:visible;
}
.printing .printView {
/* You can have any CSS here to make the view better on print */
position:absolute;
top:0;
}
What it does?
Adds .printing class to body element. With CSS we hide all body content with visibility:hidden;
At the same time, we keep CSS ready with .printing .printView to have any kind of view we want for the print area.
Trigger window.print();
Remove .printing class from the body element when the user cancels / prints.
Example:
<button onclick="handlePrint">
Download PDF
</button>
<div>
<h1>Don't print this</h1>
<div class="printView">Print this</div>
</div>
Let me know if this helps anyone :)
Use a special Stylesheet for printing
<link rel="stylesheet" href="print.css" type="text/css" media="print" />
and then add a class i.e. "noprint" to every tag which's content you don't want to print.
In the CSS use
.noprint {
display: none;
}