Så här gör du flera förhandsgranska miniatyrer med JavaScript Mouse Events

I den här handledningen har vi roligt med JavaScript-mushändelser genom att bygga upp något användbart och intressant: miniatyrer som, när de svänger över, visar ett urval olika e-böcker.

Här är den demo som vi ska bygga (flytta musen runt varje miniatyrbild):

Varje miniatyrbild visar motsvarande böcker dolda under, beroende på markörposition. Det är ett idealiskt sätt att ge en förhandsgranskning av vad som är tillgängligt (i detta fall i Envato Tuts + ebook-biblioteket).

När vi bygger detta använder vi CSS Grid Layout och JavaScript mouse händelse, bland annat.

1. HTML Markup

Markeringen vi ska använda är ganska enkel; en vanlig oorderad lista med några lika stora bilder i var och en av listobjekten (kort). 

2. CSS

När det gäller CSS-stilar är det två saker som är viktiga:

  • Vi definierar den oordnade listan som en nätbehållare och ger listobjekten bredd: 25%.  Istället för CSS-nätet kan du använda flexbox eller din föredragna layoutmetod.
  • Vi döljer visuellt och placerar absolut alla bilder inuti listobjekten, förutom den första.

CSS-reglerna som vi tillämpar på vår demo visas nedan:

.kort display: rutnät; gallergap: 20px; rutmall-kolumner: upprepa (4, 1fr);  .card position: relative; boxskugga: 0 3px 6px rgba (0, 0, 0, 0,5);  .card: svävar markör: pekare;  .card img: not (: first-of-type) position: absolute; topp: 0; höger: 0; botten: 0; vänster: 0; opacitet: 0;  .card img.is-visible opacity: 1; 

Med ett par andra återställda stilar (borttagning av kulorna från den oordnade listan, vilket ger kroppen en bakgrundsfärg etc.) hamnar vi med det här:

3. JavaScript

Låt oss lägga till följande två rader så att när alla sidtillgångar är klara, i det funktionen exekveras. Vi utlöser det också varje gång webbläsarfönstret ändras.

window.addEventListener ("load", init); window.addEventListener ("resize", init);

Inne i den här funktionen händer ett antal saker; Först slung vi igenom korten.

funktion init () const cards = document.querySelectorAll (". card"); cards.forEach (el => // actions here); 

Loop barnens bilder

För varje kort hämtar vi antalet barnbilder utan att ta hänsyn till den första bilden. 

Notera: första bilden är synlig som standard och inte absolut positionerad. 

const numOfChildImages = el.querySelectorAll ("img: not (: first-of-type)"). längd;

Om det finns minst en barnbild, gör vi följande saker:

  • Beräkna kortets bredd (bredden på den första bilden) och ...
  • ... dela kortet i lika delar genom att dela dess bredd med antalet barnbilder.
om (numOfChildImages> 0) const width = el.getBoundingClientRect (); const delar = bredd / numOfChildImages; 

För att bättre förstå detta, låt oss anta att vårt första kort är 235 px bredt. Detta kort innehåller fyra bilder (kom ihåg att vi ignorerar den första bilden), så divisionen 235px / 4 ger oss 58.75px. Så vad är rollen för detta nummer? Tja, det skapar våra intervall, så vid korthuvudet spårar vi muspekaren X, kontrollerar dess intervall och visar slutligen den lämpliga bilden.

För vårt enkla exempel är här de genererade områdena:

Mus X Position
Bild att visa
0 1:a
58.75px 2:e
117.5px 3:e
176.25px 4:e

Observera att kolumnen "Bild att visa" visar bilden som ska visas från poolen på bilderna i fyra barn (vi återigen utesluter den första synliga bilden).

Nu när vi känner till kraven, låt oss översätta dem till kod. Fortfarande inne i slingan lyssnar vi på mouse händelse.

// sväva kort el.addEventListener ("mousemove", e => // gör saker här);

När det här händelsen brinner, utför vi följande åtgärder:

  1. Få X-koordinaten för muspekaren i förhållande till "svängt" -kortet och inte i förhållande till webbläsarfönstret.
  2. Ta bort är synlig klass från alla kortbilder.
  3. Visa lämplig bild beroende på muspositionen (se föregående tabell för ett exempel). 

En del av koden som implementerar ovanstående beteende är följande:

el.addEventListener ("mousemove", e => // 1 const xPos = e.pageX - el.offsetLeft; // 2 removeIsVisibleClass (); // 3 switch (numOfChildImages) fall 1: om (xPos> 0 && XPOS <= parts)  addClass(el, "img:nth-child(2)");  break; case 2: if (xPos > 0 && xPos <= parts)  addClass(el, "img:nth-child(2)");  else if (xPos > delar && xPos <= parts * 2)  addClass(el, "img:nth-child(3)");  break; // more cases below  );

Som du kan se finns det två anpassade funktioner. För det första removeIsVisibleClass funktion som ansvarar för att ta bort är synlig klass från motsvarande bild. För det andra, desto mer generellt addClass funktion som är ansvarig för att lägga till är synlig klass till målbilden. 

Här är deras signatur:

funktion removeIsVisibleClass () if (document.querySelector ("img.is-visible")) document.querySelector ("img.is-visible"). classList.remove ("is-visible");  funktion addClass (förälder, barn, className = "is-visible") parent.querySelector (child) .classList.add (klassnamn); 

Hittills har vi sett vad som händer varje gång vi svävar över ett kort. Låt oss nu diskutera det motsatta scenariot. Med andra ord, vad ska hända om vi sluta svävar över ett kort. I det här fallet bör den första första bilden visas:

// insides kortslinga el.addEventListener ("mouseleave", () => removeIsVisibleClass (););

4. Browser Support

Vår demo ska fungera bra i de flesta skrivbords webbläsare. Några anteckningar men:

  • Demon använder sig av CSS Grid och för varje slinga som inte stöds av alla webbläsare. Det finns alternativa lösningar för båda fallen om du föredrar att använda en återgång.
  • Demon fungerar på samma sätt på alla skärmar / enheter och är inte optimerad för små skärmar / beröringsenheter. För vår enkla demo är det bra, men i ett verkligt projekt kanske du vill begränsa denna implementering till endast större skärmar (eller enheter utan beröring).

Slutligen använder vi som vanligt Babel för att kompilera ES6-koden ner till ES5.

Slutsats

I denna handledning lyckades vi bygga en intressant svävareffekt genom att utnyttja JavaScript-mushändelser. Förhoppningsvis har du blivit inspirerad nog att bygga något fantastiskt. 

För att ta ytterligare saker uppmanar jag dig att bygga en återanvändbar funktion som hanterar den repeterande koden inuti växla påstående. Skicka en kommentar om du tar utmaningen på!