Printing All or Part of a Page without the Need for Printer-Friendly Pages
In reference to the printing of Web documents on the Internet, almost all sites simply create separate "printer-friendly" pages that are designed especially to be printed, to avoid the hassles of trying to get NOT-printer-friendly web pages to print right on various browsers. Especially challenging: multiple pages, which tend to screw up in Firefox/Mozilla/Netscape, and columns, which amost certainly screw up everywhere on all browsers. The main thing to do in a printer page is use static positioning, not absolute. In other words, use natural page flow, not forced. And dump all your side columns and navigation buttons and print only the text. If you do this, most browsers will do okay—maybe even Firefox (?), although we haven't tested the difference between multiple pages and one very long statically positioned natural flow page.
Any browser should be able to be handle a really long 1-column, statically-positioned, natural-flow text page, printing however many pages it needs to. This is simpler than trying to deal with printing multiple pages. Many webmasters simply create PDF documents; then users can print any or all of the content with ease. Of course, most users have enough sense to select the text they want on a page and then "Print Selection."
So printing one very long statically positioned natural flow page is the easy way. But what if the page will change a lot so you'll be needing to edit both the web page and printer page for many documents often? Worse yet, what if the page REQUIRES columns for navigation, aesthetics, ads, and/or links? As you likely know, static positioning and columns are nearly incompatible, but even if you manage to pull it off, by the time you start needing printer pages of the document, you'll surely need to make these separate printer pages.
Javascript to the Rescue
But there are a few clever tactics that can bear fruit in the quandry outlined above. Whether out of laziness or because a person hasn't time to edit both the regular web page and its printer page everytime there's a change, sometimes messing with two separate pages just so visitors can print decently is just not in the cards. What if you've used too much disk space on your host's server and there isn't room for duplicates of dozens or hundreds of text pages?
There are many possible DHTML approaches to this problem. InnerHTML changes to the page on the fly that you effect just for the printing is one option. But I like temporarily making the page more printer friendly, then restoring the page afterwards.
Printing Just a Part of a Page
Printing the text or image contents of a div called "myDiv" can be done from a temporary window in which you recreate the div contents, and surprisingly, all browsers and platforms like this code, as long as myDiv fits on one printer page:
wi = window.open('', 'p')
wi.document.open()
element=document.getElementById("myDiv")
wi.document.write(element.innerHTML)
wi.print()
wi.document.close()
wi.close()
This does a great job of avoiding problems with the absolute positioning which innundates most pages, as well as avoiding column issues. If the div's contents fits on one printer page, this will work great!
Printing All of a Page
If all text to be printed will fit on one printer page, simply use the above routine. If not, use it repeatedly. This suggests that you could break up a page into printer-page-sized divs and have your printer routine print each in turn—in a loop. This does a great job of avoiding problems with the absolute positioning which innundates most pages, as well as avoiding multiple page issues and column issues, but, on the downside, each print() command will generate a Printer Dialog needing a response.
Temporary Page Tweaking
You'll want to avoid the multiple print dialog curse, of course. I'm not sure you always can, with Firefox/Mozilla/Netscape, due to their infamous multiple page printing bug. So you might be forced to either make special printer pages or force the multiple print dialog curse on them. However, with most browsers, you can probably get away with the tweak-print-untweak strategy below. First, make the non-text-related divs (link lists, ads, and navigation) go away by taking them out of the flow via their display property:
n=document.getElementById('z')
n.style.display='none'
And make the positioning be static in each div to be printed:
p=document.getElementById('x')
p.style.position='static'
Then print the page:
window.print()
Then restore the dumped divs and the absolute positioning:
p.style.position='absolute'
n.style.display='inline'
In reality, of course, nothing is ever that simple. The various browsers all had quirks to deal with, with Windows IE the least quirky and Firefox and Safari the most quirky. Once one page was printed, Firefox tried to call it quits so I had to run the routine from "Printing Just a Part of a Page," above, on the div that it tried to forget about, and the display='none' stuff didn't work on it at all. Safari didn't know it should turn white text on a black background into the reverse for printing, even though the other browsers did this fine, and it also printed characters that were too small and light, so I had to make the characters bigger and bold before printing them. I had to make certain navigational divs lose visibility rather than non-displaying them (m.style.visibility='hidden' and m.style.visibility='visible' afterwards). So I had to browser sniff and do different Javascripts for each browser. Here's my way of making all text in a table in a div be bold (which got restored after printing):
var table = document.getElementById("mytable");
var ee=table.getElementsByTagName("td");
for(var i=0;i<ee.length;i++){ee[i].style.fontWeight = 'bold';}
In addition, I needed to use an alert box in strategic places because the pages would get tweaked and then untweaked before the print routine ran EVEN THOUGH THE PRINT ROUTINE WAS IN THE CODE BEFORE THE RESTORING CODE! Apparently the print dialog did not bother to wait for the printing to start up before running the remainder of the code. Go figure!