Kuidas vanilje JS-is karusell nullist üles ehitada.

Foto autor Xavi Cabrera saidil Unsplash

Uue tehnoloogia vabastamise tempo on uskumatu. Nii kiiresti, et on lihtne liikuda uusima ja suurima raamistiku või raamatukogu juurde, jätmata aega põhialuste tõeliseks mõistmiseks.

Olles juhtinud ja praegu juhtinud veebiarendusmeeskondi, on minu põhirõhk minu meeskonna isiklikul kasvamisel. Üks esimesi ülesandeid, mille panin lootustandvatele arendajatele, kes soovivad oma JS-i põhiteadmisi arendada, on karusseli ehitamine.

Karusselli väljakutse

Lühidalt on selge.

Ehitage brauseriga loetavasse koodi toimiv karussell. Ei mingeid raamatukogusid, raamistikke ega ehitustööriistu. Ainult HTML5, CSS3 ja JavaScript.
Boonuspunktid, kui see töötab puutetundlike ekraanidega seadmetes toimuvate puutetundlike sündmustega.

Selle ülesande seadmine mulle meeldib, kuna karusseli ehitamine nõuab arhitektuurset mõtlemist, andmete ja elementide haldamist, DOM-i manipuleerimist ja kasutaja suhtlemist. Selle ülesande täitmiseks ja sellest õppimiseks on nii palju võimalusi, et sama arendaja, tehes sama lühikest aega, mõne kuu vahega, annaks sama arendaja täiesti teistsuguste tulemuste.

Nüüd, rääkides piisavalt, hakkame seda välja mõtlema.

Enne mis tahes koodi kirjutamist peame otsustama, kuidas me soovime, et HTML, CSS ja JS töötaksid koos.

Kui me peaksime pilte JS-is massiivina edastama, kas peaksime ehitama semantilise HTML-i, et struktuur oleks olemas enne JS-i laadimist, kas toimub animatsioon, kui jah, siis kas seda juhib JS või CSS?

Selles näites kasutatakse struktureeritud HTML-i, CSS3-siirdeid ja JS-i juhitavat interaktiivsust.

HTML: struktuur

Me ehitame oma karusselli struktuuri. Selle kodeerimisel peame arvestama, et ühel lehel võib olla rohkem kui üks karussell, seega kasutame taaskasutatavuse huvides sihtimiseks ja kujundamiseks atribuuti class over id.

Siin on meie põhistruktuur:

  
    
    
    
    
    
      
    
    
  

Alustades karussellimähist, kasutame seda oma karusseli suuruse määramiseks ja peidame selle sisemusest kogu ülevoolu sisu.

karussell hoiab kõiki meie elemente, näiteks pilte ja navigeerimisnuppe.

karussell__photo rakendatakse meie siltide hõlpsaks kujundamiseks . Samuti on meile antud pilt, mida soovime algklassi kuvamiseks.

nupp karussell__ lipuga --next ja --prev, et saaksime anda igaühele neist oma klõpsuürituse. Minu klassi nimetamise tavadest huvitatud isikutele järgin BEM-i metoodikat.

HTML on tehtud. Järgmisena, CSS.

CSS: stiilid ja üleminekud

Olen suur pooldaja CSS-i kirjutamisel kõigepealt väiksematele ekraanidele - AKA Mobile First) ja seejärel meediumipäringute abil disaini laiendamiseks, nagu sisu nõuab.

Seda silmas pidades on see CSS karusseli ühe veeru vaade ja lühiduse huvides jätan müüja eesliited (nt veebikokkutulek) välja.

Teeme ära.

Sukeldumine .karussell-ümbrisega, siin pole midagi erilist, lihtsalt ülevool ja laius. Idee on selles, et laiust saab muuta vastavalt teie sisule ja kõik, mis selle sees on, sobib sobivaks.

.karussell-ümbris {
  ülevool: varjatud;
  laius: 90%;
}

Samuti tahame rakendada kasti suuruse omadusele äärisekasti, nii et polster ja ääris sisalduksid meie elementide kogulaiuses ja -kõrguses.

.karussell-ümbris * {
  kasti suurus: äärise kast;
}

Kasutame teisendamise atribuuti oma karussellide üksuste teisaldamiseks, nii et kui teisendada stiili 3D-vormingus, veenduge, et meie pesastatud elemendid oleksid 3D-ruumis korralikult esitatud.

.karussell {
  teisendusstiil: säilita-3d;
}

Vaikimisi peidame kõik üksused, kuni skript käivitab karusseli. Lihtsaks positsioneerimiseks paigaldatakse elemendid absoluutselt ja nende reageeriv laius on 100%. Meie sisu dikteerib karusselli kõrguse ja ülemineku omadus on meie võlu karusseli animeerimiseks.

.karussell__photo {
  läbipaistmatus: 0;
  positsioon: absoluutne;
  ülemine: 0;
  laius: 100%;
  veeris: auto;
  polster: 1rem 4rem;
  z-indeks: 100;
  üleminek: teisendus, 5s, läbipaistmatus, 5s, z-indeks, 5s;
}

Mõnikord võib skriptide laadimine võtta natuke aega, nii et näitame algse, muutke see suhteliseks, nii et põhikonteiner laieneb, ja viige see z-indeksi abil ette. Need stiilid kehtivad ka meie aktiivse üksuse kohta, kui karusselli juhitakse.

.karussell__photo.initsiaal,
.karussell__photo.aktiivne {
  läbipaistmatus: 1;
  positsioon: sugulane;
  z-indeks: 900;
}

Karussellidel liikudes soovime, et JS seadistaks dünaamiliselt klassid eelneva ja järgmise üksuse positsioneerimiseks, tõlkides need teisendusomadusega. Kasutame neid uuesti z-indeksi abil, et panna need muudele üksustele peale, kuid aktiivse üksuse alla.

.karussell__photo.prev,
.karussell__photo.next {
  z-indeks: 800;
}
.karussell__photo.prev {
  teisendus: translateX (-100%); / * Liiguta üksus 'eelmine' vasakule * /
}
.karussell__photo.next {
  teisendus: translateX (100%); / * Liiguta üksus "järgmine" paremale * /
}

Karusseli CSS on tehtud, üle jääb vaid navigeerimisnupud, mis asuvad karusellil mõlemal küljel, nooled sees. Uue HTML-i lisamise asemel lisame nooled, kasutades pseudo-elementi ::.

.karussell__ nupp - eelmine,
.karussell__nupp - järgmine {
  positsioon: absoluutne;
  ülaosa: 50%;
  laius: 3rem;
  kõrgus: 3rem;
  taustavärv: #FFF;
  teisendus: tõlgitud Y (-50%);
  piiri raadius: 50%;
  kursor: osuti;
  z-indeks: 1001; / * Istu kõige peale * /
  ääris: 1 px tahke must;
}
nupp .karussell__ - eelmine {
  vasakul: 0;
}
.karussell__nupp - järgmine {
  paremal: 0;
}
nupp .karussell__ - eelmine :: pärast,
.karussell__nupp - järgmine :: pärast {
  sisu: " ";
  positsioon: absoluutne;
  laius: 10 px;
  kõrgus: 10 px;
  ülaosa: 50%;
  vasakult: 54%;
  parem-äärne: 2xx must must;
  serv alt: 2xx must must;
  teisendada: tõlkida (-50%, -50%) pöörata (135 kraadi);
}
.karussell__nupp - järgmine :: pärast {
  vasakult: 47%;
  teisendada: tõlkida (-50%, -50%) pöörata (-45 °);
}
Kui olete mööda käinud, ei tohiks teie karussell selle moodi liiga erinev olla.

JavaScript: see toimib!

Kui olete selle kaugele jõudnud, siis olete sellega hästi hakkama saanud ja tänan teid. Päriselt. Tänan sind väga. Sa oled parim. ❤

Struktuur on meil olemas ja see näeb välja, kuidas me tahame, kui üleminekud hakkavad minema. Nüüd peame vaid tegema selle toimima.

Enne kodeerimise alustamist on aeg see välja mõelda.

  1. Peame algatama karusseli, leides algse üksuse ja rakendades selle kõrval asuvatele üksustele klassi .prev ja .next.
  2. Siis tahame lisada oma navigeerimisnuppudele klõpsuüritused.
  3. Klõpsamissündmused pole midagi ilma funktsioonita, nii et iga suuna käsitlemiseks kirjutame kaks funktsiooni.
  4. Kui oleme teada, millises suunas kasutaja üritab liikuda, kirjutame veel ühe funktsiooni, et karusell selles suunas liikuda.
  5. Vältimaks inimeste nuppudel klõpsamist, keelame karusseli animeerimise ajal interaktiivsuse ja lubame selle uuesti valmis teha.
  6. Lõpuks tahame käsitleda kõike seda funktsioonis, mis teisaldab üksused meie karussellis, mõeldes välja, milliseid üksusi värskendada, ja värskendab neid uute klassidega, et käivitada CSS3 üleminekud.

Konfliktide vältimiseks ja selle võimalikult kaasaskantavaks muutmiseks on meie huvides kaitsta oma koodi globaalsest ulatusest, seega pakime selle kokku IIFE-s.

! (funktsioon (d) {
  // Kõik kood sisestatakse siia. Oleme dokumendi "d" ümber nimetanud.
} (dokument));

Alustuseks deklareerime oma muutujad. Valime muutuja, et sihtida oma põhiklassi .carousel__photo, siis salvestame kõik selle klassi objektid üksustesse, kui nad on salvestatud, saame neid loendada ja selle arvu totalItemsisse salvestada, siis seame slaidi meie praeguseks libistage (indeksil 0) ja lõpetamiseks määrame liikumise tõeseks, mida kasutame nuppude klõpsude lubamiseks ja keelamiseks.

var itemClassName = "karussell__photo";
    items = d.getElementsByClassName (itemClassName),
    totalItems = üksused.pikkus,
    slaid = 0,
    liikuv = tõsi;

Need järgmised kaks funktsiooni määravad algklassid ja lisavad meie sündmuste kuulajad navigeerimisnuppudele.

// Seadke klassid
funktsioon setInitialClasses () {
  // Sihib eelmist, praegust ja järgmist üksust
  // See eeldab, et on vähemalt kolm eset.
  üksused [totalItems - 1] .classList.add ("eelmine");
  üksused [0] .classList.add ("aktiivne");
  üksused [1] .classList.add ("järgmine");
}
// Määra sündmuste kuulajad
funktsioon setEventListeners () {
  var next = d.getElementsByClassName ('karussell__-nupp - järgmine') [0],
      prev = d.getElementsByClassName ('karussell__button - eelmine') [0];
  next.addEventListener ('klõpsa', moveNext);
  prev.addEventListener ('klõps', movePrev);
}

Oleme siduv moveNext ja movePrev klikisündmusele, seega loome need funktsioonid parem järgmisena. Need funktsioonid kontrollivad slaidi numbrit sõltumata sellest, kas seda suurendatakse, vähendatakse, või seadke see esimeseks või viimaseks üksuseks.

// Järgmine navigatsiooni käitleja
funktsioon moveNext () {
  // Kontrollige, kas kolite
  if (! kolimine) {
    // Kui see on viimane slaid, lähtestage väärtus 0, muul juhul +1
    if (libistage === (kokku üksused - 1)) {
      slaid = 0;
    } veel {
      slaid ++;
    }
    // Liigutage karussell värskendatud slaidile
    moveCarouselTo (slaid);
  }
}
// Eelmine navigeerimiskäsutaja
funktsioon movePrev () {
  // Kontrollige, kas kolite
  if (! kolimine) {
    // Kui see on esimene slaid, seadke see viimaseks slaidiks, muidu -1
    if (libista === 0) {
      slaid = (kokku üksused - 1);
    } veel {
      libisema--;
    }
          
    // Liigutage karussell värskendatud slaidile
    moveCarouselTo (slaid);
  }
}

Vinge. Nii et meil on võimalik koodi käivitada, kirjutame liikuva muutuja käitlemiseks väikese loogika, mis seab selle käivitamisel tõeseks ja pärast ülemineku lõppemist tagasi valeks.

funktsioon invalidInteraction () {
  // Seadke “liikumine” tõeseks sama aja jooksul kui meie üleminek.
  // (0,5 s = 500 ms)
  
  liikuv = tõsi;
  // setTimeout täidab oma funktsiooni üks kord pärast antud aega
  setTimeout (funktsioon () {
    liikuv = vale
  }, 500);
}

Põhifunktsioon, mis haldab kogu karusselli, asub teisaldamispaigas (slaid), mis võtab argumendiks slaidi numbri. See on meie suurim funktsioon, nii et ma olen koodi kommenteerinud.

funktsioon moveCarouselTo (slaid) {
  // Kontrollige, kas karussell liigub, kui mitte, siis lubage interaktsiooni
  if (! kolimine) {
    // ajutiselt keelata interaktiivsus
    invalidInteraction ();
    // Uuendage "vanad" külgnevad slaidid "uutega"
    var newPrevable = slaid - 1,
        newNext = slaid + 1,
        oldPrevable = slaid - 2,
        oldNext = slaid + 2;
    // Kontrollige, kas karussellil on rohkem kui kolm eset
    if ((kokkuüksused - 1)> 3) {
      // Kontrollib ja värskendab, kui uued slaidid on piirest väljas
      if (newEelmine <= 0) {
        oldPrevable = (kokkuüksused - 1);
      } else if (newNext> = (totalItems - 1)) {
        vana järgmine = 0;
      }
      // Kontrollib ja värskendab, kui slaid on alguses / lõpus
      if (libista === 0) {
        newPrevable = (kokkuüksused - 1);
        oldPrevable = (kokku üksused - 2);
        oldNext = (slaid + 1);
      } else if (libistage === (kokku üksused -1)) {
        newPrevable = (slaid - 1);
        newNext = 0;
        vanaJärgmine = 1;
      }
      // Nüüd oleme välja töötanud, kus oleme ja kuhu läheme,
      // klasside lisamisel / eemaldamisel käivitame üleminekud.
      // Lähtesta vanad järgmised / eelmised elemendid vaikeklassidesse
      üksused [oldPrevable] .className = itemClassName;
      üksused [oldNext] .className = itemClassName;
      // Lisage uusi klasse
      üksused [newPrevable] .className = itemClassName + "eelmine";
      üksused [slaid] .className = itemClassName + "aktiivne";
      üksused [newNext] .className = itemClassName + "järgmine";
    }
  }
}

Oleme peaaegu kohal! Seal on üks viimane funktsioon, mida peame tegema, ja see, millele me helistame, et kõik toimiks.

funktsioon initCarousel () {
  setInitialClasses ();
  setEventListeners ();
  // Seadke liikumine valele, nii et karussell muutuks interaktiivseks
  liikuv = vale;
}

Lõpuks helistage initCarousel (), lisades selle allosas:

// pane vihma
initCarousel ();

Kui olete mööda käinud, peaksite otsima - ja suhtlema - midagi sellist:

Loodan, et teile meeldis minu debüütartikkel. Kui olete leidnud, et see on kasulik, siis palun jagage seda ning kui soovite end pidevalt kursis hoida, saate mind Instagramis jälgida.