#javascript #css #dom #cross-browser
#javascript #css — код #дом #кроссбраузерный
Вопрос:
Мне нужно проверить, существует ли правило CSS, потому что я хочу выдать несколько предупреждений, если файл CSS не включен.
Каков наилучший способ сделать это?
Я мог бы отфильтровать window.document.styleSheets.cssRules
, но я не уверен, насколько это кроссбраузерно (плюс я замечаю при переполнении стека, для которого объект равен null styleSheet[0]
).
Я также хотел бы свести зависимости к минимуму.
Есть ли простой способ сделать это? Должен ли я просто создавать соответствующие элементы и тестировать эффекты?
Редактировать: Если нет, то каковы проблемы кросс-браузерной проверки window.document.styleSheets
?
Ответ №1:
Я не знаю, подходит ли вам этот вариант, но если вы хотите проверить один файл, вы можете написать свое сообщение об ошибке и переключить стиль, чтобы скрыть его в этом файле.
<span class="include_error">Error: CSS was not included!</span>
Файл CSS:
.include_error {
display: none;
visibility: hidden;
}
Комментарии:
1. Да, это было похоже на мою текущую тактику. Лучшее, что я мог бы сделать на данный момент
.css-file-loaded-marker { z-index: -98256; }
, и$('<p>').addClass('css-file-loaded-marker').css('z-index') == -98256
я понятия не имею, насколько это кроссбраузерно на самом деле, все ли браузеры поддерживают подобные z-индексы? Все ли применяют css к отдельному элементу?2. Да, я так думаю. w3schools.com/cssref/pr_pos_z-index.asp Мне больше нравится мое решение, поскольку оно имеет меньше накладных расходов и работает даже тогда, когда JavaScript отключен или jQuery не может загрузиться.
3. Да, я думаю, что это прекрасное решение, вы получили мой голос. В моем случае мне нужно знать из JS, поскольку я не контролирую html (это виджет пользовательского интерфейса jquery)
Ответ №2:
Я проверяю правильность установки CSS с помощью javascript.
В моей таблице стилей есть правило CSS, которое устанавливает для определенного идентификатора значение position: absolute .
#testObject {position: absolute;}
Затем я программно создаю временный div с visibility: hidden с этим идентификатором и получаю вычисленную позицию стиля. Если это не absolute
так, то нужный CSS не установлен.
Если вы не можете поместить свое собственное правило в таблицу стилей, то вы можете определить одно или несколько правил, которые, по вашему мнению, являются репрезентативными для таблицы стилей и вряд ли будут изменены, и создать временный объект, который должен получать эти правила и проверять их существование таким образом.
Или, наконец, вы можете попытаться перечислить все внешние таблицы стилей и найти конкретное имя файла, которое включено.
Дело в том, что если вы хотите узнать, включена ли внешняя таблица стилей, вам нужно выбрать что-то в этой таблице стилей, что вы можете искать (имя файла или какое-либо правило в нем или какой-либо эффект, который оно вызывает).
Комментарии:
1. Проблема в том, что это решение требует контроля над файлом css. Что, если у вас его нет? Я хочу проверить, например, что разработчик не забыл включить css, необходимый для стороннего виджета. Я мог бы, конечно, выбрать одно из правил, но хрупкое хрупкое хрупкое.
2. Вам придется что-то искать! Вы можете либо искать включенную таблицу стилей с определенным именем файла, либо искать существование определенного правила. Выберите то, что вы хотите искать. Вы должны что-то искать. Я сделал одно предложение, но вы можете поискать конкретное правило, которое уже есть в таблице стилей, если хотите. Да, это немного хрупко, если реализация сильно меняется, но вам нужно что-то искать, поэтому, если весь файл может измениться, тогда вы должны принять некоторую вероятность того, что ваш метод обнаружения может сломаться в будущем.
3. Да, я не против поиска правил, но поиск последствий этих правил гораздо более хрупок, потому что вам нужно сбалансировать «то, что они вряд ли изменят», и «эффект, который вряд ли возникнет в каком-то другом правиле». Если вы можете просто проверить наличие правила напрямую, вы исключите половину этого уравнения.
4. @George Mauer — Если вы хотите напрямую изучить таблицу стилей, вы можете, хотя это немного сложно сделать в кроссбраузерном режиме. Но изучение влияния на созданный пользователем div не является более хрупким и намного проще выполнять кроссбраузерные. Вы создаете div только с целевым идентификатором или классом, и если вы не получаете желаемого эффекта, тогда желаемое правило не должно быть активным.
Ответ №3:
Вот что у меня получилось, что работает. Это похоже на ответы @Smamatti и @jfriend00, но более подробно. Я действительно хотел бы, чтобы был способ напрямую проверять правила, но ладно.
CSS:
.my-css-loaded-marker {
z-index: -98256; /*just a random number*/
}
JS:
$(function () { //Must run on jq ready or $('body') might not exist
var dummyElement = $('<p>')
.hide().css({height: 0, width: 0})
.addClass("my-css-loaded-marker")
.appendTo("body"); //Works without this on firefox for some reason
if (dummyElement.css("z-index") != -98256 amp;amp; console amp;amp; console.error) {
console.error("Could not find my-app.css styles. Application requires my-app.css to be loaded in order to function properly");
}
dummyElement.remove();
});
Комментарии:
1. Черт возьми, в некоторых случаях это не удается в Chrome. Какого черта?
2. У меня всегда работает (обратите внимание, что я проверяю стиль с помощью d3). Странно. Есть новости?
3. В итоге я выбрал другой подход, так что в последнее время я действительно не пытался этого делать, извините.
Ответ №4:
Я бы использовал такой css-селектор из вашего виджета jquery.
$('link[href$="my-app.css"]')
Если вы получаете результат, это означает, что существует элемент link, который имеет href, заканчивающийся на «my-app.css»
Затем используйте эту функцию для проверки определенного свойства css для элемента, от которого вы зависите. Я бы предложил что-то конкретное для ваших стилей, например ширину контейнера, а не что-то случайное, например -9999 zindex
var getStyle = function(el, styleProp) {
var x = !!el.nodeType ? el : document.getElementById(el);
if (x.currentStyle)
var y = x.currentStyle[styleProp];
else if (window.getComputedStyle)
var y = document.defaultView.getComputedStyle(x, null).getPropertyValue(styleProp);
return y;
}
Вот так
getStyle($('#stats-container')[0], "width")
или
getStyle("stats-container", "width")
Комментарии:
1. Хорошая идея на самом деле. До сих пор это не упоминалось в этой теме, но «просто проверьте, существует ли ссылка на странице», — это совершенно правильный подход. Хотя я бы всегда рекомендовал указать параметр для подавления этой проверки в случае, если css был переименован или объединен.
2. @GeorgeMauer Если бы я создавал плагин js, основанный на css, я бы заставил js динамически загружать связанный css на страницу и запускать обратный вызов при загрузке. Таким образом, вы контролируете имя файла и время его загрузки / доступности.
3. Мы обсуждаем здесь мелочи, но я был бы в ярости, если бы нашел компонент, который делал это без переопределения, поскольку это нарушает весь смысл объединения вашего js
Ответ №5:
Если вы беспокоитесь о том, что не сможете редактировать таблицы стилей других людей, вы можете проксировать их через собственную таблицу стилей, используя import
@import url('http://his-stylesheet.css');
.hideErrorMessage{ ... }
Этого достаточно, если вы просто хотите знать, пытается ли ваш код загрузить таблицу стилей, но это не поможет, если вам нужно знать, правильно ли была загружена внешняя таблица стилей.
Комментарии:
1. Я не понимаю, как это говорит мне, был ли загружен его файл-stylesheet.css? Особая проблема заключается в том, что у меня есть виджет jQuery, который имеет зависимости от css, и я хочу, чтобы console.error выдал сообщение, если они не загружены
2. Идея заключается в том, что вы изменили бы все ссылки в своем коде с «his-StyleSheet.css» на «myProxyStylesheet.css». Как я уже упоминал, это, вероятно, не очень полезно в вашем случае (поскольку вы на самом деле хотите обнаружить внешнюю таблицу стилей), но это полезно, если вы считаете, что проблема может возникнуть из-за того, что вы просто забыли включить таблицу стилей в первую очередь.