Bagaimana saya melakukan slider yang benar-benar adaptif (carousel)

Selamat siang, para pembaca dan penulis terkasih!


Hari ini saya akan memberi tahu Anda bagaimana proyek menghadapi saya dengan tugas membuat slider adaptif dan apa yang terjadi


Tentang artikel itu dan untuk siapa artikel itu


Saya menulis artikel ini bukan hanya karena saya ingin mendapatkan respons komunitas untuk menyelesaikan masalah ini, tetapi juga karena menyelesaikan pertanyaan-pertanyaan artikel tampaknya mendasar bagi saya untuk memahami kemampuan beradaptasi slider di web. Jika seseorang telah menulis komponen seperti itu, harap balas dan bagikan pengalaman serupa


Sedikit tentang apa yang terjadi dan alat apa yang digunakan


Dalam aplikasi Bereaksi, Anda perlu membuat korsel (selanjutnya saya akan menggunakan nama ini), elemen-elemen yang terlihat harmonis di layar ukuran berapa pun. Ada beberapa batasan:


  1. Lebar maksimum elemen adalah 150 px
  2. Alat yang Digunakan - Bereaksi Owl Carousel
  3. Ukuran maksimal wadah untuk korsel adalah 1190 px
  4. Ada juga indikator properti padding untuk layar yang berbeda (mempengaruhi lebar bagian wadah yang terlihat) dan margin (antara elemen setidaknya 5 piksel)
  5. Korsel harus berputar
    Dan kondisi lain yang tidak mempengaruhi subjek artikel

Digresi pada mekanisme korsel


Banyak korsel (Bereaksi Owl Korsel bukan pengecualian) menggunakan kelas aktif khusus untuk menampilkannya, yang menggambarkan elemen-elemen yang saat ini ditampilkan di layar.


Untuk menampilkan loop tak terbatas pada layar, elemen pertama dan terakhir diduplikasi (mekanisme dan masalah dubbing ini adalah topik untuk artikel terpisah).


Properti dijelaskan oleh objek khusus, kami akan tertarik pada objek responsif, yang bertanggung jawab untuk menetapkan kembali properti.


Data yang tersisa pada mekanisme kerja akan jelas dalam perjalanan menggambarkan solusi.


Masalah pertama


Pada awalnya semuanya berjalan lancar - elemen-elemennya sendiri ditulis dan bergaya, sifat dasar seluruh korsel dijabarkan. Masalah dimulai ketika menyetel properti {loop: true}


Korsel tidak bisa diputar dengan benar


Ketika menggulir ke bagian akhir daftar, ruang kosong tetap ada di korsel dan untuk beberapa saat menggulirnya.


Alasannya adalah lebar maksimum elemen, tidak konsisten dengan jumlah mereka. Contoh nyata adalah lebar wadah 1190 px, dengan jumlah elemen diatur ke 3.


Dengan kata lain, korsel mengharapkan 3 elemen untuk meregang ke 1190px, dan mereka tidak dapat menjadi lebih besar dari 150px.


Meningkatkan jumlah item


Masalahnya mengambil sudut yang berbeda: jika ada terlalu banyak elemen per kontainer, lebarnya menjadi terlalu kecil (dan ada konten di dalamnya!) Jika saya mengatur properti min-width, maka pada beberapa ukuran layar elemen merangkak satu sama lain, mengabaikan margin, yang melanggar kondisi .


Kami merangkum kondisi kemampuan beradaptasi


  1. Jumlah elemen pada layar harus kurang dari rasio ukuran layar
    lebar minimum elemen - jika tidak, bahkan elemen dengan lebar minimum tidak akan pas di layar.
  2. Rasio ukuran layar dengan jumlah elemen yang diperkirakan tidak boleh melebihi panjang estimasi maksimum, jika tidak ada masalah dengan perulangan.
  3. Kondisi yang dijelaskan di atas harus dipenuhi untuk ukuran layar apa saja (dari 330px hingga 1190px).

Kami memecahkan masalah sebagai programmer


Jika Anda mendekati masalah secara berurutan, jelas bahwa Anda harus menyerahkan sesuatu, dalam kasus saya itu adalah lebar minimum elemen.


Apa yang harus menjadi lebar minimum elemen sehingga untuk semua layar kontainer kondisi adaptasi terpenuhi?


//       const getBackTrace = (minScreen = 300, maxElementWidth = 150) => { let backTrace = {} for (let minElementWidth = maxElementWidth; minElementWidth > 0; minElementWidth--){ //            //     backTrace for(let screen = minScreen; screen <= 1100; screen++){ let elementCount = screen / minElementWidth | 0 if((screen / elementCount) > maxElementWidth){ backTrace[minElementWidth] = screen break } } } for(let key in backTrace){ //        ,      if (backTrace[key - 1] == undefined){ backTrace.result = key - 1 return backTrace } } } // getBackTrace(300, 150).result = 100 

Hasil dalam 100px tidak sesuai untuk saya, karena itu tidak memungkinkan saya untuk mencocokkan semua konten dalam elemen. Karena itu, kami melanjutkan pencarian sampai kami menemukan nilai yang tepat dan mencari apa lagi yang harus dikorbankan.


Ingat subtitlenya? Untuk mencari, tulis fungsi


 const getMinScreen = (minWidth = 300, maxWidth = 767, maxElementWidth = 150) => { let research = [] //  ,          // getBackTrace,       for(let min = minWidth; min < maxWidth; min++){ let { result } = getBackTrace(min, maxElementWidth) research.push({result, min}) } //          "  "  return research .reduce((acc, curr, idx, arr) => { let obj = {} let {min, result} = curr obj[min] = result if(idx == 0) return obj if(arr[idx-1].result == result){ return {...acc} } else { return {...acc, ...obj} } }, {}) } /* Returned object {300: 100, 303: 101, 306: 102, 309: 103, 312: 104, 315: 105, 318: 106, 321: 107, 324: 108, 327: 109, 330: 110, 333: 111, 336: 112, 452: 113, 456: 114, 460: 115, 464: 116, 468: 117, 472: 118, 476: 119, 480: 120}   480    */ 

Mempertimbangkan objek yang diperoleh, Anda dapat melihat lompatan besar dalam transisi dari 336px ke 452px.
Saya membuat keputusan dengan tekad kuat untuk membatasi kemampuan beradaptasi hingga 36px.


Kami menggambarkan objek adaptif


Tampaknya masalah telah dipecahkan, tetapi solusi seperti itu hanya membuktikan bahwa kepatuhan dengan kondisi dimungkinkan untuk layar dari 336px, tetapi tidak menggambarkan metode. Tetapi ada kondisi berbeda yang membatasi saya dalam produksi objek dengan sifat kemampuan beradaptasi
Setelah menerima sendiri bahwa lebar minimum elemen tanpa kerugian bisa 107 px, dengan memvariasikan nilai margin, saya sampai pada indikator berikut:


Layarmarginlebar minimum
336+5107
468+10107
763+15112

Satu-satunya yang tersisa adalah mengumpulkan data yang diterima dalam tumpukan dan mengimplementasikan objek adaptif:


 getResponsiveOwlItems = () => { let responsive = {}; responsive[0] = {items: 2, nav: false} // 112 = 107 (minimal div) + 5 (margins) let itemMinWidthReference = 112; const getOneWidth = deviceWidth => deviceWidth / itemMinWidthReference | 0 // 1190 - container width for(let i = itemMinWidthReference * 3 + 20; i <= 1190; i += itemMinWidthReference){ // .container padding > 768 90px + padding 90(.container) // .container padding < 768 40px + padding -40(.container) // +20px stagePadding let padding = i > 767 ? 200 : 20 if(i > (468 + padding)) { itemMinWidthReference = 117 } if(i > (767 + padding)) { itemMinWidthReference = 127 } let items = getOneWidth(i - padding) let nav = i > 700 ? true : false let margin = 5; if (i > 468){ margin = 10 } if (i > 767){ margin = 15 } responsive[i.toString()] = {items, nav, margin} //      itemMinWidthReference i = i - (i % itemMinWidthReference) + 1 } return responsive; } 

Pada hari publikasi, semuanya terlihat logis, dan saya tidak dapat mereproduksi kesalahan dalam korsel - semuanya mungkin berfungsi sebagaimana dimaksud.


Terima kasih atas perhatian Anda, menunggu komentar dan komentar Anda!

Source: https://habr.com/ru/post/id461525/


All Articles