For Loop tidak menerapkan anak ke-n dengan benar

Menggunakan Sass, saya mengulang item dengan kelas animateMe dan menerapkan penundaan animasi menggunakan indeks sebagai pengganda.

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

Menggunakan Angular, saya menerapkan kelas animateMe pada div hanya ketika kondisi ngClass terpenuhi.

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

Ini seharusnya hanya menerapkan kelas jika kategori item berbeda dari kategori item terakhir dan animate disetel ke true, dan memang demikian.

animate: boolean = true;

Ini menghasilkan 4 div yang memiliki kelas animateMe. Namun, penundaan animasi tidak diterapkan dengan benar karena div pertama dan kedua memiliki penundaan yang benar masing-masing sebesar 0,5 detik dan 1 detik, sedangkan div ketiga memiliki penundaan yang salah sebesar 3 detik.

Div ketiga mendapatkan kelas animateMe:nth-child(6) tetapi seharusnya animateMe:nth-child(3).

Bagaimana cara memperbaikinya? Saya telah membuat StackBlitz untuk masalah ini.


person cfoster5    schedule 01.08.2018    source sumber
comment
Semua CSS tampaknya baik-baik saja (seperti dalam loop sass membuat semua kelas Anda dengan benar sehingga :nth-child berfungsi seperti yang diharapkan). Apakah Anda mengacu pada bagaimana #neededfoodnames:nth-child(4) tidak memiliki konten? Atau Anda mencoba menimpa css Anda dengan ng-animate   -  person stwilz    schedule 01.08.2018
comment
juga PS Anda memiliki banyak contoh #neededfoodnames di sana :)   -  person stwilz    schedule 01.08.2018
comment
@stwilz Saya telah menghapus #neededfoodnames. Kelas animateMe seharusnya hanya diterapkan pada 4 div, dan oleh karena itu animateMe:nth-child(6) seharusnya tidak ada, tetapi memang ada.   -  person cfoster5    schedule 01.08.2018
comment
lists[i-1]?.category saya melihat ada kesalahan ketik di sini. titik setelah tanda tanya di operator ternary Anda.   -  person DragonKnight    schedule 01.08.2018


Jawaban (1)


Array lists Anda memiliki objek yang tidak dianggap sebagai elemen animateMe. Hanya beberapa elemen yang memiliki kelas animateMe. Lihat tangkapan layar ini:

masukkan deskripsi gambar di sini

Tangkapan layar ini menjelaskan mengapa pemilih nth-child tidak berfungsi seperti yang diharapkan. Saya melihat dua solusi untuk Anda.

Solusi 1

Solusi terbaik adalah dengan membersihkan elemen-elemen tersebut. Idealnya Anda hanya memiliki animateMe elemen di bagian spesifik tersebut, seperti ini:

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

Anda harus menemukan cara untuk menampilkan UI yang sama, tetapi dengan lebih sedikit elemen div (misalnya, menggunakan lebih banyak gaya atau cukup memindahkan elemen di bawah div animateMe). Jika hal ini tidak memungkinkan karena alasan tertentu, Anda dapat mempertimbangkan solusi #2.

Solusi 2

Solusi alternatif (dan tidak terlalu bersih) untuk Anda adalah dengan memproses terlebih dahulu array tersebut dan menyimpan atribut order yang dapat digunakan oleh loop. Misalnya:

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

Anda kemudian dapat mengulang array dan menambahkan atribut data-order yang dapat kita cocokkan dengan CSS:

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

Jika properti order tidak ditentukan dalam objek Anda, atribut data-order tidak akan dicetak. Berikut ini contoh keluarannya:

<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>

Langkah terakhir adalah mengubah kode SaSS Anda agar sesuai dengan elemen tersebut:

@for $i from 1 through 100 {
    div[data-order="#{$i}"].animateMe {
        animation-delay: .5s * $i;
    }
}
person HugoTeixeira    schedule 01.08.2018
comment
Merupakan praktik buruk untuk menargetkan elemen dalam CSS berdasarkan jenis tag elemennya, Anda dapat menghapus div dari Sass di atas dan itu akan tetap berfungsi seperti yang diharapkan. - person ESR; 01.08.2018
comment
@EdmundReed Bisakah Anda memposting tautan ke referensi yang mengonfirmasi bahwa ini adalah praktik buruk? Mengingat browser biasanya mengindeks elemen berdasarkan nodeName, div harus membuat pemilih lebih efisien dan, menurut definisi, merupakan praktik yang baik. - person HugoTeixeira; 01.08.2018
comment
Mungkin secara mikroskopis lebih baik dalam hal kinerja, tetapi dalam hal pemeliharaan dan skalabilitas, ini adalah praktik yang buruk. Artikel ini sepertinya menjelaskan alasannya frontstuff.io/you-need -untuk-menghentikan-penargetan-tag-di-css. Dengan hal-hal seperti ini, pemeliharaan dan skalabilitas cenderung lebih diutamakan daripada peningkatan kinerja yang sangat kecil. - person ESR; 02.08.2018