Topic: IE6.0打印机制解析 |
Print this page |
1.IE6.0打印机制解析 | Copy to clipboard |
Posted by: chengbd Posted on: 2004-06-21 13:49 网页打印,可以通过浏览器的"打印"功能实现,但"打印模板"机制,却是 IE 5.5 /6.0 以及 Netscape 6.0 所独有的;准确一点, IE 5.5 只是一个机制雏形,在 IE 6.0 中才得以完全体现。IE 6.0 的打印功能模块,在精确控制页面边界,文本间隔,以及打印的统一性上,功能更为完备。 通过创建打印模板,你可以精确控制: 网页打印及预览时的页面风格与内容编排风格; 打印属性,如自动为打印的页面添加卷标或编号; 精确控制打印预览界面的各个元素与变量。 通过打印模板,你可以: 自动为所有打印页面添加固定内容,如公司标识,版权申明,或者指定广告; 自定义页面标头与尾注等元素,比如页码或卷标; 指定打印历史与任务; 书本化奇偶分页映射打印...... 打印模板机制是建立在动态 HTML 语言基础上的,涉及到主要两个行为:DeviceRect, LayoutRect ,下面我们就这两个行为深入地探讨 IE 6.0 的打印机制。 另外需要说明的是,DHTML (动态超文本标识语言)的行为跟其他语言的"行为"一样,都是一种应用编程接口,初始状态下有自己的默认属性,在一定的事件下,由用户决定调用其承认的功能模块,从而产生相对应的"行为"。而且,"行为"可以自己编写,不过得以".htc"为其扩展名以供调用。 一.DeviceRect ,定义打印总体风格: 打印总体风格,包括为打印页面添加如公司标识的固定内容(网页上不一定有,只体现在打印纸张上或预览页面上,后同);打印页面的颜色风格;打印页面的边缘属性或图案;等等。 在进行 DeviceRect 引用前,先得确定页面风格,方法是用<style>进行设置。 例一:我们来定制如下的打印模板 8.5 inch 宽 11 inch 高 黄色背景 1 pixel 宽的黑色实心左边界 1 pixel 宽的黑色实心上边界 4 pixels 宽的黑色实心右边界 4 pixels 宽的黑色实心下边界 所有边界与纸张边缘为 10 pixels 的距离 现在我们用 style 进行设定,假设这个 style 名为 Mystyle1: <style TYPE="text/css"> .Mystyle1 { width:8.5in; height:11in; background:#FFFF99; border-left:1 solid black; border-top:1 solid black; border-right:4 solid black; border-bottom:4 solid black; margin:10px; } </style> 下面我们给出 DeviceRect 引用的完全页面代码, <HTML XMLNS:IE> <HEAD> <?IMPORT NAMESPACE="IE" IMPLEMENTATION="#default"> <style TYPE="text/css"> .Mystyle1 { width:8.5in; height:11in; background:#FFFF99; border-left:1 solid black; border-top:1 solid black; border-right:4 solid black; border-bottom:4 solid black; margin:10px; } </style> </HEAD> <BODY> <IE:DEVICERECT ID="page1" CLASS="Mystyle1" MEDIA="print"> </IE:DEVICERECT> <IE:DEVICERECT ID="page2" CLASS="Mystyle1" MEDIA="print"> </IE:DEVICERECT> </BODY> </HTML> 在这个页面中,共进行了两个 DeviceRect 引用。作为一种规则,每一个单独的打印页面,必须有一个相对应的 DeviceRect 标记,如果有 1000 个页面,那就得有 1000 个 DeviceRect 标记!吓住了?别担心,后面我们会教你一个方法,让所有的 DeviceRect 标记自动完成! 在上面的代码中,ID 是标志属性,不同的页面必须有自己不同的标识;CLASS 引用了 style 属性;MEDIA 属性则指明了本页面的最终用途是进行打印;<?IMPORT NAMESPACE="IE" IMPLEMENTATION="#default">这句话则是指输入默认的行为,它们分别是 DeviceRect, LayoutRect。 二.LayoutRect ,定义页面内容风格: 跟 DeviceRect 一样,不同的页面,要进行 LayoutRect 引用时都需要添加 LayoutRect 标记,其智能添加方法将在后面介绍; LayoutRect 与 DeviceRect 如果在同一个页面中同时出现,则前者需放在后者之内;另外, LayoutRect 对内容风格的设定,也通过 style 得以实现。 例二:我们来定制如下的内容风格的打印模板: 5.5 inches 宽 8 inches 高 与打印纸张边缘,四边保持 1 inch 的宽度(加上页面本身的边缘宽度,为实际的打印边缘宽度) 白色背景 1 inch 宽的虚线边界 先定制名为 contentstyle 的风格: <style TYPE="text/css"> .contentstyle { width:5.5in; height:8in; margin:1in; background:white; border:1 dashed gray; } </style> 然后下面是进行引用的完整网页代码: <HTML> <HEAD> <?IMPORT NAMESPACE="IE" IMPLEMENTATION="#default"> <style TYPE="text/css"> .contentstyle { width:5.5in; height:8in; margin:1in; background:white; border:1 dashed gray; } </style> </HEAD> <BODY> <IE:LAYOUTRECT ID="layoutrect1" CONTENTSRC="2.html" CLASS="contentstyle" NEXTRECT="layoutrect2"/> <IE:LAYOUTRECT ID="layoutrect2" CLASS="contentstyle"/> </BODY> </HTML> 跟例一中的源代码相比,例二中只是以 LayoutRect 代替了原来的 DeviceRect 标记;DeviceRect 定制的是模板整体风格,而 LayoutRect 定制的是具体内容的版面风格;LayoutRect 的 ID 属性也具有唯一性; CONTENTSRC 属性则指明了具体的将起作用网页文件;CLASS 指明了风格的引用对象;跟 DeviceRect 不同,在进行 LayoutRect 引用时,必须在每个页面指定 NEXTREC ,即依次排列的下一个内容风格,这里的"下一个内容"用其页面的相应 ID 进行标识,如本例中的 LayoutRect2 。 三.DeviceRect 与 LayoutRect 的协同作战: 上面我们分别讨论了 DeviceRect 与 LayoutRect 的作用与引用方法,现在我们来看一下,如何在同一个打印模板中进行定制与引用。 在每一个打印模板上,必然包含两方面的内容,一个是整体的模板风格(DeviceRect),另一个是内容风格(LayoutRect);第一个打印页面跟其他页面是不同的,因为第一个页面中必须指明 CONTENTSRC 属性,而同一打印任务中的其他页面不再需要进行 CONTENTSRC 的指定。 例三: 下面是第一个页面中的 DeviceRect 代码: <IE:DEVICERECT ID="page1" CLASS="masterstyle" MEDIA="print"> <IE:LAYOUTRECT ID="layoutrect1" CONTENTSRC="2.html" CLASS="contentstyle" NEXTRECT="layoutrect2"/> </IE:DEVICERECT> 下面是其他页面中的 DeviceRect 代码: <IE:DEVICERECT ID="page2" CLASS="masterstyle" MEDIA="print"> <IE:LAYOUTRECT ID="layoutrect2" CLASS="contentstyle"/> </IE:DEVICERECT> 下面我们将 DeviceRect 与 LayoutRect 结合起来使用,其源代码如下: <HTML XMLNS:IE> <HEAD> <?IMPORT NAMESPACE="IE" IMPLEMENTATION="#default"> <style TYPE="text/css"> .contentstyle { width:5.5in; height:8in; margin:1in; background:white; border:1 dashed gray; } .Mystyle1 { width:8.5in; height:11in; background:#FFFF99; border-left:1 solid black; border-top:1 solid black; border-right:4 solid black; border-bottom:4 solid black; margin:10px; } </style> </HEAD> <BODY> <IE:DEVICERECT ID="page1" CLASS="Mystyle1" MEDIA="print"> <IE:LAYOUTRECT ID="layoutrect1" CONTENTSRC="2.html" CLASS="contentstyle" NEXTRECT="layoutrect2"/> </IE:DEVICERECT> <IE:DEVICERECT ID="page2" CLASS="Mystyle1" MEDIA="print"> <IE:LAYOUTRECT ID="layoutrect2" CLASS="contentstyle"/> </IE:DEVICERECT> </BODY> </HTML> 四.DeviceRect 与 LayoutRect 标记的动态自动添加: 前面我们说到,每个单独的打印页面都需要各自的 DeviceRect 与 LayoutRect 标记,那么,如果我们有 1000 个页面需要打印,是否就要在每个页面上重复繁琐的 Copy & Paste 操作? 答案是否定的,我们完全可以通过 JavaScript 脚本来完成这一繁琐的工作。 要实现 HTML 声明的动态创建,关键在于 <DIV> 标记的定义,下面是其定义规则。 <DIV ID="devicecontainer"> ...... </DIV> <DIV>与</DIV>之间,采用 insertAdjacentHTML() 方式,并主要利用了其 afterBegin 与 BeforeEnd 两个变量,现在我们将第一个页面"插入"到<DIV></DIV>之间: devicecontainer.insertAdjacentHTML("afterBegin", newHTML); 具有继承属性的后续页面,调用 beforeEnd 变量: devicecontainer.insertAdjacentHTML("beforeEnd", newHTML); 要装载 devicecontainer 页面,还需在 <Body>中添加: <BODY ONLOAD="addFirstPage()"> 现在我们在 JavaScript 中添加包含前面详细介绍的 LayoutRect 与 DeviceRect 元素,用到的命令是 addFirstPage() 。需要注意的是,newHTML 标记后使用的是双引号,而 LayoutRect 与 DeviceRect 标记后的变量使用单引号。如下: function addFirstPage() { newHTML = "<IE:DEVICERECT ID='devicerect1' MEDIA='print' CLASS='mystyle1'>"; newHTML += "<IE:LAYOUTRECT ID='layoutrect1' CONTENTSRC='2.html'" + "ONLAYOUTCOMPLETE='onPageComplete()' NEXTRECT='layoutrect2'" + "CLASS='contentstyle'/>"; newHTML += "</IE:DEVICERECT>"; devicecontainer.insertAdjacentHTML("afterBegin", newHTML); } 细心的读者一定会发现,LayoutRect 后出现了一个新的属性:LayoutRect:onLayoutComplete ,这个属性主要指定了 LayoutRect 停止响应的后续事件,如系统资源消耗殆尽而停止响应,或者 LayoutRect 指定的变量溢出。 好了,有了上面的原理,下面我们来编写具有自动"插入"功能的 JavaScript 代码: function onPageComplete() { if (event.contentOverflow) { newHTML = "<IE:DEVICERECT ID='devicerect" + (lastPage + 1) + "' MEDIA='print' CLASS='mystyle1'>"; newHTML += "<IE:LAYOUTRECT ID='layoutrect" + (lastPage + 1) + "' ONLAYOUTCOMPLETE='onPageComplete()' NEXTRECT='layoutrect" + (lastPage + 2) + "' CLASS='contentstyle'/>"; newHTML += "</IE:DEVICERECT>"; devicecontainer.insertAdjacentHTML("beforeEnd", newHTML); lastPage++; } 在上面的代码中,contentOverflow 代表的是由于页面信息过长,本页的 LayoutRect 停止响应,则直接跳到下一个页面,让 LayoutRect 重新定义下一个页面的版面;onPageComplete() 则不管页面是否过长,LayoutRect 是否停止响应,只要到了页面尾部则自动跳到下一页,这也是最常见的情况。 在编写本脚本时,关键处在于保持清醒,不能让任意一个变量出错。其中,ID 不仅针对 DeviceRect 与 LayoutRect ,还为 NextRect 所引用,页面指向不能出错;当前页面的页码应该是 lastPage+1 ,下一个页面的页码应该是 lastPage+2 ;NextRect 标记需要下一个页面的 LayoutRect 属性支持,因此它的值应该为 "layoutRect"+(lastPage+2);打开第一个页面时,这个 LastPage 初始值为 1 |
2.Re:IE6.0打印机制解析 [Re: chengbd] | Copy to clipboard |
Posted by: aegean Posted on: 2004-07-30 14:17 好,看到这个,有了思路,一直浏览器打印总是很成问题的。谢谢 |
3.Re:IE6.0打印机制解析 [Re: chengbd] | Copy to clipboard |
Posted by: xiaodong_1567 Posted on: 2004-07-31 10:23 满有帮助的,谢了 |
4.Re:IE6.0打印机制解析 [Re: chengbd] | Copy to clipboard |
Posted by: 猪七戒 Posted on: 2004-08-14 19:26 不错! 很有帮助!谢谢楼主! |
5.Re:IE6.0打印机制解析 [Re: chengbd] | Copy to clipboard |
Posted by: wanglive Posted on: 2004-09-02 15:24 不错,很有帮助. |
6.Re:IE6.0打印机制解析 [Re: chengbd] | Copy to clipboard |
Posted by: javadd Posted on: 2004-11-28 13:39 哇哇,非常感谢. |
7.Re:IE6.0打印机制解析 [Re: chengbd] | Copy to clipboard |
Posted by: frankwater Posted on: 2004-12-12 23:49 不错,非常感谢! |
8.Re:IE6.0打印机制解析 [Re: chengbd] | Copy to clipboard |
Posted by: madamimadam Posted on: 2005-01-28 22:16 俺是菜鸟一个啊,为什么我在IE6.0 的打印菜单中看不见有打印模版这个选项? 是不是需要自行写那个模版的? |
9.Re:IE6.0打印机制解析 [Re: chengbd] | Copy to clipboard |
Posted by: miaoql Posted on: 2005-03-12 08:14 good,thanks |
10.Re:IE6.0打印机制解析 [Re: miaoql] | Copy to clipboard |
Posted by: YuLimin Posted on: 2005-03-12 19:52 不错,收藏之:) |
Powered by Jute Powerful Forum® Version Jute 1.5.6 Ent Copyright © 2002-2021 Cjsdn Team. All Righits Reserved. 闽ICP备05005120号-1 客服电话 18559299278 客服信箱 714923@qq.com 客服QQ 714923 |