Avatar billede tipsen Nybegynder
10. august 2005 - 02:27 Der er 20 kommentarer og
1 løsning

Find nye billede dimensioner ved dynamisk udskiftning af billede

Hej eksperter

Jeg har en webside hvor der som start vises et bestemt billede fra en nærmere fastsat mappe under webroden. Det er muligt at vælge et andet billede i en drop-down boks, hvorefter det valgte billede hentes ind og vises i stedet for det oprindelige.

Da størrelsen af billederne har en betydning kunne jeg godt tænke mig, at jeg samtidig kunne opdatere to tekstfelter (span, div etc), hvor henholdvis højden og bredden af billedet kan angives.

Det var relativt nemt at få opdateret billedet udfra brugerens valg i drop-down boksen, men hvordan finder jeg det nye billedes dimensioner og fortæller disse til brugeren.

Jeg er mest interesseret i en cross-browser løsning og vil derfor helst undgå en browser-afhængig løsning.

På forhånd tak!

Mvh Tommy Ipsen
Avatar billede roenving Novice
10. august 2005 - 02:42 #1
F.eks. vedat udnytte onload på et img-tag:

<script language="javascript" type="text/javascript">
function showSize(pic){
  document.getElementById('bredde').innerHTML = document.billede.offsetWidth;
  document.getElementById('hojde').innerHTML = document.billede.offsetHeight;
}
</script>


Billedets dimensioner:<br>
Bredde: <span id="bredde"></span>&nbsp;px<br>
Højde: <span id="hojde"></span>&nbsp;px<br>
<input type="button" onclick="document.billede.src=document.billede.src.indexOf('billede.jpg')>-1?'../eksperten_logo_new.gif':'../billede.jpg'" value="Skift billede"><br>
<img name="billede" src="../eksperten_logo_new.gif" onload="showSize(this);">
Avatar billede roenving Novice
10. august 2005 - 02:43 #2
-- og funktionen kaldes jo fra tagget, så man kan ligesågodt tage den derfra:

function showSize(pic){
  document.getElementById('bredde').innerHTML = pic.offsetWidth;
  document.getElementById('hojde').innerHTML = pic.offsetHeight;
}
Avatar billede roenving Novice
10. august 2005 - 03:11 #3
-- og jeg brugte lige en button til at skifte billedet, men det skulle ingen trille spille !-)
Avatar billede tipsen Nybegynder
11. august 2005 - 17:42 #4
Næsten i orden, men der er et lille "delay-issue"...

Her er relevante uddrag af min nuværende kode:

<script type="text/Javascript" language="Javascript">
<!--
function ChangeStaffImage(ImageSource) {
    document.StaffImage.src = '/images/staff/'+ImageSource.value;
    waitforcomplete();
    //document.getElementById('StaffImgWidth').innerHTML = document.StaffImage.offsetWidth - 12;
    //document.getElementById('StaffImgHeight').innerHTML = document.StaffImage.offsetHeight -12;
}

function waitforcomplete() {
//:TODO: Der er et issue mht. at være bagud med at afrapportere billeddimensioner - forskel i FF og IE!
    if (document.StaffImage.complete) {
        document.getElementById('StaffImgWidth').innerHTML = document.StaffImage.offsetWidth - 12;
        document.getElementById('StaffImgHeight').innerHTML = document.StaffImage.offsetHeight -12;
    }
    else setTimeout("waitforcomplete();", 500);
}
//-->
</script>

Billedet der dynamisk skiftes:
<img class="staffpic" name="StaffImage" src="/images/staff/jas.jpg" title="Medarbejderbillede" alt="Medarbejderbillede" />

Select-elementet fra formularen, hvor billedet vælges:
<select name="imagesrc" onclick="ChangeStaffImage(this);" onkeyup="ChangeStaffImage(this);">
    <option value="abc.jpg">abc.jpg</option>
    <option value="def.jpg">def.jpg</option>
    <option value="ghi.jpg">ghi.jpg</option>
</select>

HTML-koden, hvor billededimensionerne indsættes:
(<span id="StaffImgWidth">110</span> &times; <span id="StaffImgHeight">150</span>px)

Sålænge billederne ikke er cachet i browseren, er der et issue med et lille delay indtil billedet er hentet fra serveren - dette betyder, at koden som aflæser billededimensionerne afvikles inden billedet er hentet fra serveren og dermed bliver det dimensionerne på det foregående billede der aflæses!! Efter at have kigget lidt rundt på nettet, fandt jeg frem til .complete-egenskaben, som er blevet indbygget i ovenstående. Ideen er at kigge på om billedet er hentet fra serveren og derefter aflæse højde og bredde og alternativt vente på at billedet bliver færdighentet. Selvom ideen så godt ud på den hjemmeside, hvor jeg fandt det, virker det ikke rigtigt i praksis...

Har du nogle forslag til, hvordan jeg kan omgå problemet med det lille delay indtil billedet er hentet - jeg kører det lokalt og ikke engang her bliver billedet hentet hurtigt nok!

NB: Årsagen til at jeg fratrækker 12 i dimensionerne er at jeg har indsat 2x6px margin/padding på det pågældende billede - det er en lille korrektion for dette.

Mvh Tommy
Avatar billede roenving Novice
11. august 2005 - 17:44 #5
Hvorfor bruger du ikke onload på billedet ?-)
Avatar billede tipsen Nybegynder
11. august 2005 - 18:05 #6
Tjahh - fordi jeg ikke tænkte over det :-)

Det ser ud til at fungere fint nu - den eneste lille ting jeg ikke er helt tilfreds med er den værdi (12) jeg manuelt må trække fra den aflæste værdi - det er padding og border der summerer til 12 - findes der evt. en anden egenskab end offsetWidth og -Height som kun giver selve billedets dimensioner og ikke img-taggets eller skal jeg bare lære at huske at opdateringer af mit style-sheet medfører ændringer af mit javascript?

Her er den kode jeg er endt op med - er der nogle "issues" jeg skal være opmærksom på eller er det ikke tæt på optimalt til denne problemstilling?

<script type="text/Javascript" language="Javascript">
<!--
function ChangeStaffImage(ImageSource) {
    document.StaffImage.src = '/images/staff/'+ImageSource.value;
}

function GetImgDims(img) {
    document.getElementById('StaffImgWidth').innerHTML = img.offsetWidth - 12;
    document.getElementById('StaffImgHeight').innerHTML = img.offsetHeight -12;
}
//-->
</script>

<img class="staffpic" onload="GetImgDims(this);" name="StaffImage" src="/images/staff/{$Employee.ImageSource}" title="Medarbejderbillede" alt="Medarbejderbillede" />

Select-elementet fra formularen, hvor billedet vælges:
<select name="imagesrc" onclick="ChangeStaffImage(this);" onkeyup="ChangeStaffImage(this);">
    <option value="abc.jpg">abc.jpg</option>
    <option value="def.jpg">def.jpg</option>
    <option value="ghi.jpg">ghi.jpg</option>
</select>

HTML-koden, hvor billededimensionerne indsættes:
(<span id="StaffImgWidth">110</span>&times;<span id="StaffImgHeight">150</span>px)

Mvh Tommy
Avatar billede roenving Novice
11. august 2005 - 18:12 #7
Du kan da aflæse værdierne, men kun hvis de er sat som inline styles eller er sat via noget script !-)

-- og så bliver linjen lidt vel lang, da værdierne jo indeholder enheder, som først må parses væk ...

-- så det er pest eller kolera: Vil du have din margin/padding i stylesheetet, skal du vedligeholde dit javascript også ved ændringer, vil du undlade at vedligeholde scriptet, skal du vedligeholde margin og padding på tagget !o]
Avatar billede tipsen Nybegynder
11. august 2005 - 18:29 #8
OK - tak skal du have roenving - giver du et svar, så jeg kan afslutte spørgsmålet?
Avatar billede roenving Novice
11. august 2005 - 18:35 #9
Velbekomme '-)
Avatar billede roenving Novice
11. august 2005 - 18:42 #10
-- og tak for point ;~}
Avatar billede tipsen Nybegynder
11. august 2005 - 19:08 #11
Der er åbenbart et lille issue med onload på et img-tag i XHTML - er der alternativer eller er det bare "tough luck", hvis jeg vil opnå det ønskede?
Avatar billede roenving Novice
11. august 2005 - 19:18 #12
Man kan jo være lidt fræk og først indsætte funktionen onload på dokumentet ...

-- for du vil jo i forvejen have udelukket xhtml, når du benytter dig af innerHTML !-)
Avatar billede tipsen Nybegynder
11. august 2005 - 19:21 #13
innerHTML udelukker XHTML?
Avatar billede roenving Novice
11. august 2005 - 19:29 #14
Jepz, under xhtml skal du bruge (i denne situation) .firstChild.nodeValue ...

Hvis du vil bruge javascript under xhtml er der en hel række ting fra javascript-DOM-binding, som skal tages slavisk alvorligt, bl.a. eksisterer innerX-tingene overhovedet ikke, ligesom de almindelige collections (images, frames, forms m.v. !-) heller ikke er tilgængelige ...

-- og er du pisket til at bruge en umoden teknologi, for xhtml er der jo endnu ikke een almindelig browser, som er i stand til at bruge, og slet ikke omkring hele den smarte ende af det, nemlig at man kan sætte xml-parseren til at køre sagen, hvilket alt andet lige vil være 100-vis gange hurtigere !o]

Læs oleboles artikler om dette:

http://www.eksperten.dk/artikler/537 og
http://www.eksperten.dk/artikler/538 !-)
Avatar billede olebole Juniormester
11. august 2005 - 20:55 #15
<ole>

- og grundet XHTML-DOM'en, har du heller ikke det samme document-object, som under HTML - hvilket betyder, du heller ikke kan anvende adresseringer som: document.StaffImage.src  :)

/mvh
</bole>
Avatar billede olebole Juniormester
11. august 2005 - 22:21 #16
Jeg har på fornemmelsen, der hersker en forvirring på området. De fleste opfatter fejlagtigt udtryk som:
document.images
document.getElementById
ELEMENT.innerHTML
ELEMENT.className

- er JavaScript, men det er det faktisk ikke. Det er DOM bindinger, fastlagt af W3C - ikke af ECMA, som vedligeholder den standard, JavaScript baserer sig på  ;o)

I begyndelsen - da JavaScript lige var frigivet af Netscape, som oprindelig lancerede sproget - var der lidt rod i begreberne. Der manglede generel, international standardisering indenfor webkodning, så mange strukturelle problemer var der endnu ikke taget stilling til.
Således indholdt den første JS-version således både et window- og et document-object. Selvom det har været deprecated siden, ser man af og til et levn fra den periode i form af udtryk som: 'document.location' - der jo retteligt hedder 'window.location'.

Ret hurtigt viste det sig dog at være formålstjenligt at beholde window-objektet i JavaScript - men henlægge document-objektet til den til markup-sproget hørende DOM.
På den måde kan man skifte disse DOM-script bindinger, når man skifter markup - og dermed DOM - uden at skulle skifte evt. JavaScript-version.

Det er den historiske/strukturelle forklaring på, du øjensynligt pludseligt skal til at ændre JavaScript-syntaks, når du overgår til XHTML. Det er dog ikke JS-syntaksen, som skal ændres - men blot de til XHTML hørende DOM bindinger, der skal bruges ... hvilket jo i princippet er ganske logisk  :)

De fleste af de, der skriver tutorials, aner ikke selv, hvad de forsøger at undervise i - og har ofte et skræmmende ringe kendskab til teorien bag de teknologier, de prøver at gøre sig kloge på.

Derfor har de fleste kodere desværre et yderst overfladisk og fejlfyldt kendskab til XHTML - og hvad teknologien kræver - og hvad brugen af den indebærer  :o|
- borer man lidt dybere i folks JS-forståelse, vil det som oftest vise sig, at de fleste begreber også flyder her.

Webtutorials var en okay måde at lære HTML på i begyndelsen af 90'erne - men idag er området tydeligvis blevet alt for kompliceret til, at man kan overlade udbredelsen af kendskabet om web-teknologier til tilfældige tutorial-forfattere.
De gode af slagsen kan tælles på en godt hærget maskinsnedker-hånd - og det virker, somom meget få læser dem  :o|
I dag er den eneste gode og sikre måde at tilegne sig viden om emnet (så vidt jeg kan se), at tage en god uddannelse og/eller holde sig velopdateret på W3C  ;o)
Avatar billede tipsen Nybegynder
12. august 2005 - 00:43 #17
Jeg takker for udredningen - jeg må erkende, at jeg er næsten helt blank hvad angår JS-delen - jeg søger for det meste at holde mig væk fra client-side scripting, men ind i mellem kan det øge brugervenligheden markant og så må man jo til det!

Jeg har generelt svært ved at finde ud af hvilke egenskaber og metoder DOM tilbyder for de forskellige HTML-versioner - er der noget sted jeg kan få en pæn og nem oversigt?
Avatar billede roenving Novice
12. august 2005 - 00:56 #18
Jeg har det selv sådan, at når jeg nu virkelig har brug for noget, så kaster jeg mig over syntaktiske udredninger, definitioner fra w3c, krydschecker med de seneste 3 udgaver af ecma-script-definitionen (eller var der kun to ?-), og så graver jeg resten frem ved at sammenligne resultatet af denne søgning med nogle af krinkel-krogene bag øjenbrynene (ja, nogle gange får jeg fat i den bag hvert øjenbryn !-)

-- de oversigter/definitioner, jeg er stødt ind i, er (hvis de er allerbedst) proprietære og dybt uoverskuelige (M$DN, som simpelthen er praktisk ubrugelig !-), og selv js-fædrenes vedligeholdelse lader en del tilbage at ønske, for det er jo ikke dem, som definerer bindings, det sker jo andre steder, og der vedligeholdes bindings ikke fra programmørens eller browser-producentens synspunkt ...

-- jeg må skuffe dig, for den nemme oversigt findes pr. definition ikke, men bare et sted, hvor der var en overskuelig info omkring brugen af javascript i de forskellige udgaver af Markup-Languages vil nok være en utopi, for det vil kræve voldsomt mange ressourcer at opbygge og en ret væsentlig mængde at vedligeholde, specielt, hvis den også skulle være egentlig tilgeængelig for den dedikerede amatør og den tilfældige professionelle !-)
Avatar billede olebole Juniormester
12. august 2005 - 01:50 #19
Her er en oversigt over W3C's DOM-specifikationer:
  http://www.w3.org/DOM/DOMTR

- klik f.eks. på '2. Document Object Model Level 2' - og gå dermed til:
  http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/

I bunden af denne side, finder du en TOC, hvor du klikker på 'Appendix E: ECMAScript Language Binding' - og går dermed til:
  http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/ecma-script-binding.html
Avatar billede olebole Juniormester
12. august 2005 - 01:54 #20
Avatar billede tipsen Nybegynder
13. august 2005 - 16:38 #21
Tak skal I have begge to - det er rart, at have lidt at komme videre med!
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester