Как определить тип носителя в Javascript?

Я огляделся и не видел этого вопроса еще.

Какой надежный способ в Javascript определить тип носителя (например, экран, печать, переносчик) на странице? Я видел ссылки на document.styleSheets[0].media, но мне не повезло используя это, либо из-за проблем с поддержкой браузера, либо из-за того, что я что-то не понимаю.

Я спрашиваю, потому что я хочу, чтобы что-то скрывалось от Javascript на экране, но не в режиме просмотра. Нельзя полагаться на связанные со средой стили, потому что я использую Prototype для запуска тумблера для элемента, а Prototype не позволяет элементу переключаться на видимый, если он был объявлен невидимым (display: none) с не-встроенным CSS *. Я попытался просто установить встроенные стили для конкретного элемента для элемента (<div style="@media print { foo: bar; } @media screen { blargh: bfargle; }">), но из того, что я могу сказать, это не поддерживается.

Я знаю, что я могу циклически перебирать таблицы стилей и проверять, активна ли связанная с таблицей связанная с печатью таблица стилей, но я в настоящее время в ситуации, когда различные объявления стиля в стиле мультимедиа смешиваются в одном связанная таблица стилей, так что ничего хорошего. И да, я могу просто разделить таблицы стилей на разные типы носителей, но сначала хотел бы выяснить, могу ли я просто надежно вытащить тип носителя из DOM с помощью Javascript, полностью независимо от CSS. О, и я пробовал этот трюк "скрыть элемент для вида печати, а затем проверить, видно ли это с помощью Javascript", но это всегда приводило к (когда я загружаю предварительный просмотр). Javascript не замечает, что предполагаемый- скрытые элементы видны и выполняют любые манипуляции с DOM, о которых я рассказываю, несмотря на то, что эти элементы не видны. Если кто-нибудь хочет получить более подробную информацию о том, что я здесь говорю, я могу подробно остановиться в редактировании.

* Это то, что я не понял и постоянно раздражаюсь. Любой, кто может дать какое-либо представление об этом, получает от меня большой запас.

Ответы

Ответ 1

[..], Prototype не позволит элементу переключаться на видимый, если он был объявлен невидимым (display: none) с не-встроенным CSS. Это то, что я не понял и постоянно раздражаю. Любой, кто может дать какое-либо представление об этом, получает от меня большой запас.

Вы, вероятно, уже видели это, но документацию, например. show (есть другие связанные функции с той же нотой), что:

Element.show не может отображать элементы, скрытые с помощью стилей CSS. Обратите внимание, что это не ограничение Prototype, а следствие того, как работает CSS display.

Итак, это известная проблема, и они обвиняют 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!

Как вы уже знаете, это не сработает. Зачем? Ну, как Prototype знает, что для свойства < reset "display, когда вы сообщаете p#victim к show самому себе? (Другими словами: как узнать, что должно было быть значением display, если display: none не было в наборе правил с помощью селектора p#victim.) Ответ прост: он не может. (Подумайте об этом на секунду. Что, если другой набор правил изменит значение display, если display: none не присутствовал в нашем наборе правил с помощью селектора p#victim? (Т.е. мы не можем предположить, что, например, p всегда должно быть установлено на block, другие правила могут изменить это значение.) Мы не можем удалить свойство display из набора правил в таблице стилей, и мы не можем удалить все соединение между элементом и набор правил, потому что он может содержать другие свойства и т.д. (даже если было бы возможно, что это было бы imho, неочевидным, чтобы найти, какой набор правил для этого делать). Конечно, мы могли бы продолжать и продолжать с этим, но afaik нет известного решения этой проблемы.)

Тогда почему работает встроенная альтернатива? Во-первых, давайте посмотрим, как реализовано show:

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

Вспомним единственную важную вещь, которую выполняет эта функция, - установить element.style.display в пустую строку (''), которая "удаляет" display из style. Большой! Но что это значит? Почему мы хотим удалить его?! Сначала мы должны выяснить, что 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, и для меня есть много уровней awesomeness для чтения, и есть много случаев, когда jQuery не может вычислить правильное значение для display. (Быстрая последняя заметка: Firebug..., но я предполагаю, что она использует некоторые эксклюзивные материалы Firefox или что-то в этом роде.)

Ответ 2

EDIT: Извините (обратите внимание на себя: RTFQ Rob, sheesh!). Быстрый поиск в googling это вверх и плагин jquery если это любое использование. Он в основном использует правила @media, но не встроен, насколько я могу судить, поэтому поддержка вашего браузера может отличаться, но это лучшее, на что вы можете надеяться, поскольку я думаю: (

Ответ 3

Посмотрите, работает ли это... Я думаю, вы можете сделать это для каждого типа и просто проверить, возвращает ли оператор 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

и script, чтобы проверить его во всех браузерах (за исключением некоторых новых, поэтому будьте осторожны:))

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

этот script работает в if-statement как логическое значение true/false! Надеюсь, вы заработаете!

Ответ 4

document.getElementsByTagName('link').each(function( link )
{
  //do something with link.media
  //hide whatever you need to hide, etc
});

Ответ 5

Я тестировал свой script, упомянутый выше, теперь он работает со всеми новыми браузерами, в том числе. Окончательный вариант IE8.

Переместился script: http://cssmedia.pemor.pl/ Не стесняйтесь использовать его, если хотите.

Что касается Marcin Wiazowski