Изменить объект, когда другой объект зависает [дубликат]

Что вы должны знать о this

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

function foo() {
    console.log(this);
}

// normal function call
foo(); // `this` will refer to `window`

// as object method
var obj = {bar: foo};
obj.bar(); // `this` will refer to `obj`

// as constructor function
new foo(); // `this` will refer to an object that inherits from `foo.prototype`

Чтобы узнать больше о this, просмотрите документацию MDN .


Как сделать обратитесь к правильному this

Не используйте this

Фактически вы не хотите иметь доступ к this в частности, но объект, на который он ссылается на . Вот почему простое решение - просто создать новую переменную, которая также относится к этому объекту. Переменная может иметь любое имя, но общие - self и that.

function MyConstructor(data, transport) {
    this.data = data;
    var self = this;
    transport.on('data', function() {
        alert(self.data);
    });
}

Поскольку self является нормальной переменной, она подчиняется лексическим правилам области и доступна внутри обратного вызова. Это также имеет то преимущество, что вы можете получить доступ к значению this самого обратного вызова.

Явно установить this обратного вызова - часть 1

Возможно, у вас есть не контролируйте значение this, потому что его значение устанавливается автоматически, но на самом деле это не так.

Каждая функция имеет метод .bind [docs] , который возвращает новую функцию с this, привязанную к значению. Функция имеет то же поведение, что и тот, который вы назвали .bind, только то, что this было установлено вами. Независимо от того, как и когда эта функция вызывается, this всегда будет ссылаться на переданное значение.

function MyConstructor(data, transport) {
    this.data = data;
    var boundFunction = (function() { // parenthesis are not necessary
        alert(this.data);             // but might improve readability
    }).bind(this); // <- here we are calling `.bind()` 
    transport.on('data', boundFunction);
}

В этом случае мы привязываем обратный вызов this к значению MyConstructor 's this.

Примечание. При связывании контекста для jQuery вместо этого используйте jQuery.proxy [docs] . Причина этого заключается в том, что вам не нужно сохранять ссылку на функцию при отмене обратного вызова события. jQuery обрабатывает это внутренне.

ECMAScript 6: Используйте функции стрелок

В ECMAScript 6 представлены функции стрелок , которые можно рассматривать как лямбда-функции. У них нет собственной привязки this. Вместо этого this просматривается в области видимости как обычная переменная. Это означает, что вам не нужно называть .bind. Это не единственное особое поведение, которое у них есть. Дополнительную информацию см. В документации MDN.

function MyConstructor(data, transport) {
    this.data = data;
    transport.on('data', () => alert(this.data));
}

Установите this обратного вызова - часть 2

Некоторые функции / методы, которые принимают обратные вызовы, также принимают значение, к которому должен обращаться обратный вызов this. Это в основном то же самое, что и привязывать его самостоятельно, но функция / метод делает это за вас. Array#map [docs] - такой метод. Его подпись такова:

array.map(callback[, thisArg])

Первый аргумент - это обратный вызов, а второй аргумент - значение this. Вот надуманный пример:

var arr = [1, 2, 3];
var obj = {multiplier: 42};

var new_arr = arr.map(function(v) {
    return v * this.multiplier;
}, obj); // <- here we are passing `obj` as second argument

Примечание. Можно ли передать значение для this, как правило, упоминается в документации этой функции / метода. Например, метод $.ajax jQuery [docs] описывает параметр, называемый context:

Этот объект станет контекстом всех обратных вызовов, связанных с Ajax.


Общая проблема: использование объектных методов в качестве обработчиков обратных вызовов / событий

Еще одно распространенное проявление этой проблемы - когда объектный метод используется как обработчик обратного вызова / события , Функции являются первоклассными гражданами в JavaScript, а термин «метод» - просто разговорный термин для функции, которая является значением свойства объекта. Но эта функция не имеет конкретной ссылки на ее «содержащий» объект.

Рассмотрим следующий пример:

function Foo() {
    this.data = 42,
    document.body.onclick = this.method;
}

Foo.prototype.method = function() {
    console.log(this.data);
};

Функция this.method назначается как обработчик события click , но если щелкнуть document.body, зарегистрированное значение будет undefined, потому что внутри обработчика события this ссылается на document.body, а не на экземпляр Foo. Как уже упоминалось в начале, то, что относится к [49], зависит от того, как называется функция, а не от того, как она определена. Если код выглядит следующим образом, может быть более очевидно, что функция не имеет неявной ссылки на объект:

function method() {
    console.log(this.data);
}


function Foo() {
    this.data = 42,
    document.body.onclick = this.method;
}

Foo.prototype.method = method;

Решение такое же, как указано выше: если доступно, используйте .bind явно привязать this к определенному значению

document.body.onclick = this.method.bind(this);

или явно вызвать функцию как «метод» объекта, используя анонимную функцию в качестве обработчика обратного вызова / события и назначить object (this) к другой переменной:

var self = this;
document.body.onclick = function() {
    self.method();
};

или использовать функцию стрелки:

document.body.onclick = () => this.method();
1084
задан Dmitry Gonchar 7 December 2015 в 16:06
поделиться

14 ответов

Нет, селектор «предыдущего сиблинга» отсутствует.

В соответствующей заметке ~ используется для общего брака-последователя (это означает, что элемент появляется после этого, но не обязательно сразу после) и является селектором CSS3. + для следующего родного брата и является CSS2.1.

См. Комбинированный смежный блок-класс из Селектора уровня 3 и 5.7 Смежные селекторные ролики из Каскадные таблицы стилей Уровень 2 Редакция 1 (CSS 2.1) Спецификация .

672
ответ дан Domenic 22 August 2018 в 16:05
поделиться
  • 1
    Из стандарта CSS3: Элементы, представленные двумя последовательностями , совместно используют один и тот же родительский элемент в дереве документов, а элемент, представленный первой последовательностью , предшествует (не обязательно сразу ) элемент, представленный вторым. – Lie Ryan 26 February 2011 в 17:34
  • 2
    @Lie Ryan: Да, но пункт cletus делает в его ответе, что вы не выбираете предыдущий элемент. – BoltClock♦ 29 March 2011 в 22:05
  • 3
    Вот пример, который я сделал, чтобы понять, что это может и не может сделать. jsfiddle.net/NuuHy/1 – Abacus 17 July 2013 в 19:26
  • 4
    Функция jquery, полезная для этого, - prev (). Например, $ («# the_element»). Prev (). Css («background-color», «red») – Satbir Kira 18 May 2015 в 21:11
  • 5
    В зависимости от вашей разметки это может помочь: stackoverflow.com/questions/42680881/… – samnau 18 April 2018 в 14:09

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

Что вы можете сделать, это использовать селектор CSS3: псевдо classe nth-child()

#list>* {
  display: inline-block;
  padding: 20px 28px;
  margin-right: 5px;
  border: 1px solid #bbb;
  background: #ddd;
  color: #444;
  margin: 0.4em 0;
}

#list :nth-child(-n+4) {
  color: #600b90;
  border: 1px dashed red;
  background: orange;
}
<p>The oranges elements are the previous sibling li selected using li:nth-child(-n+4)</p>

<div id="list">
  <span>1</span><!-- this will be selected -->
  <p>2</p><!-- this will be selected -->
  <p>3</p><!-- this will be selected -->
  <div>4</div><!-- this will be selected -->
  <div>5</div>
  <p>6</p>
  <p>7</p>
  <p>8</p>
  <p>9</p>
</div>

Ограничения

  • Вы не можете выбрать предыдущие элементы основанный на классах следующих элементов
  • Это то же самое для псевдо классов
11
ответ дан allicarn 22 August 2018 в 16:05
поделиться
  • 1
    Почему они должны быть одним и тем же узлом? Почему бы просто не использовать :nth-child(-n+4)? – Ian 27 October 2014 в 21:13
  • 2
    @Ian, потому что :nth-child(-n+4) является псевдо-классом, который должен применяться к селектору для правильной работы. Если вы не убедите, попробуйте поэкспериментировать, используя вилку своей скрипки, и вы увидите, что она не будет – 0x1gene 28 October 2014 в 01:11
  • 3
    Фактически, вы можете использовать независимый тип узла, используя селектор *, но это неприятная практика. – Josh Burgess 13 January 2015 в 20:07
  • 4
    Это ответ, который работал для меня, не знаю, почему он не проголосовали выше или не принят. – Jake Cattrall 23 January 2015 в 15:59
  • 5
    Фактически, он работает для разных узлов: jsfiddle.net/aLhv9r1w/316 . Обновите свой ответ :) – Jamie Barker 1 June 2015 в 10:44

К сожалению, нет «предыдущего» селектора, но вы можете , возможно, получить тот же эффект, используя позиционирование (например, float right). Это зависит от того, что вы пытаетесь сделать.

В моем случае я хотел получить первую 5-звездочную рейтинговую систему CSS. Мне нужно было бы покрасить (или поменять значок) предыдущих звезд. Если плавать каждый элемент вправо, я по сути получаю тот же эффект (html для звезд, таким образом, должен быть записан «назад»).

Я использую FontAwesome в этом примере и заменяю между юникодами fa -star-o и fa-star http://fortawesome.github.io/Font-Awesome/

CSS:

.fa {
    display: inline-block;
    font-family: FontAwesome;
    font-style: normal;
    font-weight: normal;
    line-height: 1;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* set all stars to 'empty star' */
.stars-container {
    display: inline-block;      
}   

/* set all stars to 'empty star' */
.stars-container .star {
    float: right;
    display: inline-block;
    padding: 2px;
    color: orange;
    cursor: pointer;

}

.stars-container .star:before {
    content: "\f006"; /* fontAwesome empty star code */
}

/* set hovered star to 'filled star' */
.star:hover:before{
    content: "\f005"; /* fontAwesome filled star code */
}

/* set all stars after hovered to'filled star' 
** it will appear that it selects all after due to positioning */
.star:hover ~ .star:before {
    content: "\f005"; /* fontAwesome filled star code */
}

HTML: (40)

JSFiddle: http://jsfiddle.net/andrewleyva/88j0105g/

2
ответ дан Andrew Leyva 22 August 2018 в 16:05
поделиться
  • 1
    float right и + или ~ выбирают меня как самую чистую работу. – Wylliam Judd 1 November 2017 в 22:12

Уровень 4 выбора вводит :has() (ранее индикатор объекта !), который позволит вам выбрать предыдущего брата с:

previous:has(+ next) {}

... но в время написания, это некоторое расстояние, выходящее за пределы кровопускания для поддержки браузера.

121
ответ дан BoltClock 22 August 2018 в 16:05
поделиться
  • 1
    Реальный ответ: селектора css разработаны, чтобы быть легкими (быстрыми) для реализации для браузера. Документ можно перемещать один раз , сопоставляя элементы по ходу, без необходимости возвращаться назад, чтобы настроить соответствие. – chowey 12 August 2013 в 04:55
  • 2
    «Кровотечение для поддержки браузера» может быть завышенным. Начиная с написания этого, даже последняя версия Chrome не может использовать псевдо-класс :has(). – Reed Martin 20 January 2017 в 08:59
  • 3
    Селектор :has() будет специально не использоваться в таблицах стилей, т. Е. Вы сможете использовать его в Javascript – James Tudsbury 13 June 2017 в 13:35
  • 4
    @chowey - ваш компьютер может обрабатывать безумные видеоигры с бесчисленными математическими вычислениями при высоком FPS, но браузер едва справляется с укладкой предыдущих элементов в CSS. какая ирония. – vsync 20 June 2017 в 10:09
  • 5
    @ReedMartin - Вот почему я сказал некоторое расстояние за пределы кровоточащего края – Quentin 20 June 2017 в 10:18
  • 6
    – Arch Linux Tux 15 February 2018 в 16:02

У меня был тот же вопрос, но потом у меня был момент «духа». Вместо записи

x ~ y

напишите

y ~ x

Очевидно, что это соответствует «x» вместо «y», но отвечает «есть ли совпадение?». вопрос и простой обход DOM могут привести вас к правильному элементу более эффективно, чем цикл в javascript.

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

65
ответ дан Bryan Larsen 22 August 2018 в 16:05
поделиться
  • 1
    Я считаю, что это работает, когда можно легко найти. Проблема в том, что y можно найти только по отношению к x, и, обратив его, вы не можете найти y, потому что вам нужно сначала найти x. Это, конечно, относится к вопросу о том, что y является предшественником родного брата, а не следующим, но может также применяться для того, чтобы y являлся следующим братом. – David 12 February 2013 в 21:14
  • 2
    Ты будешь суровым, суровым. (извините, не смог удержаться.) Дело в том, что иногда вам просто нужно знать, что «существует ли существует?». В других случаях вы можете использовать & quot;: before & quot; поставить что-то между этими двумя элементами. Наконец, если вам нужно перейти в jQuery, используйте find (& quot; y ~ x & quot;). Prev () проще, чем многие альтернативы. – Bryan Larsen 13 March 2013 в 11:04
  • 3
    Идея предыдущего селектора-сиблинга заключается в том, что он выберет предыдущий элемент. К сожалению, обращение вспять, как описано здесь, не обеспечивает эту функциональность. – Zenexer 31 July 2013 в 01:56
  • 4
    Спасибо @Zenexer за разъяснение, что этот ответ не дает реального решения первоначального вопроса, я начал чувствовать себя глупо, думая о том, как y ~ x может решить мою проблему – Jaime Hablutzel 23 April 2014 в 22:20
  • 5
    Я понимаю идею этого ответа, однако рассуждения, приведенные в ответе, не совсем понятны. Селектор y ~ x не отвечает «есть ли совпадение» & quot; вопрос, потому что два приведенных здесь селектора означают совершенно разные вещи. Нет никакого способа y ~ x, когда-либо создавшего соответствие, например, поддерева <root><x/><y/></root>. Если вопрос «существует ли y существует?» то селектор просто y. Если вопрос «существует ли y существует, если имеется один член x в любой произвольной позиции?» то вам понадобится оба селектора. (Хотя, может быть, я просто задираю в этот момент ...) – BoltClock♦ 27 October 2015 в 10:23

В зависимости от вашей конкретной цели существует способ достижения полезности родительского селектора без использования одного (даже если бы он существовал) ...

Скажем, у нас есть:

<div>
  <ul>
    <li><a>Pants</a></li>
    <li><a>Socks</a></li>
    <ul>
      <li><a>White socks</a></li>
      <li><a>Blue socks</a></li>
    </ul>
  </ul>
</div>

Что мы можем сделать, чтобы блок Socks (включая цвета носка) выделялся визуально с использованием интервала?

Что было бы неплохо, но не существует:

ul li ul:parent {
  margin-top: 15px;
  margin-bottom: 15px;
}

Что существует:

li > a {
  margin-top: 15px;
  display: block;
}
li > a:only-child {
  margin-top: 0px;
}

Это устанавливает, что все привязные ссылки имеют верхний край 15px и сбрасывают его обратно на 0 для тех, у которых нет элементов UL (или других тегов) внутри LI.

1
ответ дан falsarella 22 August 2018 в 16:05
поделиться

У меня была аналогичная проблема, и выяснилось, что вся проблема такого характера может быть решена следующим образом:

  1. дает всем вашим элементам стиль.
  2. дает выбранный вами item style.
  3. дает следующие элементы стиль с использованием + или ~.

, и таким образом вы сможете стилизовать свои текущие предыдущие элементы (все элементы переопределены текущими и следующими элементами) и ваши следующие элементы.

пример:

/* all items (will be styled as previous) */
li {
  color: blue;
}

/* the item i want to distinguish */
li.milk {
  color: red;
}

/* next items */
li ~ li  {
  color: green;
}


<ul>
  <li>Tea</li>
  <li class="milk">Milk</li>
  <li>Juice</li>
  <li>others</li>
</ul>

Надеюсь, что это кому-то поможет.

0
ответ дан Hejar 22 August 2018 в 16:05
поделиться

Если вы знаете точную позицию, будет работать исключение из всех следующих братьев :nth-child().

ul li:not(:nth-child(n+3))

Что бы выбрать все li s до третьего (например, 1-го и 2-го) , Но, по-моему, это выглядит уродливым и очень плотным.

Вы также можете выбрать n-й-правый справа налево:

ul li:nth-child(-n+2)

Что делает то же самое .

4
ответ дан kernel 22 August 2018 в 16:05
поделиться

Я нашел способ сфокусировать всех предыдущих братьев и сестер (напротив ~), которые могут работать в зависимости от того, что вам нужно.

Допустим, у вас есть список ссылок и при падении на одном, все предыдущие должны стать красными. Вы можете сделать это следующим образом:

/* default link color is blue */
.parent a {
  color: blue;
}

/* prev siblings should be red */
.parent:hover a {
  color: red;
}
.parent a:hover,
.parent a:hover ~ a {
  color: blue;
}
<div class="parent">
  <a href="#">link</a>
  <a href="#">link</a>
  <a href="#">link</a>
  <a href="#">link</a>
  <a href="#">link</a>
</div>

161
ответ дан mantish 22 August 2018 в 16:05
поделиться
  • 1
    Вы можете добавить объяснение того, как это работает. (кажется, что вы применяете стиль ко всем элементам и к следующим элементам, но это может быть описано явно) – A.L 24 April 2015 в 17:04
  • 2
    Вот сценарий для того, что я упомянул выше: jsfiddle.net/y9zeLr1n – Steven Vachon 19 May 2015 в 15:13
  • 3
    да, но один предыдущий нужен большую часть времени НЕ ВСЕ предыдущие! – azerafati 1 May 2016 в 15:15
  • 4
    Все ссылки становятся красными, если я нахожусь над пространством между ними, для меня. – Lynn 1 August 2016 в 08:19
  • 5
    @Lynn ответ включает только код, чтобы сделать предыдущие ссылки красными на зависании. Дополнительные стили зависят от вашего варианта использования. Для компонента рейтинга звезды (который, как я полагаю, является обычным делом), вам нужно будет избавиться от этого пространства, а также сделать красную зависающую ссылку. – mantish 4 August 2016 в 10:23

Рассмотрим свойство order схем flex и grid.

В приведенных ниже примерах я сосредоточусь на flexbox, но те же понятия применимы к Grid.


С помощью flexbox можно смоделировать предыдущий селектор сиблинга.

В частности, свойство flex order может перемещать элементы вокруг экрана.

Пример:

Вы хотите, чтобы элемент A загорелся, когда элемент B зависает.

<ul>
    <li>A</li>
    <li>B</li>
</ul>

ШАГИ

  1. Сделайте контейнер ul гибким.
    ul { display: flex; }
    

  1. Отменить порядок братьев и сестер в надписи.
    <ul>
       <li>B</li>
       <li>A</li>
    </ul>
    

  1. Используйте селектор для подключения к элементу A (~ или +).
    li:hover + li { background-color: red; }
    

  1. Используйте свойство flex order, чтобы восстановить порядок братьев и сестер на визуальном дисплее.
    li:last-child { order: -1; }
    

... и voilà! Предыдущий родитель (или, по крайней мере, имитируемый) родился [или g28]

Вот полный код:

ul {
    display: flex;
}

li:hover + li {
    background-color: red;
}

li:last-child {
    order: -1;
}

/* non-essential decorative styles */
li {
    height: 200px;
    width: 200px;
    background-color: aqua;
    margin: 5px;
    list-style-type: none;
    cursor: pointer;
}
<ul>
    <li>B</li>
    <li>A</li>
</ul>

Из спецификации flexbox:

5.4. Порядок отображения: свойство order

Элементы Flex по умолчанию отображаются и выкладываются в том же порядке, что и в исходном документе. Свойство order можно использовать для изменения этого заказа.

Свойство order управляет порядком, в котором элементы гибкости появляются в контейнере flex, назначая их порядковым группам. Он принимает одно значение <integer>, которое указывает, к какой порядковой группе принадлежит элемент flex.

Начальное значение order для всех элементов flex равно 0.

Также см. order в спецификации CSS Grid Layout spec .


Примеры «предыдущих селекторов севера», созданных с использованием свойства flex order.

.container { display: flex; }

.box5 { order: 1; }    
.box5:hover + .box4 { background-color: orangered; font-size: 1.5em; }

.box6 { order: -4; }
.box7 { order: -3; }
.box8 { order: -2; }
.box9 { order: -1; }
.box9:hover ~ :not(.box12):nth-child(-1n+5) { background-color: orangered;
                                              font-size: 1.5em; }
.box12 { order: 2; }
.box12:hover ~ :nth-last-child(-1n+2) { background-color: orangered;
                                        font-size: 1.5em; }
.box21 { order: 1; }
.box21:hover ~ .box { background-color: orangered; font-size: 1.5em; }

/* non-essential decorative styles */
.container {
    padding: 5px;
    background-color: #888;
}
.box {
    height: 50px;
    width: 75px;
    margin: 5px;
    background-color: lightgreen;
    display: flex;
    justify-content: center;
    align-items: center;
    text-align: center;
    cursor: pointer;
}
<p>
Using the flex <code>order</code> property to construct a previous sibling selector
</p>

<div class="container">
    <div class="box box1"><span>1</span></div>
    <div class="box box2"><span>2</span></div>
    <div class="box box3"><span>3</span></div>
    <div class="box box5"><span>HOVER ME</span></div>
    <div class="box box4"><span>4</span></div>
</div>

<br>

<div class="container">
    <div class="box box9"><span>HOVER ME</span></div>
    <div class="box box12"><span>HOVER ME</span></div>
    <div class="box box6"><span>6</span></div>
    <div class="box box7"><span>7</span></div>
    <div class="box box8"><span>8</span></div>
    <div class="box box10"><span>10</span></div>
    <div class="box box11"><span>11</span></div>
</div>

<br>

<div class="container">
    <div class="box box21"><span>HOVER ME</span></div>
    <div class="box box13"><span>13</span></div>
    <div class="box box14"><span>14</span></div>
    <div class="box box15"><span>15</span></div>
    <div class="box box16"><span>16</span></div>
    <div class="box box17"><span>17</span></div>
    <div class="box box18"><span>18</span></div>
    <div class="box box19"><span>19</span></div>
    <div class="box box20"><span>20</span></div>
</div>

jsFiddle


A Side Note & ndash; Две устаревшие убеждения о CSS

Flexbox разрушает давние убеждения в отношении CSS.

Одно из таких убеждений заключается в том, что предыдущий селектор сиблинга невозможен в CSS .

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

Как описано выше, это убеждение не совсем верно. Предыдущий сингл-селектор может быть смоделирован в CSS с использованием свойства flex order.

Миф z-index

Еще одно давнее убеждение что z-index работает только с расположенными элементами.

Фактически, самая последняя версия spec & ndash; Проект редактора W3C & ndash; все еще утверждает, что это правда:

9.9.1 Определение уровня стека: свойство z-index

z-index

  • Значение: auto | | inherit
  • Начальное: auto
  • Применяется к: позиционированным элементам
  • Inherited: no
  • Процент: N / A
  • Медиа: визуальный
  • Вычисленное значение: как указано

(выделено курсивом)

В действительности, однако, эта информация устарела и неточна.

Элементы, которые являются элементами гибких элементов или , могут создавать (f28) static.

4.3. Элемент Flex Item Z-Ordering

Элементы Flex представляют собой то же самое, что и встроенные блоки, за исключением того, что порядок ортогонального заказа используется вместо необработанного порядка документа и значения z-index, отличные от auto создать контекст стекирования, даже если position - static.

5.4. Z-axis Ordering: свойство z-index

Порядок рисования элементов сетки точно такой же, как и встроенные блоки, за исключением того, что порядок ортогонального заказа используется вместо необработанного порядка документа и z-index, отличные от auto, создают контекст стекирования, даже если position - static.

Ниже приведена демонстрация работы z-index над непозиционированными элементами гибкости: https://jsfiddle.net/m0wddwxs/

99
ответ дан Michael_B 22 August 2018 в 16:05
поделиться
  • 1
    Свойство order не является решением, поскольку оно предназначено только для изменения порядка visual , поэтому он not восстанавливает первоначальный семантический порядок, который вы вынуждены изменить в HTML для этого обходного пути для работы. – Marat Tanalin 20 March 2016 в 22:47
  • 2
    @Marat Tanalin: для 90% случаев использования, предполагая, что поддержка браузера не является проблемой, это будет работать нормально. Остальные 10% случаев использования - это 1) случаи, когда изменение визуального порядка не является решением, или 2) случаями, которые вообще не связаны с CSS. К счастью, для # 2, selectors-4 предоставляет: has (), и это просто разработчикам селекторных библиотек для его реализации. – BoltClock♦ 21 March 2016 в 05:52
  • 3
    Имейте в виду, что CSS2.2 ED, который вы цитируете, по существу, еще CSS2. И flexbox и grid layout не существуют в CSS2, так что, насколько это касается CSS2, эта информация, безусловно, сохраняется. По крайней мере, текст можно было бы обновить, указав, что z-index может применяться к другим типам элементов на будущих уровнях CSS, так же, как он говорит, что другие свойства могут устанавливать контекст стекирования, например непрозрачность. – BoltClock♦ 21 March 2016 в 06:05
  • 4
    В случае, если у кого-то возникли проблемы с пониманием, когда z-index будет работать, даже когда «omg» нет position указано! », Спецификация упоминает концепцию stacking context , которая хорошо объясняется в этой статье о MDN – Rogier Spieker 28 April 2016 в 17:45
  • 5
    @Michael_B, пожалуйста! Я имел дело с большим количеством сторонников, не подозревающих об этом. Еще одна вещь, которую я хотел бы упомянуть, faux previous sibling selector также прекрасно работает с float: right (или любыми другими средствами для отмены порядка, из которых flex/order имеет мало (наименьшее?)) побочные эффекты). Взбитые два скрипта: , демонстрирующие подход float: right и , демонстрирующий direction: rtl – Rogier Spieker 28 April 2016 в 17:57

Как уже говорилось много раз - с div ~ p выбраны все элементы <p>, которым предшествует элемент <div>.

Проверьте этот список все селектор CSS.

-1
ответ дан Nesha Zoric 22 August 2018 в 16:05
поделиться
  • 1
    Нет, вы попробовали? Он не выбирает предшествующие элементы, а следующие . – Soaku 21 April 2018 в 15:57

Два трюка . В основном, инвертирование HTML-кода ваших желаемых элементов в HTML и использование ~ Оператора следующего сиблинга :

float-right + инвертирует порядок HTML элементы

div{ /* Do with the parent whatever you know just to make the
  inner float-right elements appear where desired */
  display:inline-block;
}
span{
  float:right;  /* float-right the elements! */
}
span:hover ~ span{ /* On hover target it's "previous";) elements */
  background:red;
} 
<div>
  <!-- Reverse the order of inner elements -->
  <span>5</span>
  <span>4</span>
  <span>3</span>
  <span>2</span>
  <span>1</span>
</div>


Родитель с direction: rtl; + инвертирует порядок внутренних элементов

.inverse{
  direction: rtl;
  display: inline-block; /* inline-block to keep parent at the left of window */
}
span:hover ~ span{ /* On hover target it's "previous";) elements */
  background:gold;
}
Hover one span and see the previous elements being targeted!<br>

<div class="inverse">
  <!-- Reverse the order of inner elements -->
  <span>5</span>
  <span>4</span>
  <span>3</span>
  <span>2</span>
  <span>1</span>
</div>

20
ответ дан Roko C. Buljan 22 August 2018 в 16:05
поделиться

+ для следующего брата. Есть ли эквивалент для предыдущего брата?

Вы можете использовать два селектора ax : ! и ?

Там 2 следующие селекторные функции для сиблинга в обычном CSS:

  • + является непосредственным последующим селектором сиблинга
  • ~ является любым последующим селектором сиблинга

. В обычном CSS нет предыдущего селектора sibling.

Однако в ax CSS послепроцессорной библиотеки есть 2 предыдущие селекторные функции:

  • ? - это предыдущий селектор немедленного (напротив +)
  • ! является любым предыдущим селектором (см. ~)

Рабочий пример:

В следующем примере:

  • .any-subsequent:hover ~ div выбирает любой последующий div
  • .immediate-subsequent:hover + div выбирает немедленный последующий div
  • .any-previous:hover ! div выбирает любой предыдущий div
  • .immediate-previous:hover ? div выбирает непосредственный предыдущий div

div {
  display: inline-block;
  width: 60px;
  height: 100px;
  color: rgb(255, 255, 255);
  background-color: rgb(255, 0, 0);
  text-align: center;
  vertical-align: top;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.6s ease-out;
}

code {
  display: block;
  margin: 4px;
  font-size: 24px;
  line-height: 24px;
  background-color: rgba(0, 0, 0, 0.5);
}

div:nth-of-type(-n+4) {
  background-color: rgb(0, 0, 255);
}

div:nth-of-type(n+3):nth-of-type(-n+6) {
  opacity: 1;
}

.any-subsequent:hover ~ div,
.immediate-subsequent:hover + div,
.any-previous:hover ! div,
.immediate-previous:hover ? div {
  opacity: 1;
}
<h2>Hover over any of the blocks below</h2>

<div></div>
<div></div>

<div class="immediate-previous">Hover for <code>?</code> selector</div>
<div class="any-previous">Hover for <code>!</code> selector</div>
<div class="any-subsequent">Hover for <code>~</code> selector</div>
<div class="immediate-subsequent">Hover for <code>+</code> selector</div>

<div></div>
<div></div>

<script src="https://rouninmedia.github.io/axe/axe.js"></script>

14
ответ дан TylerH 22 August 2018 в 16:05
поделиться
  • 1
    Это дает мне синтаксическую ошибку, когда я пытаюсь реализовать ее по sass внутри проекта rails. – alex 5 September 2017 в 22:57
  • 2
    ax - постпроцессор CSS. Он не использует тот же синтаксис, что и предварительные процессоры CSS, такие как Sass, Less или Stylus. – Rounin 6 September 2017 в 15:11

Другое решение flexbox

Вы можете использовать инверсию порядка элементов в HTML. Затем, используя order, как в ответе Michael_B , вы можете использовать flex-direction: row-reverse; или flex-direction: column-reverse; в зависимости от вашего макета.

Рабочий пример:

.flex {
  display: flex;
  flex-direction: row-reverse;
   /* Align content at the "reversed" end i.e. beginning */
  justify-content: flex-end;
}

/* On hover target its "previous" elements */
.flex-item:hover ~ .flex-item {
  background-color: lime;
}

/* styles just for demo */
.flex-item {
  background-color: orange;
  color: white;
  padding: 20px;
  font-size: 3rem;
  border-radius: 50%;
}
<div class="flex">
  <div class="flex-item">5</div>
  <div class="flex-item">4</div>
  <div class="flex-item">3</div>
  <div class="flex-item">2</div>
  <div class="flex-item">1</div>
</div>

11
ответ дан Vadim Ovchinnikov 22 August 2018 в 16:05
поделиться