使用Javascript更改显示样式(CSS)而不影响打印样式

问题描述:

我有一个Web应用程序,它利用单独的print stylesheet来控制页面从打印机出来时的外观。直到我最近对该网站做了一些Javascript增强功能之后,这一切才奏效。其中一个增强功能允许用户冻结页面标题和导航以及表格标题。这背后的Javascript做了一些CSS技巧来冻结屏幕上的元素。不幸的是,将position: fixed应用于我的标题(例如)会导致它在每个页面上打印,而这不是预期的效果。我如何使用Javascript来调整客户端的元素样式而不影响打印样式?使用Javascript更改显示样式(CSS)而不影响打印样式

@media print { #foo { color: blue; } }    /* Print definition */ 
@media screen { #foo { color: green; } }    /* Display definition */ 
document.getElementById('foo').style.color = 'red'; /* Overrides both! */ 
+0

注意:很多用Javascript改变的样式甚至都没有在CSS打印文件中设置。理想情况下,我将有一种方法来改变*只显示*样式在Javascript中。必须用'!important'手动覆盖CSS打印文件中的所有JS调整并不是真正的解决方案。 – 2011-06-13 19:59:26

没有好的解决方案!我结束了被利用onbeforeprintonafterprint功能在IE(我在这里的位置,我们只有IE用户)“解冻”和“重新冻结”的元素做...

window.onbeforeprint = function() { 
    document.getElementById('foo').style.position = 'static'; 
} 

window.onload = window.onafterprint = function() { 
    var el = document.getElementById('foo'); 
    // Get element position and size 
    // Set left/top/width/height properties 
    // Set position to fixed 
    el.style.position = 'fixed'; 
} 
+0

[html5shiv](http://code.google.com/p/html5shiv/)的功能与在旧版IE中支持打印HTML5元素类似。所以,这项技术是强大的。 – thirtydot 2011-06-21 00:32:18

!important添加到您的打印规则。

+0

咦?这不会做任何事情。我甚至没有在我的CSS规则中设置“位置”(或者我用JavaScript调整的其他任何东西)。 – 2011-06-13 19:54:06

+0

我想这意味着我将不得不重写每个我用Javascript调整的样式?我可以看到那里的目标!所以明年当我必须改变Javascript时,我会忘记更改CSS覆盖...... Ug-leeeee – 2011-06-13 19:55:38

+0

顺便说一句,我试着添加这个并设置'position:static!important'来避免打印时的固定位置,现在它每次尝试打印或预览时都会使IE崩溃! – 2011-06-13 20:12:48

你可以试试这个 @media print {#foo {color:blue!important; }}

问题是,javascript。style.something,编辑元素的内联css,因此它会覆盖正常的css类/ id规则。

或者你也可以和班级一起工作。 document.getElementById('foo')。className ='redText';

并将.redText保存在您的常规css文件中(而不是打印文件),比填写!print重要规则要好得多。

+0

感谢您提供更完整的答案。我很伤心有没有更清洁的方式,像'document.getElementById('foo')。displayStyle.color ='green';' – 2011-06-13 19:57:44

+0

不幸的是,没有,没有。但是使用类实际上很干净。因为当你以后回来做一些维护时,你会发现CSS中的所有样式规则(它们在语义上属于它们),而不必编辑你的CSS和JS文件。 – Pantelis 2011-06-13 19:59:44

+0

不是一个真正的选择。如果您考虑冻结页面上的元素,您必须修复位置,然后在父代中设置其精确的坐标。如果这些元素的内容因页面而异,则无法预测它将占用的大小(如果您使用的是任何类型的流布局),因此必须在Javascript中动态进行更改。我卡住了。 – 2011-06-13 20:03:11

而不是在你的元素更改属性与此的:

document.getElementById('foo').style.color = 'red'; 

追加新<style>元素,例如:

$('<style>@media screen { #foo { color: green; } }</style>').appendTo('head'); 

这将是更好的所有所需的更改连接成一个<style>元素,如果可能的话。

+2

好主意。我已经在IE6,IE9,Chrome和FF5上测试过了。 – 2011-08-05 01:37:22

正确解决方案是不捅到风格节点,但不是配合你的屏幕特定风格的调整,以CSS类仅影响的事情你的屏幕再现:

@media screen { .freeze { position: fixed; } } /* Display-only definition */

+

document.getElementById('foo').className = "freeze";

作为奖励,这也使得只需一行js即可轻松更改大量样式,这使得事情更快,更容易维护。