For Loop неправильно применяет nth-child

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

@for $i from 1 through 100 {
  .animateMe:nth-child(#{$i}) {
    animation-delay: .5s * $i;
  }
}

Используя Angular, я применяю класс animateMe к div только тогда, когда выполняются условия с ngClass.

<div id="neededfoodnames" *ngFor="let list of lists; let i = index" [ngClass]="{'animateMe':lists[i-1]?.category != list.category && animate == true}">
.....
</div>

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

animate: boolean = true;

Это приводит к 4 div, которые имеют класс animateMe. Однако задержка анимации не применяется правильно, так как первый и второй div имеют правильные задержки 0,5 с и 1 с соответственно, а третий div имеет неправильную задержку 3 с.

Третий div получает класс animateMe:nth-child(6), но он должен быть animateMe:nth-child(3).

Как я могу это исправить? Я создал StackBlitz для этой проблемы.


person cfoster5    schedule 01.08.2018    source источник
comment
Кажется, что весь CSS в порядке (так как в цикле sass все ваши классы создаются правильно, поэтому: nth-child работает как положено). Вы имеете в виду, что #neededfoodnames:nth-child(4) не содержит контента? Или вы пытаетесь перезаписать свой css с помощью ng-animate   -  person stwilz    schedule 01.08.2018
comment
также PS у вас есть несколько экземпляров #neededfoodnames там :)   -  person stwilz    schedule 01.08.2018
comment
@stwilz Я удалил #neededfoodnames. Класс animateMe должен применяться только к 4 div, и поэтому animateMe:nth-child(6) не должен существовать, но он существует.   -  person cfoster5    schedule 01.08.2018
comment
lists[i-1]?.category здесь опечатка. точка после вопросительного знака в вашем тернарном операторе.   -  person DragonKnight    schedule 01.08.2018


Ответы (1)


В вашем массиве lists есть объекты, которые не считаются элементом animateMe. Только несколько элементов имеют класс animateMe. Смотрите этот снимок экрана:

введите здесь описание изображения

Этот снимок экрана объясняет, почему селектор nth-child не работает должным образом. Я вижу два решения для вас.

Решение 1

Лучшее решение — очистить эти элементы. В идеале у вас должно быть только animateMe элементов в этом конкретном разделе, например:

<div class="animateMe">...</div>
<div class="animateMe">...</div>
<div class="animateMe">...</div>
<div class="animateMe">...</div>

Вы должны найти способ отобразить тот же пользовательский интерфейс, но с меньшим количеством div элементов (например, используя больше стилей или просто перемещая элементы под animateMe div). Если это невозможно по какой-либо причине, вы можете рассмотреть решение № 2.

Решение 2

Альтернативное (и не очень чистое) решение для вас — предварительно обработать этот массив и сохранить атрибут order, который может использоваться циклом. Например:

lists = [{}, {order:1}, {}, {}, {order:2}, {}, {order:3}, {}, {}];

Затем вы можете просмотреть массив и добавить атрибут data-order, который мы можем сопоставить с CSS:

<div *ngFor="let list of lists; let i = index" [ngClass]="{'animateMe': list.order && animate}" [attr.data-order]="animate ? list.order : null">
    ...
</div>

Если свойство order не определено в вашем объекте, атрибут data-order не будет напечатан. Вот пример вывода:

<div>...</div>
<div class="animateMe" data-order="1">...</div>
<div>...</div>
<div>...</div>
<div class="animateMe" data-order="2">...</div>
<div>...</div>
<div class="animateMe" data-order="3">...</div>
<div>...</div>
<div>...</div>

Последний шаг — изменить код SaSS, чтобы он соответствовал этим элементам:

@for $i from 1 through 100 {
    div[data-order="#{$i}"].animateMe {
        animation-delay: .5s * $i;
    }
}
person HugoTeixeira    schedule 01.08.2018
comment
Плохая практика нацеливать элементы в CSS по их типу тега элемента, вы можете удалить div из приведенного выше Sass, и он все равно будет работать должным образом. - person ESR; 01.08.2018
comment
@EdmundReed Не могли бы вы опубликовать ссылку на ссылку, которая подтверждает, что это плохая практика? Учитывая, что браузеры обычно индексируют элементы по имени узла, div должен сделать селектор более эффективным, и это, по определению, является хорошей практикой. - person HugoTeixeira; 01.08.2018
comment
Возможно, это микроскопически лучше для производительности, но для ремонтопригодности и масштабируемости это плохая практика. Эта статья выглядит так, будто объясняет, почему frontstuff.io/you-need -to-stop-target-tags-in-css. При таких вещах удобство сопровождения и масштабируемость, как правило, предпочтительнее незначительного прироста производительности. - person ESR; 02.08.2018