Как вы определяете тип носителя в Javascript?
-
20-08-2019 - |
Вопрос
Я огляделся и не заметил, чтобы этот вопрос еще задавался.
Какой надежный способ в Javascript определить тип носителя (напримерэкран, печать, карманный компьютер) страницы? Я видел ссылки на document.styleSheets[0].media
, но мне не повезло использовать это либо из-за проблем с поддержкой браузера, либо потому, что я чего-то не понимаю.
Я спрашиваю, потому что я хочу, чтобы что-то было скрыто Javascript в режиме просмотра экрана, но не в режиме печати.Для этого нельзя полагаться на стили, зависящие от мультимедиа, потому что я использую Prototype для запуска переключателя для элемента, а Prototype не позволяет переключать элемент в режим visible, если он был объявлен невидимым (display: none
) с нестрочным CSS*.Я попытался просто установить встроенные стили для конкретного носителя для элемента (<div style="@media print { foo: bar; } @media screen { blargh: bfargle; }">
), но из того, что я могу сказать, это не поддерживается.
Я знаю, что могу циклически просматривать таблицы стилей и проверять, активна ли связанная таблица стилей для печати или нет, но в настоящее время я нахожусь в ситуации, когда различные объявления стиля для конкретного носителя смешаны в одной связанной таблице стилей, так что это никуда не годится.И да, я могу просто разделить таблицы стилей на разные типы носителей, но сначала я хотел бы выяснить, могу ли я просто надежно извлечь тип носителя из DOM с помощью Javascript, полностью независимо от CSS.О, и я попробовал этот трюк "скрыть элемент для вида печати, затем проверить, виден ли он с помощью Javascript", но это всегда приводило к тому, что (когда я загружаю предварительный просмотр) Javascript определял, что предполагаемые скрытые элементы видны, и выполнял любые манипуляции с DOM, которые я ему указывал, несмотря на тот факт, что эти элементы не являются видимый.Если кто-нибудь захочет получить более подробную информацию о том, о чем я здесь говорю, я могу уточнить в редактуре.
* Это то, чего я не понял и постоянно раздражаюсь.Любой, кто может дать хоть какое-то представление об этом, получает от меня большое одобрение.
Решение
[..], Prototype не позволит переключить элемент в режим visible, если он был объявлен невидимым (
display: none
) с нестрочным CSS.Это то, чего я не понял и постоянно раздражаюсь.Любой, кто может дать хоть какое-то представление об этом, получает от меня большое одобрение.
Вы, вероятно, уже видели это, но документация для, например 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!
Как вы уже знаете, это не сработает.Почему?Ну, как бы Prototype узнал, что нужно "сбросить" display
свойство, когда вы сообщаете p#victim
Для show
сам по себе?(Другими словами:как он может выяснить, какой должна была быть ценность display
если в display: none
не присутствовал в наборе правил с p#victim
селектор.) Ответ прост:этого не может быть.(Подумайте об этом на секунду.Что, если другой набор правил изменит значение display
если в display: none
не присутствовал в нашем наборе правил с p#victim
селектор?(То есть.мы не можем предположить, что, например, p
всегда должно быть установлено значение block
, другие наборы правил могли изменить это значение.) Мы не можем удалить display
свойство из набора правил в таблице стилей, и мы не можем удалить всю связь между элементом и набором правил, потому что она может содержать другие свойства и так Далее (даже если бы это было возможно, было бы, имхо, неочевидно найти который набор правил для этого с помощью).Конечно, мы могли бы продолжать в том же духе, но, на самом деле, не существует известного решения этой проблемы.)
Тогда почему работает встроенная альтернатива?Во-первых, давайте посмотрим на то, как show
реализуется:
show: function(element) {
element = $(element);
element.style.display = ''; // <-- the important line
return element;
}
Afaict единственная важная вещь, которую делает эта функция, это установить 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 корректно обрабатывает содержимое таблиц стилей, во всяком случае, в данном случае!Это не так просто объяснить, как Прототип решения, и есть много уровней удивительности, с которыми мне нужно ознакомиться прямо сейчас, и есть много случаев, когда jQuery не удается вычислить правильное значение для display
.(Краткое последнее замечание:Firebug ..., но я предполагаю, что он использует какие-то эксклюзивные материалы Firefox или что-то в этом роде.)
Другие советы
Редактировать:Извините (Заметка для себя:RTFQ Роб, блин!).Быстрый поиск в Google на дерновой это вверх и a плагин jquery если это хоть как-то поможет.В основном он использует правила @media, но, насколько я могу судить, не встроенный, поэтому поддержка вашего браузера может отличаться, но, я думаю, это лучшее, на что вы можете надеяться: (
Посмотрим, сработает ли это...Я думаю, вы можете сделать это для каждого типа и просто проверить, возвращает ли оператор 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 /~марцинв/cssmedia/
этот скрипт работает в if-операторе как логическое значение true / false!Надеюсь, у вас получится!
document.getElementsByTagName('link').each(function( link )
{
//do something with link.media
//hide whatever you need to hide, etc
});
Я протестировал свой скрипт, упомянутый выше, - теперь он работает со всеми новыми браузерами, вкл.IE8 окончательный.
Сценарий перенесен сюда: http://cssmedia.pemor.pl/ Не стесняйтесь использовать его, если только вы хотите.
С уважением Marcin Wiazowski