Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Afspilning af lyd - virker kun i IE(9)

4 views
Skip to first unread message

Dennis Munding

unread,
Apr 30, 2012, 5:46:40 AM4/30/12
to
Hej gruppe


Jeg har i datalogi fået til opgave at implementere en app lavet til android,
på en hjemmeside med alle de udvidelser jeg selv har lavet.
En af disse er lyd ved klik på en knap.

P.t. virker det kun i IE(9) - har ikke mulighed for at teste i tidl.
versioner.

Projektet kan ses her:
http://test.skovaa-munding.dk/javascript/sider/terning.shtml

Tilhørende javascript til afspilning af lydfilen:

<kode>
var audiofile = '../sound/rolldice.wav';
var loop = 1;

function playsound() {
document.getElementById("content").innerHTML=document.getElementById("content").innerHTML+'<bgsoundid="audioContainer" src="" loop="'+loop+'">'; var e=document.getElementById('audioContainer'); e.src=audiofile;}</kode>Tilhørende html:<kode><div id="content"> <input type="button" value="Kast med terningerne" onclick="playsound();kast(); frekvens()" class="button" /></kode>Ved ikke om det har noget af sige, at der er flere kald i onclick - kan detpåvirke??Min umiddelbare mening er, at det burde det ikke gøre...Jeg er på ingen måde i nærheden af at være javascript-øvet - ikke engangnybegynder... :-)Så ethvert konstruktivt indspark er kærkomment. (Min datalogilærer leverstadig i forrige århundrede, så det gør det ikke nemmere, når man skalfejlsøge... :-/På forhånd tak for hjælpen.Med venlig hilsen--Dennis Mundinga.k.a. The Eye - Member of the PosseGrim Squadhttp://pgsquad.com/"When you hear the wind - you're already dead..."

Birger Sørensen

unread,
Apr 30, 2012, 7:16:32 AM4/30/12
to
Dennis Munding udtrykte præcist:
Noget er gået galt med linieskift i din post - det er lidt svært at
læse...

Der findes ikke noget <bgsound> element i standarderne - det er en
M$ting - og dit script til lyden, virker da heller ikke i FF.
http://www.w3.org/TR/html401/index/elements.html
(Se evt. Kims side
http://kimludvigsen.dk/tips-internet-websnedker-multimedia.php )

Flere ting i onclick er OK - bortset fra, at det bør implementers
unobtrusive. Det kan man også gøre med flere (er faktisk lidt af
pointen) - men man kan så ikke være sikker på rækkefølgen, så hvis den
er vigtig, bør de tre kald samles i en enkelt funktion.

Principielt er der en fejl - der er lige så mange <bgsound> elementer,
som der har været terningkast. Du tilføjer et element til "content",
ved hvert slag, men fjerner dem aldrig igen...
Du giver dem oven i købet samme id - audioContainer - så det burde være
relativt enkelt at fjerne eksisterende, inden der indsættes et nyt.
var audio = document.getElementById('audioContainer');
if (audio) {
audio.parentNode.removeChild(audio);
}
Id'er skal være unike, så enten skal du fjerne elementet, eller også
overveje om elementet skal indsættes i HTML'en, hvis det er nok at
ændre src'en.
(Jeg ved det ikke - bruger ikke M$'s opfindelser udenfor standarderne.
Men du kunne prøve det, hvis det er nok at der er lyd i IE.)

Dit js mangler at definere variable - nogle steder bruger du var
deklarationen; andre steder ikke.

Firbug brokker sig over ikke at kunne finde billedet terning1.png - men
viser det alligevel. Tror det står et eller andet sted i enten HTML
eller CSS med en forkert sti.

Ellers fint nok.

Birger

--
http://varmeretter.dk - billig, sund og hurtig mad
http://skippersevent.dk


Dennis Munding

unread,
Apr 30, 2012, 12:10:13 PM4/30/12
to
Hej Birger,
"Birger Sørensen skrev:
Ved ikke lige, hvad der er gået galt der - har ikke ændret på mine
indstillinger (plejer ikke at være problemer).

> Der findes ikke noget <bgsound> element i standarderne - det er en
> M$ting - og dit script til lyden, virker da heller ikke i FF.
> http://www.w3.org/TR/html401/index/elements.html
> (Se evt. Kims side
> http://kimludvigsen.dk/tips-internet-websnedker-multimedia.php )

Nej, det var jeg klar over, men tænkte jeg ville prøve det alligevel...
Har lavet et nyt forsøg med <object> (1).

> Flere ting i onclick er OK - bortset fra, at det bør implementers
> unobtrusive. Det kan man også gøre med flere (er faktisk lidt af
> pointen) - men man kan så ikke være sikker på rækkefølgen, så hvis den er
> vigtig, bør de tre kald samles i en enkelt funktion.

Rækkefølgen er ikke vigtig - blot de bliver udført, når der klikkes på
knappen.

Unobstrive - et ord jeg ikke forstår betydningen af i denne sammenhæng...??

> Principielt er der en fejl - der er lige så mange <bgsound> elementer, som
> der har været terningkast. Du tilføjer et element til "content", ved hvert
> slag, men fjerner dem aldrig igen...
> Du giver dem oven i købet samme id - audioContainer - så det burde være
> relativt enkelt at fjerne eksisterende, inden der indsættes et nyt.
> var audio = document.getElementById('audioContainer');
> if (audio) {
> audio.parentNode.removeChild(audio);
> }

Den havde jeg ikke lige luret (min manglende kendskab til javascript er nok
hovedårsagen).
Javascriptkoden var noget jeg fandt på et website.
Skulle jeg nok have undladt. :-)

> Id'er skal være unike, så enten skal du fjerne elementet, eller også
> overveje om elementet skal indsættes i HTML'en, hvis det er nok at ændre
> src'en.

Tjek! :-)

> (Jeg ved det ikke - bruger ikke M$'s opfindelser udenfor standarderne. Men
> du kunne prøve det, hvis det er nok at der er lyd i IE.)

Hvis det kun virker i IE er det ikke brugbart i min verden... :-)

> Dit js mangler at definere variable - nogle steder bruger du var
> deklarationen; andre steder ikke.

Forstået - det er en ommer... :-)
Gider ikke bruge tid på at "reparere" ubrugelig kode - så hellere lave det
ordenligt "from scratch". :-)

> Firbug brokker sig over ikke at kunne finde billedet terning1.png - men
> viser det alligevel. Tror det står et eller andet sted i enten HTML eller
> CSS med en forkert sti.

Det var en "fejl-40"... :-/
Er rettet.

> Ellers fint nok.

Takker :-)

(1) Har for overskuelighedens skyld, lagt det i et "svar" for sig selv.

Mange tak for indsparket.


Med venlig hilsen
--
Dennis Munding

Dennis Munding

unread,
Apr 30, 2012, 12:31:30 PM4/30/12
to
Mit oprindelige forsøg var fyldt med fejl - især i html-delen (det er hvad
man får ud at "copy-paste" forældet kode... :-/

Jeg har derfor forsøgt mig med noget andet, som desværre ikke vil, som jeg
vil (Læs: jeg fatter ik' en meter!).

Javascriptet er ændret til:

function playsound() {
try {
document.getElementById("playsound1").value=true;
document.getElementById("playsound2").value=true;
}catch(err) {
txt="Der opstod en fejl på siden.\n\n";
txt+="Beskrivelse af fejl: " + err.message + "\n\n";
txt+="Klik OK for at fortsætte.\n\n";
alert(txt);
}
}

Html'en er ændret til:

<div>
<object classid="clsid:6BF52A52-394A-11D3-B153-00C04F79FAA6" width="0"
height="0" id="sound">
<param name="URL" value="../sound/rolldice.wav" />
<param name="autostart" id="playsound1" value="false" />
<param name="loop" value="1" />

<!--[if !IE]>-->
<object type="audio/x-wav" data="../sound/rolldice.wav" width="0"
height="0" />
<param name="autostart" id="playsound2" value="false" />
<param name="loop" value="1" />

<p>Din browser trænger til en opdatering eller et nyt plugin...</p>
</object>
<!--<![endif]-->
</object>
</div>
<form action="#">
<input type="button" value="Kast med terningerne" onclick="playsound();
kast(); frekvens()" class="button" />
...

Men jeg får (næsten som ventet) en fejl:
"Værdien af egenskaben 'value' kan ikke angives: Objektet er null eller ikke
defineret."
(Sidespørgsmål: Hvorfor kommer denne "alert" kun i IE??)


På forhånd tak for alle indspark.


Med venlig hilsenDennis Munding

Philip Nunnegaard

unread,
Apr 30, 2012, 12:47:00 PM4/30/12
to
Dennis Munding skrev:

> Unobstrive - et ord jeg ikke forstår betydningen af i denne sammenhæng...??

Princippet skulle være at undgå at kalde javascripts i html-koden og i
stedet have det hele i den eksterne javascript-fil - ligesom med css.

Selv finder jeg stoffet omkring unobtrusive javascript (eller diskret
javascript om man vil) for langhåret. Måske kommer der en dag en
tutorial om det som er tilpas pædagogisk og unørdet.

--
Philip

Dennis Munding

unread,
Apr 30, 2012, 1:43:19 PM4/30/12
to
Hej Philip,

"Philip Nunnegaard" skrev:
Mange tak for den pædagogiske forklaring, som giver meget mere mening. :-)

Birger Sørensen

unread,
Apr 30, 2012, 3:15:51 PM4/30/12
to
Dennis Munding forklarede:
> Hej Philip,
>
> "Philip Nunnegaard" skrev:
>
>> Dennis Munding skrev:
>>
>>> Unobstrive - et ord jeg ikke forstår betydningen af i denne
>>> sammenhæng...??
>>
>> Princippet skulle være at undgå at kalde javascripts i html-koden og i
>> stedet have det hele i den eksterne javascript-fil - ligesom med css.
>>
>> Selv finder jeg stoffet omkring unobtrusive javascript (eller diskret
>> javascript om man vil) for langhåret. Måske kommer der en dag en tutorial
>> om det som er tilpas pædagogisk og unørdet.
>
> Mange tak for den pædagogiske forklaring, som giver meget mere mening. :-)
>
>
> Med venlig hilsen

Det er lidt en del af "moderne tænkning": Et site består af tre dele;
indhold (HTML), formattering (CSS) og funktionalitet (scripting).
For at overholde dette, er man nødt til at fjerne scripting fra
HTML'en.
Det giver så også nogle andre fordele - man kan sætte flere
event-handlere på samme element, og man kan også fjerne dem eller ændre
hvilken der skal anvendes, afhængig af andre ting.

Og det er forholdsvis enkelt - selvom det er lidt mere besværligt, end
at skrive det i HTML.
Først skal man tænke på, at dokumentet ikke findes, før det er hentet
fra serveren, og at de enkelte elementer, ikke eksisterer før
dokumentet er hentet. Man er derfor nødt til at tildele event-handlere,
i window's onload event handler. (Window eksisterer, når browseren er
åben - derfor kan der tildlelen en event handler til window, før
dokumentet er hentet. Mener godt man kan bruge body og måske også
document også, men er ikke sikker).
Selve tildelingen sker med DOM funktioner. Uheldigvis er M$ anderledes
på det punkt. Jeg bruger en funktion til det; i det følgende kaldet
SetEvent(). Den har tre parametre: elementet eventhandleren skal sættes
for, hvilken event der er tale om, og hvilken funktion der skal kaldes.

Et eksempel der tildeler en event-handler til et klik på et billede der
har id="mit_billede", kan se sådan ud:

SetEvent(window, 'click', InitDokument);

function SetEvent(elm, evt, fnc) { // sætter event handlere på
elementer
if (elm) {
if (elm.addEventListener) { // for rigtige browsere
elm.addEventListener(evt, fnc, false);
}
else if (elm.attachEvent) { // for IE
elm.attachEvent('on'+evt, fnc);
}
}
}

function InitDokument() {
var elm = document.getElementById('mit_billede');
if (elm) {
SetEvent(elm, 'click', MinKlikHandler);
}
}

function MinKlikHandler() {
alert('Du klikkede på billedet');
}

Og det skulle nogenlunde demonstrere teknikken.
Bemærk at funktionen der angives til SetEvent (eller hvis du selv vil
skrive en rutine til det, DOM-funktionerne addEventListener() i rigtige
browsere og attachEvent() i IE), er en pointer til funktionen - altså
funktionsnavnet uden paranteser - og at man ikke kan overføre parametre
(andre end eventen selv - det gøres automatisk i rigtige browsere, i IE
skal man bruge window.event).
Skal man bruge eventen - altså det der aktiverede eventhandleren - skal
man have den med som parameter i eventhandler funktionen, som f.eks.:
function MinKlikHandler(evt) { ... }

Håber det hjælper lidt på forståelsen.

Birger Sørensen

unread,
Apr 30, 2012, 3:30:23 PM4/30/12
to
Birger Sørensen har bragt dette til verden:
Første linie i eksemplet er forkert. Der skal selvfølgelig stå:

SetEvent(window, 'load', InitDokument);

Philip Nunnegaard

unread,
Apr 30, 2012, 5:48:30 PM4/30/12
to
Birger Sørensen skrev:

> Og det er forholdsvis enkelt

(...)

> SetEvent(window, 'click', InitDokument);
>
> function SetEvent(elm, evt, fnc) { // sætter event handlere på elementer
> if (elm) {
> if (elm.addEventListener) { // for rigtige browsere
> elm.addEventListener(evt, fnc, false);
> }
> else if (elm.attachEvent) { // for IE
> elm.attachEvent('on'+evt, fnc);
> }
> }
> }
>
> function InitDokument() {
> var elm = document.getElementById('mit_billede');
> if (elm) {
> SetEvent(elm, 'click', MinKlikHandler);
> }
> }
>
> function MinKlikHandler() {
> alert('Du klikkede på billedet');
> }
>
> Og det skulle nogenlunde demonstrere teknikken.

Øh...
Stadig totalt sort snak.


--
Philip

Birger Sørensen

unread,
May 1, 2012, 1:40:39 AM5/1/12
to
Hvilken del af det Philip?

SetEvent() sætter en eventhandler - for elementet, eventen og
funktionen, der leveres som parametre.
Første linie sætter onload på window til at kalde Initdokument().
[svarer til <body onload="InitDokument()">]
InitDokument() finder billedet og sætter eventhandler for onclick til
MinKlikHandler() for det.
[svarer til <img id="mit_billede" src=".." alt=".."
onclick="MinKlikHandler()">]
Og MinKlikHandler() viser en meddelelse.

Dennis Munding

unread,
May 1, 2012, 2:37:47 PM5/1/12
to
Hej Birger,

"Birger Sørensen" skrev:
> Birger Sørensen har bragt dette til verden:

X8

>> Det er lidt en del af "moderne tænkning": Et site består af tre dele;
>> indhold (HTML), formattering (CSS) og funktionalitet (scripting).
>> For at overholde dette, er man nødt til at fjerne scripting fra HTML'en.
>> Det giver så også nogle andre fordele - man kan sætte flere
>> event-handlere på samme element, og man kan også fjerne dem eller ændre
>> hvilken der skal anvendes, afhængig af andre ting.

Den metode har jeg benyttet næsten 100% i de seneste par år. :-)

>> Og det er forholdsvis enkelt - selvom det er lidt mere besværligt, end at
>> skrive det i HTML.
>> Først skal man tænke på, at dokumentet ikke findes, før det er hentet fra
>> serveren, og at de enkelte elementer, ikke eksisterer før dokumentet er
>> hentet. Man er derfor nødt til at tildele event-handlere, i window's
>> onload event handler. (Window eksisterer, når browseren er åben - derfor
>> kan der tildlelen en event handler til window, før dokumentet er hentet.
>> Mener godt man kan bruge body og måske også document også, men er ikke
>> sikker).
>> Selve tildelingen sker med DOM funktioner. Uheldigvis er M$ anderledes på
>> det punkt. Jeg bruger en funktion til det; i det følgende kaldet
>> SetEvent(). Den har tre parametre: elementet eventhandleren skal sættes
>> for, hvilken event der er tale om, og hvilken funktion der skal kaldes.

Ok. Det havde jeg aldrig regnet ud, at man kunne...
Ovenstående fungerer glimrende i det tænkte eksempel (har testet det :-) ),
men jeg kan ikke lige gennemskue, hvordan jeg kan få afspillet en lyd, når
der klikkes på en knap...?
Tror øverste etage er stået delvis af - for mange analyser i dansk har
svitset de få tilbageværende celler... :-/

Men vil forsøge mig lidt frem - evt. i mine datalogitimer imorgen...

Forløbig tusind tak for indspark. :-)

Birger Sørensen

unread,
May 1, 2012, 6:46:59 PM5/1/12
to
Dennis Munding kom med følgende:
Jeg ville egentlig have været gennem din kode, for der er nogle ting,
jeg ville gøre anderledes. Der er f.eks. ikke nogen grund til at
terningerne er <input>, og der er reelt heller ingen grund til at bruge
en form - man vil ganske vist koble folk uden javascript af, men de har
vist ikke så meget fornøjelse af det, alligevel.
Men der er ikke blevet tid i dag.

Brugeren klikker på en "knap", og der sker nogen ting (lyd,
terning-slag, opdatering af statistik og visning af resultat).
Og du har funktionaliteten i onclick på en button;
<input type="button" class="button" onclick="playsound(); kast();
frekvens()" value="Kast med terningerne"> (mangler i øvrigt principielt
et ; efter sidste funktionskald).
Så i din kode skal du bare give button et id, fjerne tildelingen of
onload fra HTML'en, og erstatte (eller tilføje, når du nu har lagt
eksemplet ind ^^ ) tildelingen af de tre funktioner til den i
InitDokument() i eksemplet.
Så har du implementeret eventhandling - klik på knappen - og det er
unobtrusive - der er ingen js i HTML'en, og det forstyrrer ikke anden
funktionalitet, som måtte eksistere (der er ikke noget andet i dette
tilfælde, men det er vel ligemeget for eksemplets skyld)..

Det er ikke fordi jeg mener, at du absolut skal gøre det unobtrusive.
Men teknikken har nogle fordele.

Jeg har tidligere i en anden tråd nævnt forme.
Jeg har et lille script, der sørger for at alle input og textarea'er
highligter al tekst når de fokuseres, og at det første <input> i formen
altid er valgt, når den vises første gang.
Det gøres unobtrusive, og uafhængigt af HTML'en, ved i js (ved onload
på window) at gennemløbe alle <input> og <textarea>, og sætte event
handlere for dem. Så det virker på alle forme - og faktisk også, hvis
man ikke bruger forme (Hvis man f.eks. submitter med AJAX kan man ikke
bruge en form til at indsamle data).
Et sidespring måske - tanken var at belyse lidt af fordelene. Uanset
hvad der ellers sker på en side med en form og dette script, vil det
altid virke - forudsat, at det der måtte blive implementeret i den
aktuelle situation (validering f.eks.), også gøres unobtrusive. Det går
ikke at blande tingene.

Jeg kan godt uddybe hvis du er interesseret eller har brug for det.

Rune Jensen

unread,
May 2, 2012, 11:32:47 AM5/2/12
to
On 1 Maj, 07:40, Birger Sørensen <s...@bbsorensen.com> wrote:
> Philip Nunnegaard skrev den 4/30/2012:
> >> Og det skulle nogenlunde demonstrere teknikken.

Mjoh...

> > Øh...
> > Stadig totalt sort snak.
>
> Hvilken del af det Philip?

Du bør nok lave en inline JS-ekvivalent for den unobtrusive, og så
sætte dem under hinanden, ellers kan man ikke umiddelbart se
sammenhængen.

Tog også mig en rum tid at fatte.

Lav f.eks. to stykker JS, én unobtrusive og én inline, som viser en
onclick, men på den samme HTML.

Så burde man kunne se det.


MVH
Rune Jensen

scootergrisen

unread,
May 2, 2012, 12:04:51 PM5/2/12
to
Nu gider jeg ikke læse de andres svar men i stedet for at bruge
<bgsound> så brug den nye <audio>.
Jeg aner dog ikke noget om android.

Du kan prøve <audio> her og se hvad formater der virker i hvilke
browsere : http://scootergrisen.dk/htmlgrisen/kode_audio_formater.php
Og hvis det skal startes fra javascript så se : http://scootergrisen.dk/htmlgrisen/test3.php

Philip Nunnegaard

unread,
May 2, 2012, 1:01:51 PM5/2/12
to
Den 02-05-2012 17:32, Rune Jensen skrev:

> Du bør nok lave en inline JS-ekvivalent for den unobtrusive, og så
> sætte dem under hinanden, ellers kan man ikke umiddelbart se
> sammenhængen.
>
> Tog også mig en rum tid at fatte.
>
> Lav f.eks. to stykker JS, én unobtrusive og én inline, som viser en
> onclick, men på den samme HTML.
>
> Så burde man kunne se det.

Præcis. Det er så sort snak for mig, at jeg ikke en gang kan forklare
hvad jeg ikke forstår.

Altså kort sagt:

Hvordan laver jeg præcis dette:

<a href="" onclick="goer_noget()">Linktekst</a>

Jeg er med så langt som at man skal skrive <a href=""
class="noget">Linktekst</a>

Men derfra til at kæde en funktion sammen med class="noget" er jeg
hægtet helt af.

Derfor venter jeg bare på at der kommer en pædagogisk tutorial på nettet
eller en lærebog som er nem at forstå.

Indtil da vil jeg fortsætte med lave det inline.

--
Philip

Birger Sørensen

unread,
May 2, 2012, 3:33:41 PM5/2/12
to
Philip Nunnegaard har bragt dette til os:
Jeg er ikke pædagog, men jeg kan da godt prøve. ^^

Alle elementerne i HTML, er objekter, og de har indbyggede metoder til
at tildele event-handling.
Og bare for at forhindre misforståelser, så dækker det fine ord
"event-handler" over en funktion, der kaldes, når en given hændelse
(event) sker.
En event-handler er altså en funktion. (Men en funktion er først en
event-handler, når den bliver sat til at blive kaldt ved en event).

Den indbyggede funktionalitet, kan faktisk håndtere mere end een
event-handler for hver event.
Man kan sige, at on/event/ (onclick f.eks.) er i virkelighed en liste
eller et array.
Bruger man objektets indbyggede funktionalitet, tilføjes funktionen til
elementets eksisterende event-handlere for den aktuelle event.
Men bruger man inline versionen - onclick="goer_noget();" - overskriver
man listen, og fjerner altså andre handlere, der kan være tilføjet. Og
det gælder også, hvis man i javascript bruger muligheden for blot at
skrive elm.onclick=goer_noget;

Og forskellen på unobtrusive og inline er i virkeligheden, at
unobtrusive bruger objektets funktionalitet til håndtering af
eventhandlere, mens inline overskriver objektets variable (- som i
virkeligheden emm. burde være private, så de ikke kan tilgås direkte).
Så "unobtrusive", er altså også lidt mere end blot at skille js ud fra
HTML'en, for skille funktionalitet fra indhold.

Og hvordan bruger man så objectets indbyggede funktionalitet?
I al sin enkelthed, gør man det ved at kalde den objekt metode, der er
beregnet til det.
Den hedder addEvenListener() (undtagelsen er overraskende : IE<9, hvor
den hedder attachEvent()).
Der er to parametre: type og listener.
type angiver hvilken event der er tale om, og angives som en streng,
men *uden* /on/ foran; click, mousedown, keypress etc.
listener er en referance til den funktion der skal kaldes når eventen
indtræder. I js, gøres det ved at give funktionsnavnet *uden*
paranteserne.
Se evt. også
https://developer.mozilla.org/en/DOM/element.addEventListener
(der er en tredie mulig parameter, som bruges til at forhindre at
eventen kaldes, hvis der er tale om en event der "bobbler op" fra et
andet element - skal ikke komme ind på det yderligere her.)

Så hvis man nu vil skrive
<a href="" onclick="goer_noget()">Linktekst</a>
som unobtrusive?

Man er til at begynde med nødt til at kunne lokalisere anchor elementet
i sin js. Det enkleste er, at give objektet et id (ikke som Philip
foreslår class; class bruges til fomattering, ikke funktionalitet), men
er der andre måder at finde elementet, er det ikke nødvendigt. (I mit
script til forme, f.eks. tildeles en eventhandler til alle elementer af
en bestemt type - men det er nok oftere man har brug for et bestemt
element, og til det er id uovertruffen.)

Vi ændrer altså HTML'en til:
<a href="" id="mit_link">Linktekst</a>
I js skal vi så tildele en eventhandler til det element, der har
id="mit_link". F.eks.:

var linket = document.getElementById('mit_link');
linket.addEventListener('click', goer_noget); //kun browsere og IE9

[Det kan skives sammen -
document.getElementById('mit_link').addEventListener('click',
goer_noget);
- men jeg foretrækker at skille tingene for overskuelighedens skyld.
Jeg har normalt også en test på om linket også er fundet - se evt.
tidligrere eksempel - for at undgå fejlmeddelelser, hvis noget går
galt.]

Og hermed har man så tildelt den samme funktionalitet på unobtrusive
vis.
Men prøver man ovenstående, går det med stor sandsynlighed galt.
For elementet med id="mit_link" eksisterer først når dokumentet er
loadet, mens udførelsen af js ikke venter på at det sker. Så variablen
linket vil sandsynligvis være 'undefined' eller noget andet, man ikke
kan bruge til noget, og man vil få fejlmeddelelse(r) - og klik på
linket, vil ikke udføre den handling man ønsker.
Løsningen er, at tildele event-handleren i en onload på window (eller
body).
Den bør man så også tildele unobtrusive - ellers er der ikke rigtig
nogen mening med alle krumspringene. Altså

window.attachEventListener('load', InitDokument);

function InitDokument() {
var linket = document.getElementById('mit_link');
linket.addEventListener('click', goer_noget); //kun browsere og IE9
}

function goer_noget() {
// gør noget!
}

Forskellen på ovenstående og det tidligere eksempel, er at jeg i
eksemplet bruger en js funktion (SetEvent) til at tildele
eventhandlerne.
Det skyldes, at i IE<9 hedder den metode der tildeler eventhandlere til
elementerne (objekterne) noget andet. Og det bliver for uoverskueligt,
at skulle teste for det, hver gang der skal tildeles. Derfor funktionen
SetEvent() i det tidligere eksempel. Den kalder blot den rigtige
(browserafhængige) metode, for det element der angives i parametrene.

function SetEvent(elm, evt, fnc) { // sætter event handlere på
elementer
if (elm) {
if (elm.addEventListener) { // for rigtige browsere
elm.addEventListener(evt, fnc, false);
}
else if (elm.attachEvent) { // for IE
elm.attachEvent('on'+evt, fnc);
}
}
}


Håber så det kaster lidt mere lys, og måske også lidt mere forståelse,
hvorfor det er en god idé at gøre tingene unobtrusive.
Ellers må jeg se om jeg kan finde en større fakkel. :D

Philip Nunnegaard

unread,
May 2, 2012, 3:54:40 PM5/2/12
to
Birger Sørensen skrev:

> Håber så det kaster lidt mere lys, og måske også lidt mere forståelse,
> hvorfor det er en god idé at gøre tingene unobtrusive.
> Ellers må jeg se om jeg kan finde en større fakkel. :D

Tror sgu stadig at jeg bliver nødt til at vente de 5-10 år, der går før
der kommer noget ordentligt letforståeligt stof på markedet.

Prøvede lige ovenstående, og det virker ikke.

http://www.hitsurf.dk/unobtrusivetest

Ved klik på linket skulle der gerne stå "success" på næste linje.


--
Philip

Birger Sørensen

unread,
May 2, 2012, 6:50:26 PM5/2/12
to
Følgende er skrevet af Philip Nunnegaard:
To ting - mindst. ^^
Den første er min fejl:
window.attachEventListener('load', InitDokument);
skal være
window.addEventListener('load', InitDokument);
- og det giver faktisk en fejl i Firebug.

Den anden er, at et link er nok ikke et godt eksempel - det vil faktisk
reloade siden, hvis ikke default funktionaliteten fjernes, så dit
eksempel vil heller ikke virke med inline. Prøv f.eks. med en div i
stedet.

I funktionen goer_noget, skal du nok også bruge innerHTML i stedet for
value - en div har ingen value...

Funktionen SetEvent er overflødig i dit script - den kaldes ikke. Jeg
undgik den i "den pædagogiske gennemgang", fordi den ikke har noget med
det egentlige unobtusive at gøre - den er et hjælpemiddel for IE<8. Så
dit forsøg vil kun virke i rigtige browsere eller IE9.

Birger Sørensen

unread,
May 2, 2012, 7:14:04 PM5/2/12
to
Philip Nunnegaard skrev:
http://bbsorensen.com/test/js/unobtrusive.html
Har implementeret SetEvent, så også det skal virke i M$'s forsøg på at
lave browsere.
Har ændret linket til en div.

Stig Johansen

unread,
May 3, 2012, 2:25:29 AM5/3/12
to
Birger Sørensen wrote:

> function SetEvent(elm, evt, fnc) { // sætter event handlere på
> elementer
> if (elm) {
> if (elm.addEventListener) { // for rigtige browsere
> elm.addEventListener(evt, fnc, false);
> }
> else if (elm.attachEvent) { // for IE
> elm.attachEvent('on'+evt, fnc);

Du - Birger. mangler du ikke lige den 3. del af browserne?

Se f.eks:
function addEvents (eventobject,eventtype,eventfunction) {
if ( eventobject.addEventListener ) {
eventobject.addEventListener (eventtype,eventfunction,false) ;
} else if( eventobject.attachEvent ) {
eventobject.attachEvent ('on'+eventtype,eventfunction) ;
} else {
eventobject['on' + eventtype] = eventfunction ;
}
}

--
Med venlig hilsen
Stig Johansen

Stig Johansen

unread,
May 3, 2012, 2:30:40 AM5/3/12
to
Philip Nunnegaard wrote:

> Præcis. Det er så sort snak for mig, at jeg ikke en gang kan forklare
> hvad jeg ikke forstår.
>
> Altså kort sagt:
>
> Hvordan laver jeg præcis dette:
>
> <a href="" onclick="goer_noget()">Linktekst</a>
>
> Jeg er med så langt som at man skal skrive <a href=""
> class="noget">Linktekst</a>
>
> Men derfra til at kæde en funktion sammen med class="noget" er jeg
> hægtet helt af.
>
> Derfor venter jeg bare på at der kommer en pædagogisk tutorial på nettet
> eller en lærebog som er nem at forstå.
>
> Indtil da vil jeg fortsætte med lave det inline.

Philip.

Performancewise skal du helst ikke bruge class da det er noget skrammel at
bruge til f.eks JS:

Class kræver traversing af DOM træet, hvorimod ID er lavet til en single
lookup.

Hvis du lover at lave/offentliggøre en lærebog, står jeg gerne til
disposition med lidt 'hardcore' viden.

Men at skrive forklaringer her på usenet, og Dennis, der finder 'ubrugelige
ting' på nettet gider jeg ikke at bruge tid på.

Stig Johansen

unread,
May 3, 2012, 2:36:03 AM5/3/12
to
Dennis Munding wrote:

> Hej gruppe
>
>
> Jeg har i datalogi fået til opgave at implementere en app lavet til
> android, på en hjemmeside med alle de udvidelser jeg selv har lavet.
> En af disse er lyd ved klik på en knap.

Dennis,
En af de ting du skal fortælle din 'klasselærer' er, at et eller andet firma
udtog patent på 'automagisk' afspilning af lyd (m.v.)

Det har givet en masse problemer, hvor alle browserleverandører måtte lave
'sidespring' - især aktivering vha. javascript.

MS lavede et forlig, og købte vist en 'licens', så MS har lovlig ret til
automatisk aktivering.

'Open source' communitiet er ligeglade, da der ikke kan hentes penge ved
sagsanlæg, så muligvis virker det i disse miljøer.


Google er blevet en så stor parameter, så jeg vil gætte på at selv William
(aka Bill) ikke tør spille hardball med dem.

Anders Wegge Keller

unread,
May 3, 2012, 2:37:59 AM5/3/12
to
Stig Johansen <wop...@gmail.com> writes:

...

> Du - Birger. mangler du ikke lige den 3. del af browserne?

...


> } else {
> eventobject['on' + eventtype] = eventfunction ;
> }

Hvor mange browsere er det lige, der ender her? Ikke at jeg er uenig
i at den skal med som fall-back, men du skal helt tilbage til
MSIE5/Mac, efter hvad jeg har læst mig til, før denne gren bliver
relevant.

Og så bør du også overveje hvad der sker, hvis der kommer to
eventhandlere til:

} else {
/* Stone age */
if (typeof elm['on' + evt] != 'function') {
elm['on' + evt] = func;
} else {
var oldfunc = elm['on' + evt];
elm['on' + evt] = function () {
oldfunc();
func();
}
}
}

Ovenstående er sakset fra min egen kode, så navnene matcher ikke det
citerede eksempel, men det skulle være til at gennemskue ideen.



--
/Wegge

Leder efter redundant peering af dk.*,linux.debian.*

Anders Wegge Keller

unread,
May 3, 2012, 3:12:33 AM5/3/12
to
Stig Johansen <wop...@gmail.com> writes:

> Performancewise skal du helst ikke bruge class da det er noget skrammel at
> bruge til f.eks JS:
>
> Class kræver traversing af DOM træet, hvorimod ID er lavet til en single
> lookup.

Ikke nødvendigvis. Det bliver godt nok temmeligt hardcore, men i
korte træk:

- Tilføj det event du vil fange på niveauet *over* de elementer der
er interessante, og sæt capture til true.

- I eventhandleren undersøger du om det element der reagerede har den
rigtige klasse.

- Hvis det har, afbryder du eventets videre udbredelse, og gør hvad
du nu har behov for.

Ovenstående virker ikke i gamle IE-udgaver (dem uden
AddEventListener), så der skal stadig kodes en fall-back med DOM
traversering. Men det er stadigvæk noget der i de fleste tilfælde vil
gøre tingene noget simplere.

Der er en noget bedre forklaring end den jeg er i stand til at give
her: http://www.howtocreate.co.uk/tutorials/javascript/domevents

Og google lader også til at give nogle fornuftige hits, hvis du søger
efter "DOM event capture".

Stig Johansen

unread,
May 3, 2012, 4:59:01 AM5/3/12
to
Anders Wegge Keller wrote:

> Stig Johansen <wop...@gmail.com> writes:
>
> ...
>
>> Du - Birger. mangler du ikke lige den 3. del af browserne?
>
> ...
>
>
>> } else {
>> eventobject['on' + eventtype] = eventfunction ;
>> }
>
> Hvor mange browsere er det lige, der ender her? Ikke at jeg er uenig
> i at den skal med som fall-back, men du skal helt tilbage til
> MSIE5/Mac, efter hvad jeg har læst mig til, før denne gren bliver
> relevant.

Ved det ikke Wegge, men det er mit indtryk at der kommer mange 'gadgets'
til, som ikke har gennemførte browsere.

> Og så bør du også overveje hvad der sker, hvis der kommer to
> eventhandlere til:

Jo den erstatter selvfølgelig default eventhandler, men

>
> } else {
> /* Stone age */
> if (typeof elm['on' + evt] != 'function') {
> elm['on' + evt] = func;
> } else {
> var oldfunc = elm['on' + evt];
> elm['on' + evt] = function () {
> oldfunc();
> func();
> }
> }
> }
>
> Ovenstående er sakset fra min egen kode, så navnene matcher ikke det
> citerede eksempel, men det skulle være til at gennemskue ideen.

Så skal man selvfølgelig have en detach eventhandler med i en afslutning.

Stig Johansen

unread,
May 3, 2012, 5:03:06 AM5/3/12
to
Anders Wegge Keller wrote:

> Stig Johansen <wop...@gmail.com> writes:
>
>> Performancewise skal du helst ikke bruge class da det er noget skrammel
>> at bruge til f.eks JS:
>>
>> Class kræver traversing af DOM træet, hvorimod ID er lavet til en single
>> lookup.
>
> Ikke nødvendigvis. Det bliver godt nok temmeligt hardcore, men i
> korte træk:

Enig (i hardcore), men jeg tror vi snakker forbi hinanden.

Laver man unobtrusive JS, er der kun få måder at finde (og tildele events)
elementer.

1) getElementById = direkte opslag
2) getElementsByTagName (IIRC) = traversing af DOM træet.

Bruger man class="noget" kan man kun finde elementet ved at traverse hele
DOM træet eller et subset jfr. 2)

Stig Johansen

unread,
May 3, 2012, 5:13:49 AM5/3/12
to
Anders Wegge Keller wrote:

> - I eventhandleren undersøger du om det element der reagerede har den
> rigtige klasse.
>
> - Hvis det har, afbryder du eventets videre udbredelse, og gør hvad
> du nu har behov for.

Jeg er ikke helt med på hvad du mener, men er det noget i denne stil som jeg
har brugt i mit Notes projekt:
----------------------------
function quickview_down(ev) {
var e = ev || window.event ;
if (!e.ctrlKey) return false ;
inmove = true ;

e.cancelBubble = true;
if (e.stopPropagation) e.stopPropagation();

// Now prevent any default action.
if (e.preventDefault) e.preventDefault(); // DOM Level 2
else e.returnValue = false; // IE

if(e.pageX || e.pageY){
moffsetX = e.pageX ;
moffsetY = e.pageY ;
} else {
moffsetX = e.clientX ;
moffsetY = e.clientY ;
}

qoffsetX = parseInt(qdiv_glob.style.left) ;
qoffsetY = parseInt(qdiv_glob.style.top) ;
qdiv_glob.style.cursor='-moz-grab';
return false ;
}
----------------------------------

Birger Sørensen

unread,
May 3, 2012, 5:43:45 AM5/3/12
to
Følgende er skrevet af Stig Johansen:
Et stykke tid endnu. Men der er hjælp på vej:
https://developer.mozilla.org/en/DOM/document.getElementsByClassName

Anders Wegge Keller

unread,
May 3, 2012, 6:28:34 AM5/3/12
to
Stig Johansen <wop...@gmail.com> writes:

> Anders Wegge Keller wrote:
>
> > Stig Johansen <wop...@gmail.com> writes:
> >
> >> Performancewise skal du helst ikke bruge class da det er noget skrammel
> >> at bruge til f.eks JS:
> >>
> >> Class kræver traversing af DOM træet, hvorimod ID er lavet til en single
> >> lookup.
> >
> > Ikke nødvendigvis. Det bliver godt nok temmeligt hardcore, men i
> > korte træk:
>
> Enig (i hardcore), men jeg tror vi snakker forbi hinanden.

Jeg tror ikke jeg har forklaret mig godt nok :(

> Laver man unobtrusive JS, er der kun få måder at finde (og tildele events)
> elementer.

> 1) getElementById = direkte opslag
> 2) getElementsByTagName (IIRC) = traversing af DOM træet.

Om man hæfter eventhandleren direkte på elementet, eller om man
fanger eventet på et højere niveau giver det samme resultat - i det
mindste når browseren implementerer en nogenlunde fornuftig event
propagation.

> Bruger man class="noget" kan man kun finde elementet ved at traverse
> hele DOM træet eller et subset jfr. 2)

Pointen i event propagation er at man slet ikke behøver traverse
noget, men kan vente til det enkelte event kommer.

Anders Wegge Keller

unread,
May 3, 2012, 6:31:31 AM5/3/12
to
Stig Johansen <wop...@gmail.com> writes:

> Anders Wegge Keller wrote:
>
> > - I eventhandleren undersøger du om det element der reagerede har den
> > rigtige klasse.
> >
> > - Hvis det har, afbryder du eventets videre udbredelse, og gør hvad
> > du nu har behov for.
>
> Jeg er ikke helt med på hvad du mener, men er det noget i denne stil som jeg
> har brugt i mit Notes projekt:

<snip>

Ja, det rammer meget præcist det jeg prøvede at forklare.

Philip Nunnegaard

unread,
May 3, 2012, 10:59:23 AM5/3/12
to
Birger Sørensen skrev:

> http://bbsorensen.com/test/js/unobtrusive.html
> Har implementeret SetEvent, så også det skal virke i M$'s forsøg på at
> lave browsere.
> Har ændret linket til en div.

Nu begynder det så småt at hjælpe. Tilføjede lige en tredje ting for at
sikre mig at jeg forstod bare lidt af det.

Tit ved man dog ikke på forhånd hvor mange af den slags der ender med at
være på den side som er genereret serverside for slutbrugeren.

I det fald må man nok generere js-koden serverside, så der er en
funktion til hver af alle de id'er, som der nu ender med at være på siden.
Men måske kan det klares med et array på en eller anden måde.

På Facebook er der fx en masse kommentarfelter ned ad siden.

På mine sider ville det typisk være en masse felter til redigering, hvor
indholdet (typisk et tal) opdateres i det øjeblik man forlader feltet.
Det er så det jeg i dag har lavet ved et inline-kald til en funktion på
eventen onchange.

--
Philip

Anders Wegge Keller

unread,
May 3, 2012, 11:23:58 AM5/3/12
to
Philip Nunnegaard <nunne...@hitsurf.dk> writes:

> Tit ved man dog ikke på forhånd hvor mange af den slags der ender med
> at være på den side som er genereret serverside for slutbrugeren.

Skal det være en unik funktion for hver enkelt link, eller hvad det
nu er for et element du skal manipulere med.

Har du egentlig postet noget eksempel kode? Jeg har været lidt
ophængt de sidste par dage, så jeg kan sagtens have overset det.

Philip Nunnegaard

unread,
May 3, 2012, 12:24:16 PM5/3/12
to
Den 03-05-2012 17:23, Anders Wegge Keller skrev:

> Skal det være en unik funktion for hver enkelt link, eller hvad det
> nu er for et element du skal manipulere med.

Nej. Det er samme funktion på hvert felt. Den skal dog regne med
forskellige tal alt efter hvad man nu måtte indtaste i felterne.

> Har du egentlig postet noget eksempel kode? Jeg har været lidt
> ophængt de sidste par dage, så jeg kan sagtens have overset det.

Jeg postede noget eksempelkode som Birger bryggede videre på. Den er her:
http://www.hitsurf.dk/unobtrusivetest

Men et eksempel på det jeg nævnte i mit sidste indlæg kan ses her:

http://www.hitsurf.dk/unobtrusivetest/anden_test.php

I eksemplet er der 3 titler, men hos andre brugere kan der være 26
titler eller 120 for den sags skyld.

--
Philip

Anders Wegge Keller

unread,
May 3, 2012, 6:08:25 PM5/3/12
to
Philip Nunnegaard <nunne...@hitsurf.dk> writes:

> Men et eksempel på det jeg nævnte i mit sidste indlæg kan ses her:
>
> http://www.hitsurf.dk/unobtrusivetest/anden_test.php

> I eksemplet er der 3 titler, men hos andre brugere kan der være 26
> titler eller 120 for den sags skyld.

Kan sangens unikke id (Det firecifrede tal) komme med som id på hver
tr?

Birger Sørensen

unread,
May 3, 2012, 7:41:07 PM5/3/12
to
Philip Nunnegaard forklarede den 5/3/2012:

> http://www.hitsurf.dk/unobtrusivetest/anden_test.php

Kan gøres f.eks. sådan - lidt afhængigt af hvad du ellers har brug
for...
http://bbsorensen.com/test/js/sang.html

Philip Nunnegaard

unread,
May 5, 2012, 12:29:08 AM5/5/12
to
Birger Sørensen skrev:

> Kan gøres f.eks. sådan - lidt afhængigt af hvad du ellers har brug for...
> http://bbsorensen.com/test/js/sang.html

Takker. Jeg er ikke lige ved min computer det næste døgns tid, men vil
kigge på det i morgen og se om jeg kan gennemskue koden.

--
Philip

Stig Johansen

unread,
May 8, 2012, 3:53:04 AM5/8/12
to
Anders Wegge Keller wrote:

>> Bruger man class="noget" kan man kun finde elementet ved at traverse
>> hele DOM træet eller et subset jfr. 2)
>
> Pointen i event propagation er at man slet ikke behøver traverse
> noget, men kan vente til det enkelte event kommer.

Nu skal vi ikke vade i det, men jeg snakkede om at attache en event(deraf
traversing) til et givent objekt, ikke triggeren af eventen.

Philip Nunnegaard

unread,
May 9, 2012, 3:41:03 PM5/9/12
to
Birger Sørensen skrev:

>> Kan gøres f.eks. sådan - lidt afhængigt af hvad du ellers har brug for...
>> http://bbsorensen.com/test/js/sang.html

Philip Nunnegaard skrev:

> Takker. Jeg er ikke lige ved min computer det næste døgns tid, men vil
> kigge på det i morgen og se om jeg kan gennemskue koden.

Og nu har jeg kigget og studeret koden.
Joda! Jeg forstår nogenlunde hvad der sker i de linjer som er tilføjet.
Men omsætte det til selv at lave nye funktioner? Der er desværre lang vej.

Muligvis er det nemt når man har rutinen. Men endnu har jeg bare ikke
set lyset. :-(

--
Philip

Birger Sørensen

unread,
May 10, 2012, 4:04:05 AM5/10/12
to
Efter mange tanker skrev Philip Nunnegaard:
Det handler lige så meget om fantasi, som det handler om rutine.

Når man skal sætte en ny side op, skal man have en forestilling - gerne
meget konkret, som skitser eller tegnigner e.l. - for ikke at ende med
at blive begrænset af hvad HTML elementerne kan bruges til.
På samme måde med funktionaliteten på siden. "Når jeg klikker her, skal
der ske sådan og såden..."

Det kan så godt være, at der skal noget rutine - viden og erfaring -
til at omsætte fantasien til noget virkeligt.
Man kan lære at tænke "ud af boksen" - og der er rigtig mange steder at
få den nødvendige viden.
Men der er kun een måde at få rutinen på.

Alle lange rejser bliver foretaget med eet skridt ad gangen. Nogen
gange meget små skridt.
Det eneste der er sikkert er, at hvis man står stille og overbeviser
sig selv om at "det kan jeg ikke" - så kommer man heller ingen vegne!


I det aktuelle eksempel, er forskellen på din "indlejerede" version og
min unobtrusive, at sangenes nummer (som jeg går ud fra, er unikt -
ellers går det galt) bliver brugt til at give id til de elementer, der
har med nummeret at gøre.
Det er generelt en god idé med id på elementer, der skal bruges i js -
men det er også generelt en god idé, at det id angiver en eller anden
form for sammenhæng med de oprindleige data, hvis det er muligt (og
hvis der er een).
I js'en har jeg skilt den kode der genererer XMLHttpReguest objektet
ud, til at være en selvstændig funktion. Egentlig mest fordi jeg kunne
se du brugte samme kode flere steder. Søgefunktionen var een af dem -
den røg så ud fordi den ikke bliver brugt på denne eksempelside. Men
det illustrerer muligheden for genbrug af kode; der er ingen grund til
at have samme kode flere gange.

Den største hurdle ved unobtusive, er somme tider, at det ikke
umiddelbart er muligt at bruge parametre. I det aktuelle eksempel, har
jeg simplificeret tingene lidt, og bruger i virkeligheden kun een -
sangens nummer, som nu er indbygget i elementets id.
Eventen overføres altid, og kan bruges til at finde det element der har
startet funktionen, når der er tale om en eventhandler. Det er den
variabel jeg har kaldt click_elm:
click_elm = (window.event) ? window.event.srcElement :
evt.originalTarget;
Jo - det er også et af de steder M$ partout vil være anderledes.
window.event findes kun i IE; hvis den gør er click_elm =
window.event.srcElement, og hvis ikke er den evt.originalTarget - hvor
evt er eventen som den overføres i rigtige browsere (her skal IE
muligvis læses IE<9).
Når jeg nu har elementet, kan jeg finde id'et - som jeg splitter på
understregningen, og anden del af det er den aktuelle sangs nummer.

De øvrige parametre i din "inline" eventhandler, er teksten "Vent" og
det element der skal bringe svaret fra serverside behandlingen.
Teksten er i alle tilfælde den samme, så det er ikke nødvendigt at have
den som parameter.
Og svar-elementet, kan identificeres med dets id. Så ingen af
parametrene er i virkeligheden nødvendige - ikke i denne demoversion i
hvert fald.
Min demoversion af gemdata.php ser sådan ud:
<?php
$id = utf8_decode($_GET['sang']);
$pt = utf8_decode($_GET['point']);
echo utf8_encode($id.'|'.$pt);
?>
Den returnerer altså blot sangens nummer og det tildelte pointtal
adskilt med en | karakter.
I den js der behandler svaret, splittes dette svar igen til et array,
med karakteren |
Det første element er altså sang-nummer, som anvendes til at finde det
element der skal bringe svaret, og det andet er svaret selv. Så det er
sådan set bare at sætte teksten ind i elementet...

Det er klart, at der kun er tale om en demo.
Og tanken var sådan set kun at demonstrere, at det kan lade sig gøre
unobtrusive - og måske give lidt idéer til, hvordan man kan omgå de
begrænsninger man løbr ind i.
I modsætning til almindelige puslespil, er der ofte mere end een
løsning på samme problem - og ingen der kan bestemme om den ene er mere
rigtig end den anden. Så det handler om at have fantasi til at
forestille sig bare een af dem, så har man løst problemet.
Der er formentlig så andre "problemer" på samme side, så en løsning
skal tage hensyn til andre problemstillinger også. Men "små skridt",
kan også anvendes til at kombinere forskellige løsninger.
Så der er ikke andet at gøre, end at klø på og eksperimentere...

Og bliver det helt mørkt, kan du godt låne en tændstik til
stearinglyset her. ^^

Dennis Munding

unread,
May 12, 2012, 2:26:54 AM5/12/12
to
Hej Birger - beklager den lange svartid (kommende eksamener tager min tid).

"Birger Sørensen" skrev:
> Dennis Munding forklarede:
>> Hej Philip,
>>
>> "Philip Nunnegaard" skrev:
>>
>>> Dennis Munding skrev:
>>>
>>>> Unobstrive - et ord jeg ikke forstår betydningen af i denne
>>>> sammenhæng...??
>>>
>>> Princippet skulle være at undgå at kalde javascripts i html-koden og i
>>> stedet have det hele i den eksterne javascript-fil - ligesom med css.
>>>
>>> Selv finder jeg stoffet omkring unobtrusive javascript (eller diskret
>>> javascript om man vil) for langhåret. Måske kommer der en dag en
>>> tutorial om det som er tilpas pædagogisk og unørdet.
>>
>> Mange tak for den pædagogiske forklaring, som giver meget mere mening.
>> :-)
>
> Det er lidt en del af "moderne tænkning": Et site består af tre dele;
> indhold (HTML), formattering (CSS) og funktionalitet (scripting).
> For at overholde dette, er man nødt til at fjerne scripting fra HTML'en.
> Det giver så også nogle andre fordele - man kan sætte flere event-handlere
> på samme element, og man kan også fjerne dem eller ændre hvilken der skal
> anvendes, afhængig af andre ting.

Det giver mening og er for mig en logisk metode. :-)

> Og det er forholdsvis enkelt - selvom det er lidt mere besværligt, end at
> skrive det i HTML.
> Først skal man tænke på, at dokumentet ikke findes, før det er hentet fra
> serveren, og at de enkelte elementer, ikke eksisterer før dokumentet er
> hentet. Man er derfor nødt til at tildele event-handlere, i window's
> onload event handler. (Window eksisterer, når browseren er åben - derfor
> kan der tildlelen en event handler til window, før dokumentet er hentet.
> Mener godt man kan bruge body og måske også document også, men er ikke
> sikker).
> Selve tildelingen sker med DOM funktioner. Uheldigvis er M$ anderledes på
> det punkt. Jeg bruger en funktion til det; i det følgende kaldet
> SetEvent(). Den har tre parametre: elementet eventhandleren skal sættes
> for, hvilken event der er tale om, og hvilken funktion der skal kaldes.
>
> Et eksempel der tildeler en event-handler til et klik på et billede der
> har id="mit_billede", kan se sådan ud:
>
> SetEvent(window, 'click', InitDokument);
>
> function SetEvent(elm, evt, fnc) { // sætter event handlere på elementer
> if (elm) {
> if (elm.addEventListener) { // for rigtige browsere
> elm.addEventListener(evt, fnc, false);
> }
> else if (elm.attachEvent) { // for IE
> elm.attachEvent('on'+evt, fnc);
> }
> }
> }
>
> function InitDokument() {
> var elm = document.getElementById('mit_billede');
> if (elm) {
> SetEvent(elm, 'click', MinKlikHandler);
> }
> }
>
> function MinKlikHandler() {
> alert('Du klikkede på billedet');
> }

Jeg har nu fået "musikken" til at spille (IE vil dog kun være med fra
version 9), og jeg har tilladt mig at kopiere og tilpasse dit eksempel
herover - med succes.
Tilbage sidder jeg så blot og tænker: Det kommer jo til at fylde temmelig
meget når man som jeg, har en del kald til forskellige funktioner i
"onclick"...
Eller er det muligt at ligge alle disse kald ind i et array, som så løbes
igennem i ovenstående kode?

> Og det skulle nogenlunde demonstrere teknikken.
> Bemærk at funktionen der angives til SetEvent (eller hvis du selv vil
> skrive en rutine til det, DOM-funktionerne addEventListener() i rigtige
> browsere og attachEvent() i IE), er en pointer til funktionen - altså
> funktionsnavnet uden paranteser - og at man ikke kan overføre parametre
> (andre end eventen selv - det gøres automatisk i rigtige browsere, i IE
> skal man bruge window.event).
> Skal man bruge eventen - altså det der aktiverede eventhandleren - skal
> man have den med som parameter i eventhandler funktionen, som f.eks.:
> function MinKlikHandler(evt) { ... }
>
> Håber det hjælper lidt på forståelsen.

Det hjælper på det efterhånden - kunne blot ønske at det var min faglærer,
der var kommet med den løsning... :-/


Med venlig hilsen
--
Dennis Munding
a.k.a. The Eye - Member of the PosseGrim Squad
http://pgsquad.com/
"When you hear the wind - you're already dead..."

Birger Sørensen

unread,
May 12, 2012, 5:23:23 AM5/12/12
to
Efter mange tanker skrev Dennis Munding:
> Hej Birger - beklager den lange svartid (kommende eksamener tager min tid).

Det er helt fint. :D

8X
>> Det er lidt en del af "moderne tænkning": Et site består af tre dele;
>> indhold (HTML), formattering (CSS) og funktionalitet (scripting).
>> For at overholde dette, er man nødt til at fjerne scripting fra HTML'en.
>> Det giver så også nogle andre fordele - man kan sætte flere event-handlere
>> på samme element, og man kan også fjerne dem eller ændre hvilken der skal
>> anvendes, afhængig af andre ting.
>
> Det giver mening og er for mig en logisk metode. :-)

Ved ikke om jeg vil kalde det en "metode". Det er en godt begrundelse
for at skrive unobtrusive. Det bliver ofte mistolket, som at være for
at fjerne js'en fra HTML'en, men det er altså kun en del af det - det
vigtigste er i virkeligheden, at bruge objekterne som de er beregnet
til, så man kan udnytte muligheden for at have flere kald på samme
event, og kunne tilføje/fjerne eventhandlere som man har brug for.

8X
> Jeg har nu fået "musikken" til at spille (IE vil dog kun være med fra version
> 9), og jeg har tilladt mig at kopiere og tilpasse dit eksempel herover - med
> succes.
> Tilbage sidder jeg så blot og tænker: Det kommer jo til at fylde temmelig
> meget når man som jeg, har en del kald til forskellige funktioner i
> "onclick"...
> Eller er det muligt at ligge alle disse kald ind i et array, som så løbes
> igennem i ovenstående kode?

Det kan vel godt lade sig gøre.
Det kommer an på hvordan elementerne findes/identificeres i js'en, og
om der skal bruges samme eventhandler.
I eksemplet fra Philip f.eks. - som jeg tror et afstemningssystem til
sange - tildeles konsekvent samme eventhandler til alle <input>.
(http://bbsorensen.com/test/js/sang.html koden står i html filen for
demoens skyld)
Man kan forestille sig at der er et eller flere, der ikke skal have
eventhandler, eller evt. en anden.
Man må så finde alternative metoder - det kunne f.eks. være at bruge
id'et også, noget i retning af

function InitSange() {
var idx = 0, inp = null;
var inps = document.getElementsByTagName('INPUT');
if (inps && (inps.length > 0)) {
for (idx = 0; idx < inps.length; idx++) {
inp = inps[idx];
if (inp.id.indexOf('sang_') > -1) {
SetEvent(inp, 'change', kaldAHAH);
}
}
}
}

Her vil alle input element hvis id endholder stengen sang_ få tildelt
eventhandleren. Så når der tilføjes søgefelt, eller anden
funktionalitet der involvere inputs, vil disse ikke få tildelt
eventhandleren (hvis man sørger for at de ikke har id'er der kan
forveksles!)
Der er mange måder at gennemgå (eller traversere eller iterere over -
kært barn har mange navne) HTML'en.
Og det handler vel i virkeligheden om at kende de muligheder der
findes, for at identificere elementerne.
Ideen med et array, er måske god. Den vil også have en ulempe med
umiddelbart at være mindre overrskuelig. Så det vil nok afhænge af det
aktuelle tilfælde, om hvordan man nemmest og mest overskueligt, finder
de elementer der skal have tildelt eventhandler.


Til din nuværende kode, vil jeg kommentere, at det er formentlig
<audio> tagget, der driller i IE<9 - det er en HTML5 ting, og de aner
formentlig ikke hvad det er...
(Hvis du vil have de øvrige IE'ere med, skal du nok over i noget med
<object> - har ingen erfaring med at lægge lyd på...)
Og endelig, så tilføjer du et <audio> tag til HTML'en, hver gang der
rulles med terningerne, og det er ikke rigtig optimalt. Der må være en
måde at starte en afspilning en enkelt gang, så tagget kan flyttes til
html, og der blot afspilles, når terningerne trilles (Scootergrisen har
vist eksempler på det på sine sider om HTML5 - kan ikke lige huske et
link).
Og ellers bør du fjerne det igen, inden du sætter et nyt ind.
Hvis vi skal være strikse og have adskillelse mellem indhold og
funktionalitet (HTML og scripting), er det ikke så godt, at scriptingen
sætter elementer ind i HTML'en. Det er på sin vis lige så galt som at
have inline js i HTML'en - omend den modsatte vej.

8X
> Det hjælper på det efterhånden - kunne blot ønske at det var min faglærer,
> der var kommet med den løsning... :-/

Det er vi enige om!

Birger Sørensen

unread,
May 12, 2012, 5:40:11 AM5/12/12
to
Birger Sørensen frembragte:

8X

> Og endelig, så tilføjer du et <audio> tag til HTML'en, hver gang der rulles
> med terningerne, og det er ikke rigtig optimalt. Der må være en måde at
> starte en afspilning en enkelt gang, så tagget kan flyttes til html, og der
> blot afspilles, når terningerne trilles (Scootergrisen har vist eksempler på
> det på sine sider om HTML5 - kan ikke lige huske et link).
> Og ellers bør du fjerne det igen, inden du sætter et nyt ind.
> Hvis vi skal være strikse og have adskillelse mellem indhold og
> funktionalitet (HTML og scripting), er det ikke så godt, at scriptingen
> sætter elementer ind i HTML'en. Det er på sin vis lige så galt som at have
> inline js i HTML'en - omend den modsatte vej.

Kunne ikke lige lade den fare....
Hvis du sætter dit tag ind i HTML'en

<audio id="player">
<source src='../sound/rolldice.ogg' type='audio/ogg' />
<source src='../sound/rolldice.mp3' type='audio/mpeg' />
</audio>
(ingen loop og ingen autoplay)

skal det kunne afspilles ved i js'en at skrive

elm = document.getElementById('player');
if (elm) { elm.play(); }

- Men det vil stadig ikke virke i de gamle IE.

http://www.catswhocode.com/blog/mastering-the-html5-audio-property
0 new messages