13.3 Drop zones
Detta exempel bygger vidare på den kod som skapades i föregående exempel. Nu tillkommer kod för hantering av drop zones. Det visas hur flera drop zones kan hanteras och hur man kan avgöra om pekaren kommer in över en drop zone eller lämnar en drop zone, för att ge en visuell feedback. Det visas också hur man kan avgöra om ett element släppts på eller utanför en drop zone. Slutligen visas hur man i en situation kan utesluta en drop zone och på så sätt göra den inaktiv.
28 min.
Sammanfattning
Det används tre variabler i hanteringen av drop zones: dropElems
, dropElem
och hoverElems
.
Variabeln dropElems
är en array som innehåller alla de element som är drop zones. Variabeln dropElem
är en variabel som håller reda på vilken drop zone pekaren befinner sig över. Båda dessa variabler initieras i funktionen pointerStart
och dropElem
sätts då till null
.
Variabeln hoverElems
är en array med alla element som pekaren befinner sig över. Den får man fram med funktionen document.elementsFromPoint()
, vilket görs i funktionen pointerMove
. Sedan jämför man dropElems
med hoverElems
, för att se om det finns en överlappning. I så fall är det en drop zone som pekaren befinner sig över och det elementet sparas i variabeln dropElem
. Finns det ingen överlappning mellan arrayerna, befinner sig pekaren utanför alla drop zones och variabeln dropElem
sätts till null
. I denna kontroll av överlappning kan man också lägga till eller ta bort en CSS-klass i elementet, för att ge eller ta bort en visuell feedback.
I funktionen pointerEnd
kontrollerar man variabeln dropElem
, för att avgöra om man släppt på en drop zone eller ej. Om den innehåller null
är det utanför en drop zone, annars innehåller variabeln den drop zone som man släppt på.
Uteslut (inaktivera) en drop zone
Om man i någon situation vill utesluta en drop zone, gör man det i funktionen pointerStart
, då man tagit fram arrayen med alla drop zones i variabeln dropElems
. Där kan man kontrollera det villkor som ska gälla för uteslutning av en drop zone och sedan ta bort elementet för denna drop zone ur arrayen dropElems
. Då kommer den inte att finnas med i de kontroller som görs i de övriga funktionerna.
CSS-egenskapen pointer-event
Vill man "inaktivera" ett element, så att det inte längre reagerar på några pointer events (inklusive mouse och touch events), kan man i CSS-koden lägga in pointer-events: none;
på elementet. För att göra elementet "aktivt", kan man istället använda värdet auto
, vilket är default-värdet, så i det läget behöver man inte ha med pointer-events
. I exemplet används pointer-event: none;
i klassen taken
.
Egna övningar
Denna övning bygger på exempel ex6-5 del a, med kod för ett litet pussel. Det är nu lite utökat och du ska använda drag-and-drop med pointer events i lösningen. Filerna test.html och test.css innehåller den HTML- och CSS-kod som behövs. Bilder finns i mappen img/puzzles. I filen test.js finns kod för initiering, välja pussel och kontrollera ett pussel. Gör följande tillägg:
- Utgå från koden i filen script-a.js, så du kan kopiera funktionerna
pointerStart
(inkl. inre funktioner),cloneElem
ochoverLapItem
och lägga dem sist i test.js. - I
init
-funktionen går du i en loop igenompieceElems
och lägger på händelselyssnare förpointerdown
, så att funktionenpointerStart
anropas. Lägg också till en händelselyssnare förtouchstart
som utförpreventDefault
.- Prova sedan att klicka på knappen "Nytt pussel" för att få nya pusselbitar i den övre raden. Testa att dra pusselbitarna. Du bör få en visuell feedback om du drar över rutorna i pusslet, men det händer ännu inget då du släpper på rutorna.
- I
pointerEnd
ska du ha kvarif
-satsen medif (dropElem)
, men ta bortswitch
-satsen i den. Istället ska du nu lägga dit kod för att byta bild mellan denimg
-tagg som man släppt på och den man dragit, dvsdropElem
ochorigElem
.- Börja med att spara
dropElem.src
i en lokal variabel. Sedan kan du sparaorigElem.src
idropElem.src.
Slutligen sparar du den lokala variabeln iorigElem.src
. - Därefter lägger du in ett anrop av
checkPuzzle
, för att kontrollera om pusslet är klart.- Prova nu igen att ta fram ett pussel och testa att du kan dra och släppa pusselbitar i rutorna i pusslet.
- Börja med att spara
- Man ska också kunna dra pusselbitar inom pusslet, för att byta plats på bitar som ligger fel. De två händelselyssnare som du la på
pieceElems
iinit
-funktionen, lägger du också in påpuzzleElems
. Du kan göra det i samma loop, eftersom det finns lika många pusselbitar som rutor i pusslet.- Därefter är det klart, så prova nu att du kan dra pusselbitar till pusslet och att du kan flytta runt pusselbitar inom pusslet. Då alla bitar ligger rätt, visas ett meddelande om att pusslet är klart.