Javascript: Print a single element

2010-02-16 – 5:18pm

Sometimes, you’ll want to allow users the ability to print only a part of your page; for example, a table but not the various links around the page. It’s possible to use a printing stylesheet, but this can cause severe headaches when you need different parts printed at different times. Really, we want to be able to just say element.printElement(), and have it just work. That’s what the MooTools function below does. It’s loosely based around the concepts outlined at this website.

Element.implement({
	printElement: function() {
		var strName = 'printer-' + (new Date()).getTime(),
		styles = $$('link[type=text/css]').clone(),
		title = document.title,
		that = this,
		iframe = new IFrame({
			name: strName,
			styles: {
				width: 1,
				height: 1,
				position: 'absolute',
				left: -9999
			},
			events: {
				load: function() {
					var doc = this.contentDocument || window.frames[strName].document;
					doc.title = title;
					$(doc.body).adopt(styles, that.clone());
					this.contentWindow.focus(); // IE requires us to focus before printing, or the parent prints.
					this.contentWindow.print();
				}
			}
		}).inject($(document.body));
		iframe.dispose.delay(15000); // Destroy the iframe in 15s so that it doesn't hang around.
	}
});
2010-02-17 – 7:37 pm

nice! A question about ie needing the div to be focussed… Is it possible for the focus to be lost before the printing starts? Is there a mechanism to prevent focus stealing? Also, can one set the visibility on the iframe to make it invisible (yes, 1×1 is small, but still…) – or could one apply a z-index to make it appear.

Just thinking aloud here – these are tiny niggles. :-)

2010-02-18 – 6:23 pm

Hi Nick,

Focussing the iframe and then printing it *should* happen consecutively and nearly instantaneously. I suppose that it’s possible (although highly unlikely) that the user could transfer focus to something else between the two operations… Unfortunately, there’s no way to make the two operations atomic.

The iframe will be invisible by virtue of the fact that it’s 9999px to the left of the viewport. :)

Add your voice

Spam protection by WP Captcha-Free