Drag & Drop, Leaflet
Tapahtumankäsittely: bubbling ja capturing
Ota valmis pohja.zip käyttöösi. Tähän on jo linkitetty tarvittavat kirjastot ja lisätty tarvittava aloitussisältö.
- Etsi kaikki input-elementit joilla type="text". Käytä document.querySelectorAll-funktioa. Käytä selektoria "input[type='text']"
-
Tulosta kaikkien hakemiesi input-elementtien arvot (value) konsoliin. Käytä
forEach-metodia.
inputs.forEach( function(current, index, list) { console.log( current.value ); });
-
Filtteroi
hakemiesi input-elementtien joukkoa siten, että käsittelet vain niitä jotka ovat
required
(vinkki:"[required]"
). Tulosta näiden arvot konsoliin. Sinun pitää ensin muuntaa nodeList-objekti taulukoksi, että pystyt käyttämään filter-metodia.Voisitko tehdä saman ilman filtteriä? Sopivalla selektorilla saat suoraan kaikki oikeat input-elementit. Yritä toteuttaa sama myös selektorilla ilman filtterointia.
- Aseta kaikille edellä hakemillesi input-elementeille arvoksi (value) "foobar". Tee tämä taas ilman silmukkaa käyttäen forEach-metodia.
-
Lisää kaikille valitsemillesi input-elementeille
input-tapahtumankäsittelijä.
Tulosta tapahtumankäsittelijässä konsoliin
this
jathis.value
.this
on tässä tilanteessa sama kuine.target
. - Siirrä ensimmäinen label-elementti lomakkeen viimeiseksi. Elementti vaihtaa paikkaa, jos se lisätään DOM-puussa uuteen kohtaan. Muista, että sinun on appendChild-metodilla lisättävä label form-elementin sisään. Ensimmäisen labelin saat helpoiten etsittyä querySelector-funktiolla.
- Tee kopio (cloneNode) viimeisestä label-elementistä sisältöineen ja lisää se vielä viimeiseksi. Sinulta pitäisi siis löytyä "Malli1" kahteen kertaan.
- Poista "Malli2"-label sisältöineen.
- Muuta edellä tekemäsi input-tapahtuman käsittely yksinkertaisemmaksi ja tehokkaammaksi. Lisää input-tapahtumankäsittely suoraan form-elementtiin. Lähes kaikki tapahtumat kulkevat koko elementtipuun läpi alkaen objektista, johon tapahtuma kohdistui ja kulkien puun läpi aina body-elementtiin asti. Tämä on bubbling. Kts. bubbling and capturing. Todellisuudessa tapahtuma etenee ensin ylimmältä tasolta (body) alas aina siihen elementtiin johon se kohdistui. Tämä vaihe on capturing (tunneling). Vasta tämän jälkeen palataan takaisin ylöspäin (bubbling) ja se on järkevin vaihe käsitellä tapahtuma.
- Lisää form-elementtiin input-tapahtuman käsittely jossa tulostat konsoliin
aina sen elementin valuen ja name-attribuutin, johon tapahtuma kohdistui. Lisää
kaikille input-elementeille uniikit name-attribuutit. Tutki mitä sisältävät
tapahtumankäsittelijälle parametrina tulevan objektin (event tai e) target,
currentTarget
ja type-propertyt. Vertaa näitä myösthis
-objektiin.- target : elementti (tässä input), jolle tapahtuma on tapahtunut
- currentTarget : elementti (tässä form), joka käsittelee tapahtuman
- type : tapahtuman tyyppi ( tässä input )
- this : elementti, joka käsittelee tapahtuman (tässä form)
- Jos haluat estää tapahtuman bubbling/capturing vaiheen niin se onnistuu kutsumalla e.stopPropagation(). Tätä ei kannata tehdä ellei siihen ole oikeasti hyvä syy.
- Lisää lomakkeelle (form-elementti) click-tapahtumankäsittelijä. Tulosta konsoliin hiiren koordinaatit aina click-tapahtuman tapahtuessa. Kts. MouseEvent Selvitä itsellesi mitä eroa on erilaisilla koordinaattityypeillä
Drag & Drop
Lue HTML Drag and Drop API ja Drag Operations.
Tee valmiissa pohjassa oleva "Tätä voi kohta raahaamalla siirtää"-teksti raahattavaksi alueelle jolla lukee "Tänne voi kohta pudottaa". Drag & Drop toteutetaan seuraavalla tavalla:
- Aseta raahattavan elementin draggable-ominaisuuden arvoksi true
let drag = document.getElementById("drag"); drag.setAttribute("draggable", "true");
- Aseta raahattavan elementin dragstart-tapahtumalle
käsittelijä. Aseta käsittelijässä raahattava
data.
Dataa voi olla useassa eri muodossa.
Omassa sovelluksessa voi keksiä tyypiksi aivan oman, mutta jos haluat raahauksen toimivan sovelluksien välillä, on käytettävä standardityyppejä. Oma tyyppi oman sovelluksen sisällä mahdollistaa raahattavan tiedon tunnistamisen ja estää väärän datan raahaamisen väärään paikkaan.
drag.addEventListener("dragstart", function(e) { // raahataan datana elementin id-attribuutin arvo e.dataTransfer.setData("text/plain", drag.getAttribute("id")); //voi myös raahata omalla keksityllä tyypillä // e.dataTransfer.setData("omadata", drag.getAttribute("id")); // sama data voi olla raahattavana useassa eri muodossa! vrt. leikepöytä });
- Voit asettaa myös raahausefektin.
- Luo raahauksia vastaanottava kohde määrittelemällä drop-
ja dragover-tapahtumankäsittelijät.
Dragover-tapahtumassa aseta sopiva dropEffect. Firefoxissa on oletusdropefekti "move". Chromessa efekti on "none". Chromessa raahaaminen ei toimi ellei efektiä ole määritelty. Dragover-tapahtumassa ei vielä pääse käsiksi raahatun datan sisältöön, mutta pystyy lukemaan raahattavan datan tyypin (
e.dataTransfer.types
).if ( e.dataTransfer.types.includes("text/plain") ) ...
Drop-tapahtumassa lue raahattu data ja tee sille jotain. Tässä tapauksessa hae elementti raahatun id:n perusteella ja siirrä se raahausalueen sisälle. Raahattua dataa ei voi lukea raahauksen aikana, vain vasta drop-tapahtumassa. Tämä on tarkoituksellinen rajoite eli et voi vakoilla kaikkea mitä sovelluksesi yli satutaan raahaamaan.Poikkeus: Firefox sallii dragover-tapahtumassa raahatun datan sisällön käpistelyä, JOS data ja raahaus on lähtöisin firefoxista. Chromessa tämäkään ei onnistu.
let drop = document.getElementById("drop"); drop.addEventListener("dragover", function(e) { e.preventDefault(); // Set the dropEffect to move e.dataTransfer.dropEffect = "move" // tämä ei toimi vaan data on aina 0 mittainen // let data = e.dataTransfer.getData("text/plain"); }); drop.addEventListener("drop", function(e) { e.preventDefault(); let data = e.dataTransfer.getData("text/plain"); // lisätään tämän elementin sisään e.target.appendChild(document.getElementById(data)); });
- Kokeile toimiiko
- Tee vastaavalla tavalla toimiva alueen kopioiminen. Kopioi raahaamalla "Tätä voi kohta raahaamalla kopioida"-aluetta "Tänne voi kohta pudottaa"-alueelle. Käytä harjoituksen vuoksi itse keksittyä datan tyyppiä.
Drag & dropin yhteydessä käytetään seuraavia tapahtumia:
- drag tapahtuu elementtiä raahattaessa
- dragend tapahtuu, kun raahaaminen lopetetaan
- dragenter tapahtuu, kun raahataan elementti drop-kohteen päälle
- dragexit
- dragleave, tapahtuu, kun elementti poistuu drop-kohteen päältä
- dragover, tapahtuu, kun elementtiä raahataan drop-kohteen päällä
- dragstart, tapahtuu, kun aloitetaan raahaaminen
- drop, tapahtuu, kun elementti pudotetaan drop-kohteeseen
Lisätietoa
- HTML Drag and Drop API
- DataTransfer
- Reommended Drag Types
- Drag Operations
- Dragging and Dropping Multiple Items
- HTML5 drag and drop API across browsers
Kartat
Paikkatieto ja kartat ovat useissa sovelluksissa tärkeitä. Tehdään yksinkertainen karttasovellus Leaflet-kirjaston avulla.
Kopioi käyttöösi valmis pohja2.zip johon on linkitetty tarpeelliset kirjastot.
- Luo kartta ja lisää siihen maanmittauslaitoksen maastokartta.
Joudut ensimmäisenä hakemaan itsellesi oman API-avaimen, jotta voit käyttää MML:n karttoja.
let mymap = new L.map('map', { crs: L.TileLayer.MML.get3067Proj() }).setView([62.2333, 25.7333], 11); L.tileLayer.mml_wmts({ layer: "maastokartta", key : "henkilökohtainen MML:n API-avain" }).addTo(mymap);
- Piirrä kartalle ympyrä koordinaatteihin [62.2325, 25.7355]
let circle = L.circle( [62.2325, 25.7355], { color: 'red', fillColor: '#f03', fillOpacity: 0.5, radius: 100 } ).addTo(mymap);
Kokeile muutella ympyrän parametreja. Lisää ympyrään myös popup:
circle.bindPopup('Jiihaa!');
- Lisää kartalle myös markeri koordinaatteihin [62.2333, 25.7333].
let marker = L.marker([62.2333, 25.7333]).addTo(mymap);
- Piirrä kartalle myös viiva käyttäen polyline-objektia:
let koords = [[62.2325, 25.7355],[62.2333,25.7333],[62.23, 25.73],[62.232, 25.7222]]; let polyline = L.polyline(koords, {color: 'blue'}).addTo(mymap);
-
Lisää markeriin popup, joka kertoo markerin koordinaatit:
marker.bindPopup("Paikka : " + marker.getLatLng() + "").openPopup();
- Tee markerista raahattava (draggable)
- Seuraa markerin dragend-tapahtumaa. Päivitä popup aina raahaamisen päätyttyä näyttämään uuden sijainnin koordinaatit
marker.addEventListener("dragend", function(e) { ... });
- Jatka piirtämääsi polylinea aina siihen pisteeseen mihin raahaat markerin.
- Kokeile keskittää kartta sijaintipaikkaasi
mymap.locate({setView: true, maxZoom: 16});
Muista antaa selaimelle lupa kertoa sijaintisi sivulle. Kokeile sivua myös puhelimellasi. Kts. Leaflet on Mobile
Käyttäjien kommentit