这个公司项目中的一个需求,效果是打印gmap里一个弹出层的内容,由于页面本身就已经有一个打印全页内容的功能,本来是想能过改变打印样式文件来实现这个功能的,但发现如果用户先打印这个弹出层的内容后,再打印全页内容的时候,样式文件没法变回原来的那个,也就是说没法确定改回原来的那个样式文件的时间点,由于时间比较紧,所以用的是window.open方法实现的。现在项目接近尾声,所以抽空写了个iframe版的。这样就没用前面讲到的问题了,也不用担心用户的浏览器屏蔽掉弹出窗口的问题了。
function printPartOfDocument() { this.init.apply(this, arguments) } printPartOfDocument.prototype = { init: function(o, part) { this.o = this.getId(o); this.part = this.getId(part); this.frame = ''; this.printCss = ''; var _this = this; this.addEvent(this.o, 'click', function() { _this.create() }); }, create: function() { var _this = this; if (!this.frame) { var oFrame = document.createElement('iframe'); oFrame.setAttribute('id', 'printIframe'); oFrame.style.position = 'absolute'; oFrame.style.left = '-9999px'; document.body.appendChild(oFrame); } if (!this.printCss) this.printCss = this.getPrintCss(); setTimeout(function() { _this.frame = document.getElementById('printIframe'), d = _this.frame.contentWindow.document, h = d.getElementsByTagName('head')[0], b = d.getElementsByTagName('body')[0]; for (var i = 0; i < _this.printCss.length; i++) { h.appendChild(_this.printCss[i]); } b.innerHTML = ''; b.appendChild(_this.part.cloneNode(true)); _this.frame.contentWindow.print(); }, 0); }, getPrintCss: function() { var styles = document.getElementsByTagName('head')[0].getElementsByTagName('link'), printCss = []; for (var i = 0; i < styles.length; i++) { var attr = styles[i].getAttribute('media'); if (attr == 'all' || attr == 'print') printCss.push(styles[i].cloneNode(true)); } return printCss; }, getId: function(el) { return typeof el == 'string' ? document.getElementById(el) : el }, addEvent: function(o, type, fn) { if (o.addEventListener) { o.addEventListener(type, fn, false) } else if (o.attachEvent) { o.attachEvent('on' + type, function() { fn.call(o, window.event) }) } } }
HTML:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>无标题文档</title> <link href="global.css" rel="stylesheet" type="text/css"/> <link href="print.css" rel="stylesheet" type="text/css" media="print" /> <link href="print2.css" rel="stylesheet" type="text/css" media="all" /> </head> <body> <a href="javascript:void(0)" title="print" id="print">print</a> <div id="print_content"> <h1>只会打印这个div里的内容,下面的层的内容不会被打印 </h1> <p>打印测试文字,打印测试文字,打印测试文字,打印测试文字,打印测试文字,打印测试文字,打印测试文字,打印测试文字,打印测试文字,打印测试文字,打印测试文字,打印测试文字,打印测试文字,打印测试文字,</p> </div> <div> <h1>这个层的内容不会被打印</h1> <p>这里的内容不会被打印,这里的内容不会被打印,这里的内容不会被打印,这里的内容不会被打印,这里的内容不会被打印,</p> </div> <script type="text/javascript" src="printPartOfDocument.js"></script> <script type="text/javascript"> new printPartOfDocument('print','print_content'); </script> </body> </html>
CSS:
print.css @charset "utf-8"; /* CSS Document */ body { background:#CCC;} print2.css: @charset "utf-8"; /* CSS Document */ body { font-family:Arial, Helvetica, sans-serif; font-size:12px; color:#069;} div { color:#000; border:1px solid #ddd; margin:10px auto; padding:10px;} #print_content { border:1px solid red;} ,global.css 自己随便写吧。
这个函数的思路通过js在页面里动态创建一个iframe标签,然后将需要打印的内容clone到这个iframe里面,再获取页面里的media为”all”或者“print”的样式文件插入到iframe的head里面,再将iframe约对定位,left:-9999px,达到在页面上不显示的目的。最后将这个iframe打印出来即可。由于考虑到需要打印的内容也是由js动态创建的,第二次打印的时候会将先前的内容清空。这个函数需求传两个参数,一是要执行打印事件的对象,二是指定要打印的内容。