Nu när vi bekantat oss med de olika händelserna som ingår i drag and drop skall vi titta på vad vi faktiskt behöver göra för att skapa något användbart.
0 - Förberedelser
- Fortsätt jobba i samma folder som förra labben,
lab-6. - Skapa en
b.jsoch länka in den iindex.htmlgenom att ersättaa.jsi script-taggen. - Överst i scriptfilen, skapa en konstant
messagessom innehåller elementet med idmessages.
1 - Gör element dragbara
Börja med att göra elementen dragbara. Detta görs genom att sätta egenskapen draggable till true på varje element som ska kunna dras. Vi gjorde detta i förra labben, så det borde vara snabbt gjort att göra det igen.
Du behöver:
- Loopa igenom alla element med klassen
drag-item. - Sätta egenskapen
draggabletilltruepå varje sådan element.
Förslag på lösning
const draggables = document.querySelectorAll('.drag-item');
for (const draggable of draggables) {
draggable.draggable = true;
}
Testa Nu bör du kunna dra och släppa elementen, men ännu händer såklart ingenting när vi gör det.
2 - Tillåt släpp i drop-zoner
Som du nog minns från förra labben behöver vi uttryckligen tillåta att man kan släppa elementen i drop-zoner.
Du behöver:
- Loopa igenom alla element med klassen
drop-zone. - Lägga till en eventlyssnare för
dragoverpå varje sådan element. - I lyssnaren, anropa
e.preventDefault(). Detta är nödvändigt för att tillåta drop (standardbeteendet är att inte tillåta drop).
Förslag på lösning
const dropZones = document.querySelectorAll('.drop-zone');
for (const zone of dropZones) {
zone.addEventListener('dragover', function(event) {
event.preventDefault();
});
}
Testa Nu bör du kunna dra och släppa elementen. Men fortfarande händer inget när vi gör det.
3 - Hantera släppet
Slutligen behöver vi hantera vad som händer när användaren släpper elementet. Det görs med drop-eventet.
- Lägg till en eventlyssnare för
droppå alla drop-zones (i samma loop som ovan eller en ny). - I lyssnaren, sätt
textContentpå drop-zonen till texten “Släpp mottaget!”.
Förslag på lösning
Loopen nedan är samma som ovan, men en händelsehanterare för drop är tillagd.
function onDrop(event) {
event.preventDefault();
event.target.textContent = "Släpp mottaget!";
}
for (const zone of dropZones) {
zone.addEventListener('dragover', function(event) {
event.preventDefault();
});
zone.addEventListener('drop', onDrop);
}
Testa Nu bör du kunna dra och släppa elementen. Men funktionaliteten är fortfarande ganska begränsad, eftersom vi inte har någon information om elementet som dras när vi hanterar drop-händelsen.
4 - Information om elementet som dras
Ett enkelt sätt att få tillgång till elementet som dras är att använda e.target i dragstart-eventet och spara referensen till elementet i en global variabel. Då kan vi använda den variabeln i exempelvis drop-eventet för att läsa ut data från elementet som dragits (och släppts).
Du behöver:
- Lägga till en global variabel
let draggedElement = null;. - Som reaktion på
dragstart-eventet, sättadraggedElementtill elementet som drog igång eventet (e.target). - Som reaktion på
dragend-eventet, sättadraggedElementtillnullför att indikera att ingenting dras längre. - I
onDrop, byta ut “Släpp mottaget!” mot värdet idraggedElement.textContent.
Förslag på lösning
let draggedElement = null;
for (const draggable of draggables) {
draggable.draggable = true;
draggable.addEventListener('dragstart', function(event) {
draggedElement = event.target;
});
draggable.addEventListener('dragend', function() {
draggedElement = null;
});
}
Den nya onDrop-funktionen:
function onDrop(event) {
event.preventDefault();
event.target.textContent = draggedElement.textContent;
}
Det finns flera andra sätt kommuncera data mellan det dragna elementet och dropzonen, men detta är en enkel lösning som räcker gott just nu.