15

我环顾四周,还没有看到这个问题。

Javascript 中确定页面媒体类型(例如屏幕、打印、手持设备)的可靠方法是什么?我看过对 的引用document.styleSheets[0].media,但我没有运气使用它,要么是因为浏览器支持问题,要么是因为我不理解某些东西。

我问是因为我希望 Javascript 在屏幕视图中隐藏某些内容,而不是在打印视图中。不能依赖媒体相关的样式来执行此操作,因为我正在使用 Prototype 为元素运行切换开关,如果元素被声明为不可见(display: none), Prototype 将不允许将其切换为可见-内联 CSS*。我试图为元素 ( <div style="@media print { foo: bar; } @media screen { blargh: bfargle; }">) 设置特定于媒体的内联样式,但据我所知,这不受支持。

我知道我可以循环浏览样式表并检查特定于打印的链接样式表是否处于活动状态,但我目前处于各种特定媒体样式声明都混合在单个链接样式表中的情况,所以这不好。是的,我可以将样式表拆分为不同的媒体类型,但我首先想弄清楚我是否可以使用 Javascript 可靠地将媒体类型从 DOM 中拉出,完全独立于 CSS。哦,我已经尝试过“隐藏打印视图的元素,然后检查它是否在 Javascript 中可见”的技巧,但那尽管这些元素是不可见的。如果有人想了解我在这里谈论的更多细节,我可以在编辑中详细说明。

*这是我不理解并且经常被激怒的东西。任何可以提供任何见解的人都会得到我的大力支持。

4

5 回答 5

4

display: none[..],如果使用非内联 CSS将元素声明为不可见(),Prototype 将不允许将元素切换为可见。这是我一直不理解并且经常被激怒的东西。任何可以提供任何见解的人都会得到我的大力支持。

您可能已经看到了这一点,但是 eg 的文档show(还有其他具有相同注释的相关函数)指出:

Element.show 无法显示通过 CSS 样式表隐藏的元素。请注意,这不是原型限制,而是 CSSdisplay属性如何工作的结果。

所以,这是一个已知的问题,他们责怪 CSS。但是,请考虑以下文档(我之前没有使用过 Prototype,所以我不确定这是否是等待 DOM 加载的推荐方式,但它似乎有效):

<!doctype html>
<script src="prototype.js"></script>
<script>
document.observe("dom:loaded", function() {
  $("victim").show();
});
</script>
<style>
p#victim {display:none;}
</style>
<p id="victim">Hello world!

正如您已经知道的那样,这是行不通的。为什么?display好吧,当您告诉自己时,Prototype 怎么知道将属性p#victim“重置”show为什么?(换句话说:display如果display: none没有在规则集中使用p#victim选择器,它如何找出应该是什么值。)答案很简单:它不能。(想一想。如果另一个规则集使用选择器修改我们的规则集中不存在的值怎么display办?(即我们不能假设 eg always 应该设置为,其他规则集可能已更改该值。)我们无法删除display: nonep#victimpblockdisplay样式表中规则集的属性,我们不能删除元素和规则集之间的整个连接,因为它可能包含其他属性等等(即使有可能,恕我直言,不明显找到使用哪个规则集执行此操作)。当然,我们可以继续这样做,但是 afaik 这个问题没有已知的解决方案。)

那么为什么内联替代方案有效呢?首先,让我们看看是如何show实现的:

show: function(element) {
  element = $(element);
  element.style.display = ''; // <-- the important line
  return element;
}

这个函数唯一重要的事情就是设置element.style.display一个空字符串 ( ''),它displaystyle. 伟大的!但是,这是什么意思?为什么我们要删除它?!首先,我们必须找出element.style当我们修改它的值时实际代表和修改了什么。

MDC 文档element.style说明:

返回一个表示元素style属性的对象。

注意最后一个词:属性element.style≠ 元素的当前“计算”样式,它只是属性中的style属性列表(请参阅 MDC 以获得更长/更好的解释)。

考虑以下文档:

<!doctype html>
<script src="prototype.js"></script>
<script>
document.observe("dom:loaded", function() {
  $("victim").show();
});
</script>
<p id="victim" style="display:none;">Hello world!

style="display:none;"隐藏p#victim,但是当 DOM 完成加载时,Prototype 会将其更改为style="",并且浏览器将重新计算该display属性的值(在这种情况下,该值来自浏览器的默认样式表)。

但是,请考虑以下文档:

<!doctype html>
<script src="jquery.js"></script>
<script>
$(document).ready(function(){
  $("#victim").show();
});
</script>
<style>
p#victim {display:none;}
</style>
<p id="victim">Hello world!

jQuery 正确地处理样式表的东西,在这种情况下无论如何!这不像 Prototype 解决方案那样容易解释,而且我现在需要阅读许多令人敬畏的层面,并且在很多情况下 jQuery 无法计算出正确的display. (最后一个提示:Firebug ...,但我猜它使用了一些 Firefox 独有的东西或其他东西。)

于 2009-01-31T01:21:44.287 回答
1

编辑:对不起(自我说明:RTFQ Rob,哎呀!)。一个快速的谷歌搜索把它和一个jquery 插件(如果有的话)搞定了。据我所知,它基本上使用@media 规则,但不是内联的,因此您的浏览器支持可能会有所不同,但这是您希望的最好的我认为:(

于 2009-01-30T10:56:04.907 回答
1

看看这是否有效......我认为您可以对每种类型执行此操作,只需检查语句是否返回 null 或等效项,然后应用您的规则。

从这个网站:http ://www.webdeveloper.com/forum/showthread.php?t=82453

IE:

if (document.styleSheets[0].media == 'screen'){...}

FF/NS:

document.getElementsByTagName ('LINK')[0].getAttribute ('media')

或者

document.styleSheets[0].media.mediaText

和一个在所有浏览器中检查它的脚本(除了一些新浏览器,所以要小心:))

http://student.agh.edu.pl/~marcinw/cssmedia/

此脚本在 if 语句中作为布尔值 true/false 工作!希望你能得到它的工作!

于 2009-01-30T19:05:35.340 回答
0
document.getElementsByTagName('link').each(function( link )
{
  //do something with link.media
  //hide whatever you need to hide, etc
});
于 2009-01-30T02:02:55.623 回答
0

我已经测试了上面提到的脚本 - 它现在适用于所有新浏览器,包括。IE8 决赛。

脚本移至此处:http ://cssmedia.pemor.pl/ 如果您愿意,请随意使用它。

关于 Marcin Wiazowski

于 2009-04-01T10:43:17.730 回答