让IE6/7/8支持CSS3 media print(Media Queries)打印样式

!本文可能 超过1年没有更新,今后内容也许不会被维护或者支持,部分内容可能具有时效性,涉及技术细节或者软件使用方面,本人不保证相应的兼容和可操作性。

某个项目需要支持打印样式,测试下来Chrome和FireFox正常,唯独IE8无法应用打印样式,也就是说识别不了@media定义的CSS样式节。

网上解决的办法也五花八门,我在这里整理一下,首先我们还是要从让IE支持media的的思路开始,首先JavaScript大将出马。

1. 项目css3-mediaqueries-js

该项目由Wouter van der Graaf发起(项目地址),旨在为了提供对于类似于IE 5+Firefox 1+Safari 2低版本浏览器的Media Queries支持,使用方式也很简单,直接引用脚本即可,当然现在基本上非IE的浏览器和IE9及以上版本已经原生支持Media Queries了,所以我们可以使用IE特有的条件注释处理代码引用,比如下面的代码示例:

<!-- css3-mediaqueries.js for IE less than 9 -->
<!--[if lt IE 9]>
<script 
   src="//css3-mediaqueries-js.googlecode.com/svn/trunk/css3-mediaqueries.js">
</script>
<![endif]-->

遗憾的是在IE8浏览器下实际测试下来并没有效果。

2. 使用CSS Hack

IE各个版本对CSS都有一些怪异的支持模式,猜测是浏览器开发人员故意留下的,所以我们可以利用这种特性对IE浏览器进行CSS Hack。

Keith Clark在其博文《Moving IE specific CSS into @media blocks》提供了一种CSS Hack的新思路:

目标平台IE6或者IE7:

@media screen\9 {
    body { background: red; }
}

目标平台IE6、7和8:

@media \0screen\,screen\9 {
    body { background: green; }
}

目标平台IE8:

@media \0screen {
    body { background: blue; }
}

目标平台IE8、9和10:

@media screen\0 {
    body { background: orange; }
}

目标平台IE9和10:

@media screen and (min-width:0\0) {
    body { background: yellow; }
}

使用示例

body {
  background: pink;
}
 
/* IE 6 and 7 fallback styles */
@media all\9 {
    body {
        background: red;
    }
    h1 {
        color: yellow;
    }
}
 
/* IE 6 and 7 fallback print styles */
@media print\9 {
    body {
        color: blue;
    }
    h1 {
        color: red;
    }
}

大家可以访问《IE specific CSS rules and bypass filters using @media block hacks》来测试相关属性及获取支持情况。

3. 使用onbeforeprint和onafterprint方法

这里我再提供一个思路供大家参考,我们可以给body设置一个id,比如这样的:

<html>
	<head></head>
	<body id="MyPage"></body>
</html>

然后JavaScript代码可以这样写:

window.onbeforeprint = function() {
    document.getElementById("MyPage").className += " printstyle";
};
window.onafterprint = function() {
    document.getElementById("MyPage").className =
   	document.getElementById("MyPage").className.replace
      		( /(?:^|\s)printstyle(?!\S)/g , '' );
};

最后CSS代码类似如下:

.printstyle div { /* div style */ }
.printstyle p { /* paragraph style */ }

这里利用了JavaScript触发的打印前和打印后的两个事件,对页面的class引用做出修改,这样就可以让不同的CSS样式表发生作用。

这里再说个题外话:onbeforeprintonafterprint在IE和FireFox中支持良好,如果我们需要利用这两个事件设置其他的效果,这时发现这个事件属性不是跨浏览器的,比如WebKit家族的Chrome就不支持,参考《Detecting Print Requests with JavaScript》这里有个替代的办法:

var mediaQueryList = window.matchMedia('print');
mediaQueryList.addListener(function(mql) {
    if (mql.matches) {
        console.log('onbeforeprint equivalent');
    } else {
        console.log('onafterprint equivalent');
    }
});

兼容的写法如下:

(function() {
    var beforePrint = function() {
        console.log('Functionality to run before printing.');
    };
    var afterPrint = function() {
        console.log('Functionality to run after printing');
    };
 
    if (window.matchMedia) {
        var mediaQueryList = window.matchMedia('print');
        mediaQueryList.addListener(function(mql) {
            if (mql.matches) {
                beforePrint();
            } else {
                afterPrint();
            }
        });
    }
 
    window.onbeforeprint = beforePrint;
    window.onafterprint = afterPrint;
}());

好了,扯多了,让我们继续回到IE浏览器打印上面,毕竟其他浏览器对页面打印支持良好。

参考微软MSDN的文章《Scripting Support for Web Page Printing》我们可以获取更多关于IE打印专属的特性,比如我们除了使用window.print()调用打印功能外还可以使用WebBrowser控件实现相关功能,比如下面的代码同样的实现了打印:

document.body.insertAdjacentHTML("beforeEnd",
    "<object id=\"idWBPrint\" width=0 height=0 \
      classid=\"clsid:8856F961-340A-11D0-A96B-00C04FD705A2\">
    </object>");
  idWBPrint.ExecWB(6, 1);
  idWBPrint.outerHTML = "";

实际上对于IE来说ExecWB还有更多的功能实现,比如:

WebBrowser.ExecWB(6,1)  // 打印
WebBrowser.ExecWB(7,1)  // 打印预览
WebBrowser.ExecWB(8,1)  // 打印页面设置
WebBrowser.ExecWB(10,1) // 查看页面属性

今天的介绍就到这里。

参考文档:

《Change an element’s CSS class with JavaScript》

若无特别说明,本网站文章均为原创,原则上这些文章不允许转载,但是如果阁下是出于研究学习目的可以转载到阁下的个人博客或者主页,转载遵循创作共同性“署名-非商业性使用-相同方式共享”原则,请转载时注明作者出处谢绝商业性、非署名、采集站、垃圾站或者纯粹为了流量的转载。谢谢合作!

  1. 您好!跟您的博客申请友情链接,我们的网址是www.wanjee.cn 我们是做免费在线SaaS运维、监控平台的,方便有需要的用户到您那去学习知识!加qq2468199527详聊,或者入群37960299跟许多写运维博客的博主交流经验或者互相交换友情链接。

请稍后...

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*