Подтвердить что ты не робот

Как я могу определить, наследуется ли конкретное свойство CSS с помощью jQuery?

Это очень простой вопрос, поэтому я буду держать его в курсе:

Как узнать, наследуется ли какое-либо свойство CSS элемента DOM?

Причина, по которой я спрашиваю, заключается в том, что с помощью метода jQuery css он вернет вычисленный стиль, который наследует свойства CSS родительского объекта. Есть ли способ получить свойства, установленные на самом объекте?

Пример может объяснить, что я получаю немного лучше:

CSS

div#container {
  color:#fff;
}

HTML:

<div id="container">
  Something that should be interesting
  <div class="black">
    Some other thing that should be interesting
  </div>
</div>

Итак, в случае div.black, который наследует color, как я могу определить, наследуется ли он?

$('div.black:eq(0)').css('color'), очевидно, даст мне #fff, но я хочу получить стиль самого элемента, а не его родителей.

4b9b3361

Ответ 1

Чтобы на самом деле определить, был ли стиль css унаследован или установлен на самом элементе, вам нужно будет реализовать точные правила, которые применяются браузерами для определения используемого значения для определенного стиля для элемента.

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

Селектора CSS не всегда могут следовать за отношениями родитель-ребенок, которые могут иметь упрощенные вопросы. Рассмотрим этот CSS.

body {
    color: red;
}

div + div {
    color: red;
}

и следующий HTML:

<body>
    <div>first</div>
    <div>second</div>
</body>

Оба first и second wil отображаются красным цветом, однако первый div является красным, потому что он наследует его от родителя. Второй div является красным, потому что к нему применяется правило CSS div + div, что более конкретно. Посмотрев на родителя, мы увидим, что он имеет тот же цвет, но это не тот, где второй div получает его.

Браузеры не выставляют никаких внутренних вычислений, кроме интерфейса getComputedStyle.

Простым, но ошибочным решением будет выполнение каждого селектора из таблиц стилей и проверка того, удовлетворяет ли данный элемент селектору. Если да, то предположим, что стиль был применен непосредственно к элементу. Скажем, вы хотели пройти каждый стиль в первой таблице стилей,

var myElement = $('..');
var rules = document.styleSheets[0].cssRules;
for(var i = 0; i < rules.length; i++) {
    if (myElement.is(rules[i].selectorText)) {
        console.log('style was directly applied to the element');
    }
}

Ответ 2

Я не думаю, что вы можете сказать, унаследован ли данный стиль, я думаю, что лучше всего вы можете установить заданное свойство CSS для "наследования", захватить его вычисленное значение и сравнить его с исходным значением. Если они разные, стиль определенно не унаследован.

var el = $('div.black:eq(0)');
var prop = el.css("color");
el.css("color", "inherit");
var prop2 = el.css("color");
el.css("color", prop);
if(prop != prop2)
  alert("Color is not inherited.");

Демо на jsFiddle

Дело в следующем: если вы установите div.black в #fff в CSS или через встроенный стиль, этот метод будет считать, что он унаследован. Не идеальный, на мой взгляд, но он может удовлетворить ваши потребности. Боюсь, что идеальное решение требует обхода всей таблицы стилей.

Ответ 3

http://jsfiddle.net/k7Dw6/

var $black = $('div.black:eq(0)');
alert($('<div>').attr('class', $black.attr('class')).css('line-height') === $black.css('line-height'));

Вы можете создать новый элемент с тем же классом (и, я думаю, ID), и проверить, является ли свойство CSS одинаковым или нет.

Ответ 4

Я знаю, что это старый вопрос, однако я думал, что поделился бы тем, что я сделал с ответом Джоша, а именно: изменил его, чтобы удалить css, если он был унаследован, и превратил его в плагин jQuery. Пожалуйста, не стесняйтесь снимать его, но пока он работает для меня: -)

$.fn.isInheritedStyle = function(style) {
    var current = this.css(style);
    this.css(style, 'inherit');
    var inherited = this.css(style);
    if (current == inherited)
        this.css(style, '');
    else
        this.css(style, current);
    return (current == inherited);
}

Ответ 5

Если вам интересно, как стиль отличается от родительского элемента, вы можете посмотреть значение css, которое было предоставлено родительскому элементу, указав $('div.black:eq(0)'). parent ().css( 'высота строки'). Таким образом, вы можете определить, имеет ли ребенок и родитель одно значение. Однако то, что вы можете извлечь из этого, ограничено. Возможно, что и у ребенка, и у родителя было явно назначено одно и то же!

Если вас интересует гораздо более сложная структура каскада (например, как вы можете видеть в firebug), то у меня нет хорошего ответа для вас, который использует только jQuery. Там будет какой-то неэффективный взлом, который вы можете выполнить в зависимости от конкретной информации, которую вы хотите (например, клонирование объекта, как предлагалось другим, или переключение классов и проверка эффекта переключения), но это заставляет меня расстраиваться, просто думая об этом!

Как я думаю, кто-то заметил, vanilla JS позволяет вам проверять свойства конкретных элементов стиля; поэтому, возможно, гибрид jQuery и vanilla JS доставит вам то, что вам нужно?

Просмотрите http://developer.apple.com/internet/webcontent/styles.html, чтобы увидеть javascript, который дает вам доступ к информации о стилях. AFAIK это не будет "из коробки для свободного" типа вещей из jQuery (может быть, все неправильно). Тем не менее, это должно быть возможно, если вы хотите перебирать информацию о таблицах стилей.

Изменить: Удалены некоторые вещи на основе исходного кода кода вопроса

Ответ 6

Свойство element.style JS (не jQuery) возвращает объект CSSStyleDeclaration, таким образом:

{parentRule: null, 
length: 0, 
cssText: "", 
alignContent: "", 
alignItems: ""…

Если интересующий вас стиль имеет значение, то он объявляет (или применяется JS) на уровне элемента, иначе наследуется.
Информация получена из https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/style

Я боролся с HTML5 Dnd, добавляя display: list-item на уровне элемента (li) и разбивая еще одну функциональность скрыть/показать фильтр; Я смог это исправить.
Мой специальный код:

// browser bug? it adds display:list-item to the moved elements, this
// loops clear the explicit element-level "display" style
var cols = $('#columnNames li');
for( var icol = 0; icol < cols.length; icol++) {
    var d = cols[icol].style; // the CSSStyleDeclaration 
    d.display = ""; // clear the element-level style
}

Ответ 7

Я думаю, это приятное поведение jquery. Что вы хотите получить, когда $('div.black:eq(0)').css('line-height'), false или undefined? Это настолько запутанно, потому что реальное значение line-height (унаследовано, да) равно 1 em.