Eventhandtering
I flere av eksemplene nedenfor bruker vi følgende CSS:
.hilited{border-style:solid;border-color:red;border-width:thin} .container{ display: flex; display: -webkit-flex; flex-flow: row; -webkit-flex-flow: row; justify-content: space-around; -webkit-justify-content: space-around; min-height: 50px; margin-top:30px; max-width:500px }
Eksempel1
Vi vet at vi kan plante metoder for å handtere begivenheter direkte i html-elementer slik:
<img onclick="this.classList.toggle('hilited')" src="bilder/bs1.png" alt="bs1"/>
og vi får dette, klikk på bildet:
Eksempel2
Vi skal forsøke og gjøre dette litt mer generelt ved å plante metodene fra et javaskript som kjøres når siden lastes. Vi identifiserer de elementene som skal ha en metode ved en klasse (class). I eksempelet nedenfor vi vi at alle bilder med class=bilde2 skal hilites. På denne måte oppnår en lang mer fleksibel arbeidsmetode og det er mindre koding (og omkoding) dersom vi skal redigere større HTML-strukturer. Alt vi trenger å gjøre er å merke alle elementer som skal ha samme dynamiske egenskaper med samme klasse, class. Klikk på et av bildene under.
<img class="bilde2" src="bilder/bs1.png" alt="bs1"/> <img class="bilde2" src="bilder/bs2.png" alt="bs2"/>
javaskriptet er slik:
Vi kan selvsagt identifisere de elementene vi vil plante events i på mange andre måter, f.eks querySelectorAll().
Eksempel3
Vi redesigner litt og introduserer et par standard funksjoner for å plante metoder.
addEventListener('eventname', myfunction ,false)
Den siste parameteren gir oss anledning til bestemme når vi skal plukke opp begivenheten, enten når den er på vei nedover i blokkstrukturen (true) eller når den "bobler" opp (false). Det siste er default.
Vi bruker her den teknikken at vi planter en funsjon som skal reagere på mouseover. Denne metoden tar i sin tur og planter en motode for mouseout. Dra musa over et av bildene.
<div> <div><img class="bilde3" src="bilder/bs1.png" alt="bs1"/></div> <div><img class="bilde3" src="bilder/bs2.png" alt="bs2"/></div> </div>
javaskriptet som kjører er nå slik:
Bubbling
Nå er det slik at begivenheter "bobler". Det vil si at dersom de ikke blir plukket opp i et element forplanter de seg til omgivende elementer. Det er endog slik at dersom de plukkes opp fortsetter de å vandre utover i strukturen dersom vi ikke stopper dem. Når vi som i eksemplene ovenfor har sett at vi kan plukke opp både begivenhetsstype og opprinnelseselement, må vi kunne plassere metoden som handterer begivenheten andre steder enn i det element der begivenheten skjer.
Vi redesigner eksempel2 slik at vi handterer klikk i et div element som omgir bildene.
<div id="container4" class="container"> <div id="box1" class="box"> <img class="bilde4" src="bilder/bs3.png" alt="bs3"/> </div> <div id="box2" class="box"> <img class="bilde4" src="bilder/bs4.png" alt="bs4"/> </div> <div id="box3" class="box"> <img class="bilde4" src="bilder/bs1.png" alt="bs4"/> </div> </div>
javaskriptet som kjører er nå slik:
function initCopy4(){ document.getElementById('container4') .addEventListener('click',showClick,true); } function showClick(e){ var elt=e.target; if(elt.nodeName.toLowerCase()=="img") elt.classList.toggle("hilited"); }
Siden begivenhetene bobler, kunne vi like godt ha plantet klikk-handleren i body-elementet. Problemet med det ville være at vi ville plukke opp alle klikk i hele vevsiden, ikke bare i bildene. Dersom vi hadde plassert en click event handler både i div-elementet som omgir bildene og i body-elementet ville vi fått begivenheten til behandling 2 ganger.
Det er mulig å stoppe forplantingen av begivenheter når vi anser oss ferdige med dem. Vi kan legge inn følgende kodelinjer i en metode for å avbryte boblingen av event e:
... e.stopPropagation(); ...
Vi kan illustrere bobling ved å legge inn en clik-handler både i hvert enkelt bilde og i det omgivende div-elementet.
<div class="container" id="wrapper5"> <img class="bilde5" src="bilder/bs1.png" alt="bs1"/> <img class="bilde5" src="bilder/bs2.png" alt="bs2"/> <img class="bilde5" src="bilder/bs3.png" alt="bs3"/> </div> <div id="filename">Ingen</div>
javaskriptet som kjører er nå slik:
Egne events
Vi kan også lage våre egne events, og vi kan gi event-objektet egenskaper. I dette eksempelet definerer vi event kick og vi definerer egenskapen reaction.
<div class="container" id="wrapper6"> <div id="bs1" class="box"> <img src="bilder/bs1.png" alt="bs"/> </div> <div id="bs2" class="box"> <img src="bilder/bs2.png" alt="bs2"/> </div> <div id="bs3" class="box"> <img src="bilder/bs3.png" alt="bs10"/> </div> </div> <hr/> <button onclick="doKick('bs1')" >kick box1</button> <button onclick="doKick('bs2')" >kick box2</button> <button onclick="doKick('bs3')" >kick box3</button>
javaskriptet som kjører er nå slik: