Printing Sections Of A Web Page Using DIVs And JavaScript Remote Scripting

Recently asked on Yahoo! Answers:

Is there an equivalent of “window.print()” in JavaScript for printing individual elements out of a whole page?
For example:

Whole page: window.print
Individual Element: document.getElementById(‘element’).print…

I don’t want to print a whole page, just an individual element.

This really intrigued me because it’s the first time I’ve had cause to use remote scripting with JavaScript. We’re going to use two standard XHTML pages — one, a parent, the other, a helper contained in a hidden iFrame, each with its own JavaScript function.

Let’s get to it, shall we? As always, a link to a working demo appears at the end of the article.

A couple quick notes about this script:

  • I made this to work for Firefox 2+ and Internet Explorer 6+. It works in Safari 3.1 as well. I can’t guarantee it works for other browsers.
  • Internet Explorer’s implementation of JavaScript does not support the contentDocument property of the DOM iFrame object. Why not? Who knows, it’s only been around for something like two years now.
  • Internet Explorer 7 will not focus on an iFrame just because you call a function contained on a page in that iFrame. (I know, that makes no sense at all; if I call a script on a framed page, how can I manage to do that without transferring focus to the frame?) This is not a problem in other browsers or IE 6, but the fix is simple and doesn’t affect them, either.
  • If you want things on the print page to look the way they do on your sections page, both pages need to have references to the same styles (of course; but I lost that fact in the shuffle during my testing).

The print.html Page

As I just noted, we’re going to need an XHTML helper page that will do the actual printing.

It’s a simple, standard XHTML page, with two specific elements: A DIV with a unique ID, to which we will add the section of HTML we want copied; and a simple JavaScript window.print() function.

The printing function also needs to call focus to this page, as it will appear in its frameset, to ensure IE 7 prints the right page. I’m calling this page theFrame in its parent page, so that’s what gets focus from the function.

<div id="theSection"></div></pre>

<pre lang="javascript">
function printPage() {
	window.parent.theFrame.focus();
	window.print();
}

The index.html Page

To make our “Web page sections” individually printable, all we need to do is wrap each section with a uniquely identified DIV, and create a JavaScript function that transfers the HTML content inside that DIV to the helper page, then orders the helper page to fire its printPage() function. We include the print.html page in a hidden iFrame, which allows us to send it the section we want to print.

A hidden iFrame is one with no width, height or border, located someplace innocuous on the page. For this script to work, the iFrame needs both an ID and a name; I’ve used the same value for both:

<iframe id="theFrame" name="theFrame" src="print.html" frameborder="0" marginheight="0" marginwidth="0" width="0" height="0"></iframe>

Note that you should not style the iFrame with display: none; if you do that, JavaScript cannot access the element! Also, it’s not necessary; the inline attributes of the iFrame will keep it hidden from users.

That was easy enough. Now, we place our wrapper DIVs around each section. Note that it has a unique ID, but it can also have a class it shares with other DIVs.

<div id="section2" lang="section">
	<h2>Section 2</h2>
	Morbi erat diam, dictum a, cursus ac, facilisis et, turpis. Quisque  sed leo quis lorem scelerisque ullamcorper. Ut ac nunc sit amet justo  posuere mollis. Ut auctor, nulla a hendrerit elementum, orci metus  malesuada tortor, vitae vestibulum urna ante sed purus. ...
</div>

We also need a link or button that will call the printSection() function (which I will describe shortly). The function takes as its argument the ID of the section wrapper DIV you want to print:

<a href="javascript:void(0);" onclick="printSection('section2');">Print this section</a>

The printSection() Function

The JavaScript function accepts the argument from our link or button, grabs print.html from our hidden iFrame, selects the DIV in print.html that we gave a unique ID, sets its HTML contents to be the same as the HTML contents of the selected DIV on the index.html page, and then orders print.html to execute its window printing function.

Yes, it’s that simple.

And again, note that because Internet Explorer and Mozilla don’t address the documents contained in an iFrame the same way, we need two ways of doing it.

function printSection(id) {
	if (document.getElementById('theFrame').contentDocument){
    		theIframe = document.getElementById('theFrame').contentDocument;
  	}
	else {
    		theIframe = document.frames['theFrame'].document;
  	}
	var thePrinter = theIframe.getElementById('theSection');
	var theCopy = document.getElementById(id);
	thePrinter.innerHTML = theCopy.innerHTML;
	parent.theFrame.printPage();
}

Notice, again, that due to the way DOM manipulation works, we can’t use theIframe — the reference to the theIframe on our page — to invoke the printPage() function in print.html. That’s why we needed to give it a name attribute — so we can reference theIframe as parent.theFrame, and in turn compel that iFrame page to call the printPage() function.

You can see a working demo here: http://www.dougv.com/demo/js_section_print/

I distribute code under the GNU GPL. See Copyright & Attribution for details.

3 thoughts on “Printing Sections Of A Web Page Using DIVs And JavaScript Remote Scripting

  1. Scriptar

    Nice. Unfortunately it didn’t work in Opera version 9 (it prints out the entire page.) It has a nice picture on it, however.

  2. Doug Vanderweide Post author

    Nice. Unfortunately it didn’t work in Opera version 9 (it prints out the entire page.) It has a nice picture on it, however.

    That’s bad news for the three guys using Opera, then.

Leave a Reply