Как проверить, существует ли правило css

#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». Как я уже упоминал, это, вероятно, не очень полезно в вашем случае (поскольку вы на самом деле хотите обнаружить внешнюю таблицу стилей), но это полезно, если вы считаете, что проблема может возникнуть из-за того, что вы просто забыли включить таблицу стилей в первую очередь.