Övningar i JavaScript del 5 I dessa övningar ska vi ta upp några lika händelsehanterare. Dessa ska dck inte läggas in med attribut i HTML-kden, så sm vi gjrt tidigare med nclick. Istället ska vi nu lägga in alla händelsehanterare i JavaScript-kden, så sm vi tidigare gjrt med nlad. I övningarna kmmer vi ckså in på hur man kan visa ch dölja HTML-element, genm att med JavaScript förändra värdet för CSS-stilen display eller visibility. 1. Dkument i övningsmappen Sm vanligt kan du ladda ner en övningsmapp från labratinens webbsida. Mappen innehåller en html-fil, en css-fil, en js-fil ch en mapp med några bilder. HTML- filen Öppna filen index.htm både i din editr ch i webbläsaren. Kden är uppdelad i ett antal avdelningar med div-taggar. cntrlpanel: En meny med val för de lika frukterna sm finns i bilderna. En knapp sm ska användas för att växla mellan att visa ch dölja rutan med den stra bilden (chsedfruit). fruits: En div-tagg för varje bild på en frukt. I varje div-tagg finns ckså en input-tagg för ett textfält. Därför mges alla divtaggar med ett frm-element, så att alla textfält tillhör frmuläret. chsedfruit: En img-tagg där vald frukt ska visas, då man klickar på en av de små bilderna eller väljer frukt i menyn. En p-tagg där fruktens namn ska läggas in. Texten ska sedan visas i en "ppupruta", då man för in markören över bilden. fter: Endast inf ch är ingen del av prgrammet. CSS- filen Öppna style.css i din editr Filen innehåller kd för layuten, färger, etc. För #chsedfruit p finns stilen visibility:hidden; med. Det innebär att p-taggen från början är dld. JS- filen Öppna script.js i din editr. Det finns ett antal glbala variabler sm sedan ska initieras. Det finns ckså en init-funktin på samma sätt sm vi haft i tidigare exempel i kursen. I funktinen finns ett antal lkala variabler sm kmmer att användas senare. Det finns ckså en initiering av den glbala variabeln chsedfruittag. Detta är en referens till div-taggen med den stra bilden ch görs på samma sätt sm vi gjrt i tidigare labratiner. 2012-11-24 Rune Körnefrs (rune.krnefrs@lnu.se) 1
2. Visa ch dölja den stra bilden Medieteknik Vi börjar med kden för att kunna visa ch dölja rutan med den stra bilden. Då ska du dels skriva funktinen ch dels kppla den till händelsen nclick i knappen. Händelsehanteraren Tidigare i kursen har vi lagt in ett nclick-attribut i de taggar sm vi vill ha händelsehanteraren, men nu ska det istället göras i JavaScript-kden. Lägg till följande kd i init-funktinen: functin init() {! var tag, i, inputtags; chsedfruittag = dcument.getelementbyid("chsedfruit");! tag = dcument.getelementbyid("cntrlpanel").getelementsbytagname("buttn")[0];! tag.nclick = shwhidelargeimage; Med dcument.getelementbyid("cntrlpanel") erhålls en referens till div-taggen, där knappen finns. Där går vi vidare med getelementsbytagname("buttn") ch får en array med referenser till knapparna i div-taggen. Nu har vi endast en knapp, men getelementsbytagname ger alltid en array sm resultat, så det blir en array med ett element. För att kmma åt det elementet indexerar vi med 0. Resultatet av denna långa rad blir alltså en referens till buttn-taggen ch det sparas i variabeln tag. På nästa rad lägger vi till en händelsehanterare för nclick ch säger att funktinen shwhidelargeimage ska anrpas (den funktinen ska skrivas i nästa steg). Resultatet av denna kd är densamma sm m vi i HTML-kden hade skrivit <buttn nclick="shwhideimage()"> Men nu kan vi hålla HTML-kden lite enklare ch där endast strukturera infrmatinen, medan allt sm har med funktinaliteten att göra finns i js-filen. Funktinen Sist i js-filen lägger du till följande funktin: functin shwhidelargeimage() {! alert("klick på knappen"); Till att börja med har vi endast en alert i funktinen, så att vi kan testa att det fungerar ch att den anrpas, då man klickar på knappen. Klicka på knappen, så ska alert-rutan dyka upp. Dölj rutan med den stra bilden: Ta brt alert-satsen ch lägg istället in följande: functin shwhidelargeimage() {! chsedfruittag.style.display = "nne"; Referensen till rutan lades in i chsedfruittag i init-funktinen. Här går vi vidare ch refererar till rutans stil med.style ch sedan stilen display. Den sätts till "nne", för att dölja rutan. Testa i webbläsaren 2012-11-24 Rune Körnefrs (rune.krnefrs@lnu.se) 2
Visa rutan, m den är dld Utöka funktinen med följande kd: functin shwhidelargeimage() {! if (chsedfruittag.style.display == "nne") chsedfruittag.style.display = "blck";! else chsedfruittag.style.display = "nne"; I if-satsen kntrlleras det m display är "nne". I så fall ändras display till "blck". I annat fall ändras display till "nne". Därmed kan vi växla mellan "blck" ch "nne", varje gång man klickar på knappen. 3. Välja frukt Nu ska vi skriva kden för att kunna visa en str bild av frukten, då man klickar på en liten bild. Händelsehanterare Lägg till följande kd sist i init-funktinen: functin init() {! smallimgtags = dcument.getelementbyid("fruits").getelementsbytagname("img");! fr (i=0; i<smallimgtags.length; i++) {! smallimgtags[i].nclick = chseimage;! Först tar vi fram en array med referenser till alla img-taggar i div-taggen med id="fruits". Denna array sparas i variabeln smallimgtags. (Det är en glbal variabel, eftersm vi kmmer att behöva denna array i en annan funktin i en övning längre fram.) Vi går igenm arrayen i en lp. Där lägger vi för varje element (dvs varje img-tagg) in händelsen nclick ch säger att funktinen chseimage ska anrpas. Det blir alltså samma funktin för alla bilder. Skulle vi gjrt detta i HTML-kden, så hade det blivit: <img src="..." alt="..." nclick="chseimage()"> <img src="..." alt="..." nclick="chseimage()">... Funktinen för att visa vald frukt För att kunna byta ut den stra bilden, måste vi ha en referens till dess img-tagg, så lägg till följande kd i init-funktinen: functin init() { largeimgtag = chsedfruittag.getelementsbytagname("img")[0]; Vi utgår från variabeln chsedfruittag, sm innehåller en referens till div-taggen för rutan med bilden. Sedan använder vi getelementsbytagname("img") för att få en array 2012-11-24 Rune Körnefrs (rune.krnefrs@lnu.se) 3
med img-taggarna. I den rutan finns ju endast en bild ch vi kmmer åt den genm att indexera med 0. Denna referens sparas i den glbala variabeln largeimgtag. Lägg till följande funktin sist i js-filen: functin chseimage() {! largeimgtag.src = this.src; Funktinen anrpas, då man klickar på en bild. En referens till den img-tagg sm användaren klickade på finns i this. Med hjälp av den tar vi fram img-taggens src-attribut. Samma bildfil ska visas i img-taggen för den stra bilden, så vi använder largeimgtag ch sätter dess src-attribut till src-attributet för den lilla bilden. Klicka på lika små bilder ch kntrllera att bilden visas i den stra rutan. 4. Välj frukt med menyn Man ska ckså kunna välja en frukt i menyn ch den ska då visas i img-taggen för den stra bilden. Händelsehanterare Lägg till följande kd i init-funktinen: functin init() { tag = dcument.getelementbyid("cntrlpanel").getelementsbytagname("select")[0];! tag.nchange = selectimage; På samma sätt sm vi i övning 2 refererade till knappen i cntrlpanel, refererar vi nu till select-taggen (menyn). Händelsen sm vi här kan känna av är nchange. Den inträffar då det görs ett nytt val i menyn. Till denna händelse kpplar vi funktinen selectimage. Funktinen för att visa vald bild Lägg till följande funktin sist i js-filen: functin selectimage() {! var ix;! ix = this.selectedindex - 2;! largeimgtag.src = smallimgtags[ix].src; Med this får vi en referens till select-taggen, där händelsen inträffade. I menyn tar vi fram selectedindex, sm är ett index till vald ptin-tagg. De två första ptin-taggarna är en uppmaning att välja bild ch en tm rad i menyn (se HTML-kden). Så m vi drar brt 2 ifrån ix, blir det ett index sm börjar på 0 för vald bild. Vi kan då använda det sm index till variabeln smallimgtags, sm innehåller referenser till alla små bilder (den variabeln initierades i init-funktinen i övning 3). Med smallimgtag[ix].src får vi url:en till bilden ch den läggs in i src-attributet i largeimgtag. 2012-11-24 Rune Körnefrs (rune.krnefrs@lnu.se) 4
Återställ menyn Då ett val görs i menyn, stannar menyn kvar på det valet. Ofta vill man ha det så, för att i menyn se vad man valt. Men det går ckså att ändra, så att vi visar det första alternativet igen, dvs i detta fall uppmaningen att välja bild. Lägg till följande rad i funktinen selectimage: functin selectimage() {! var ix;! ix = this.selectedindex - 2;! largeimgtag.src = smallimgtags[ix].src; this.selectedindex = 0; Genm att sätta selectedindex till 0, visas det första alternativet i menyn. 5. Kntrllera textfältet I textfälten ska man skriva frukternas namn. När man lämnar ett textfält, ska innehållet kntrlleras, för att se m rätt namn är inskrivet. Det rätta namnet finns i img-taggens alt-attribut. Händelsehanterare Lägg till följande kd i init-funktinen: functin init() { smallimgtags = dcument.getelementbyid("fruits").getelementsbytagname("img");! inputtags = dcument.getelementbyid("fruits").getelementsbytagname("input");! fr (i=0; i<smallimgtags.length; i++) {! smallimgtags[i].nclick = chseimage; inputtags[i].nblur = checkfruitname;!... Före lpen tas det fram en array med referenser till input-taggarna. Då man lämnar ett textfält (dvs klickar utanför det eller går till nästa textfält) inträffar händelsen nblur. Då ska funktinen checkfruitname anrpas. Funktinen för att kntrllera fruktnamnet Skriv in följande funktin sist i js-filen: functin checkfruitname() {! alert(this.value); Vi börjar med en alert-sats, där textfältets innehåll skrivs ut, så att vi kan kntrllera att funktinen anrpas ch att vi kmmer åt textfältet med this. Testa i webbläsaren Skriv någt i ett textfält ch klicka sedan utanför det eller tryck på tab-tangenten för att gå till nästa fält. 2012-11-24 Rune Körnefrs (rune.krnefrs@lnu.se) 5
Hämta fruktnamnet från img- taggens alt- attribut I HTML-kden har vi en struktur med en div-tagg sm mger en img-tagg, en input-tagg ch en spantagg. Händelsen har inträffat i input-taggen, så this refererar till den. För att kmma åt img-taggen, måste vi från this gå upp till div-taggen ch sedan ner i img-taggen. Ersätt alert i funktinen checkfruitname med följande kd: functin checkfruitname() {! var divtag, fruitname;! divtag = this.parentnde;! fruitname = divtag.getelementsbytagname("img")[0].alt;! alert(fruitname); Med this.parentnde, går vi upp till den tagg sm mger input-taggen, dvs till div-taggen. Utifrån divtag kan vi använda getelementsbytagname("img") för att få en array till imgtaggen ch genm att indexera med 0, får vi en referens till img-taggen. Där kan vi kmma åt alt-attributet. Använd alert, för att testa m vi får fram fruktens namn. Kntrllera fruktnamnet Nu har vi sett att vi kan få fram innehållet i textfältet ch vi kan få fram fruktens namn från imgtaggens alt-attribut, så nu kan vi jämföra dem. Ersätt alert med följande kd i funktinen checkfruitname: functin checkfruitname() {! var divtag, fruitname, spantag;! divtag = this.parentnde;! fruitname = divtag.getelementsbytagname("img")[0].alt;! spantag = divtag.getelementsbytagname("span")[0];! if (this.value == fruitname) spantag.innerhtml = "Rätt";! else spantag.innerhtml = "Fel"; På samma sätt sm vi tg fram en referens till img-taggen, tar vi fram en referens till span-taggen, där resultatet av testet ska skrivas. I if-satsen jämförs textfältet med fruktens namn. Är de lika skriver vi "Rätt", annars "Fel". Ingen resultattext, m textfältet är tmt Om man lämnar textfältet tmt, så är det nödigt att skriva "Fel", så då ska vi istället lämna spantaggen tm. Lägg till följande i funktinen: functin checkfruitname() {! var divtag, fruitname, spantag;! divtag = this.parentnde;! fruitname = divtag.getelementsbytagname("img")[0].alt;! spantag = divtag.getelementsbytagname("span")[0];! if (this.value == "") spantag.innerhtml = "";! else if (this.value == fruitname) spantag.innerhtml = "Rätt";! else spantag.innerhtml = "Fel"; 2012-11-24 Rune Körnefrs (rune.krnefrs@lnu.se) 6
Tillåt både stra ch små bkstäver Om man t.ex. skriver "Pärn" i textfältet för den frukten, så blir det fel, eftersm det står "pärn" i img-taggens alt-attribut. "Pärn" ch "pärn" är alltså inte lika. För att tillåta även stra bkstäver, kan vi knvertera texten från textfältet till små bkstäver, innan testet görs. Lägg till följande i funktinen: functin checkfruitname() {! var divtag, fruitname, spantag, inputtext;! divtag = this.parentnde;! fruitname = divtag.getelementsbytagname("img")[0].alt;! spantag = divtag.getelementsbytagname("span")[0]; inputtext = this.value.tlwercase();! if (inputtext == "") spantag.innerhtml = "";! else if (inputtext == fruitname) spantag.innerhtml = "Rätt";! else spantag.innerhtml = "Fel"; Med tlwercase() knverteras alla tecken till små bkstäver. Vi sparar den knverterade texten i variabeln inputtext ch använder sedan den i if-satserna. 6. Visa fruktens namn över den stra bilden Nu ska rutan med fruktens namn pppa upp, då markören förs in över den stra bilden. Händelsehanterare ch referens till textrutan. Lägg till följande kd i init-funktinen: functin init() { inftexttag = chsedfruittag.getelementsbytagname("p")[0];! largeimgtag.nmusever = shwinftext;! largeimgtag.nmuseut = hideinftext; Funktinerna Variabeln inftexttag blir en referens till p-taggen. I variabeln largeimgtag har vi redan tidigare (i övning 3) tagit fram en referens till imgtaggen med den stra bilden. Till denna kpplar vi nu händelserna nmusever ch nmuseut. Då muspekaren förs in över bilden ska funktinen shwinftext anrpas ch då den förs ut från bilden ska hideinftext anrpas. Lägg till följande funktiner sist i js-filen: functin shwinftext() {! inftexttag.style.visibility = "visible";! functin hideinftext() {! inftexttag.style.visibility = "hidden"; Textrutan ska pppa upp i ett lager framför övrigt innehåll, så därför används visibility, för att visa ch dölja rutan. För in markören över den stra bilden. Det pppar då upp en textruta under bilden. 2012-11-24 Rune Körnefrs (rune.krnefrs@lnu.se) 7
Psitinering av textrutan Textrutan hamnar nu där den ligger i HTML-kden. För att få den i ett lager framför bilden, måste vi lägga till psitin i CSS-kden. Lägg till kd för psitin ch krdinater för tp ch left i CSS-filen, för stilen #chsedfruit p: #chsedfruit p {... visibility:hidden; psitin:abslute; tp:50px; left:50px; Stilen visibility:hidden ch en del annat fanns redan, så lägg endast till psitin, tp ch left. Textrutan hamnar nu i övre vänstra hörnet i fönstret, eftersm krdinaterna gäller hela fönstret. Lägg till följande kd i CSS-filen: #chsedfruit div {psitin:relative; Den div-tagg sm mger bilden ch texten, får en relativ psitinering. Då kmmer krdinaterna för p-taggen inuti den, gälla för div-taggens yta istället för hela fönstret. Nu kmmer textrutan framför bilden. Ändra krdinaterna till följande: #chsedfruit p {... visibility:hidden; psitin:abslute; tp:30px; right:50px; Ett lägre värde för tp, gör att textrutan kmmer lite högre upp. Ändra ckså left till right, så utgår krdinaten från högerkanten istället. (Experimentera sedan med egna krdinater. Det går ckså ha negativa värden, t.ex. right:-30px.) Fruktens namn i textrutan I rutan ska ju namnet på den frukt sm finns i bilden visas. Detta namn kan vi ta fram ch lägga in i p- taggen, då vi byter bild i img-taggen. Lägg till följande kd i funktinen chseimage: functin chseimage() {! largeimgtag.src = this.src;! inftexttag.innerhtml = this.alt; Denna funktin anrpas då man klickar på en liten bild, så this är en referens till den imgtagg man klickat på ch med this.alt får vi fram texten i alt-attributet. Detta läggs in i p- taggen inftexttag. Välj lika bilder ch kntrllera att frukternas namn visas i ppup-rutan över den stra bilden. Det går ju ckså byta bild med menyn, så då måste vi ckså lägga in fruktens namn i p-taggen. 2012-11-24 Rune Körnefrs (rune.krnefrs@lnu.se) 8
Lägg till följande i funktinen selectimage: functin selectimage() {! var ix;! ix = this.selectedindex - 2;! largeimgtag.src = smallimgtags[ix].src;! inftexttag.innerhtml = smallimgtags[ix].alt;! this.selectedindex = 0;! I denna funktin refererar this till menyns select-tagg, så vi kan inte använda this.alt här. Men en referens till den lilla bilden har vi i smallimgtags[ix], så därigenm kan vi kmma åt alt-attributet i den lilla bilden för vald frukt. 7. Markera textfältet, då man klickar på en liten bild Klickar man på en liten bild, så ska även dess textfält markeras, så att man direkt kan skriva text där. Lägg till följande i funktinen chseimage: functin chseimage() {! largeimgtag.src = this.src;! inftexttag.innerhtml = this.alt;! this.parentnde.getelementsbytagname("input")[0].select(); Med this kmmer vi åt img-taggen. Lägger vi till parentnde, får vi en referens till den div-tagg sm mger img-taggen. Där använder vi getelementsbytagname("input") ch indexerar med 0, för att få en referens till input-taggen. Slutligen lägger vi på funktinen select(), för att välja (markera) input-taggen. Slut Då var övningarna slut för denna gång. I dessa övningar tg vi upp: Händelsehanterare för nblur, nclick, nchange, nmusever ch nmuseut. Initiering av händelsehanterare i JavaScript-kden istället för i HTML-kden. Användning av referensen this, för att referera till den tagg där händelsen inträffat. Användning av parentnde, för att gå upp en nivå i HTML-strukturen. Förändring av display eller visibility, för att visa ch dölja element. 2012-11-24 Rune Körnefrs (rune.krnefrs@lnu.se) 9