01 november, 2008

Javascript: Ändra bakgrundsbild dynamiskt på en webbsida

Javascript är ett smidigt skriptspråk när man vill ändra saker på en webbsida. Eftersom allt som visas på sidan är objekt så kan man komma åt dessa och ändra egenskaperna via Javascript. Det vi ska göra nu är att ändra en bild dynamiskt till vad vi vill.

Varför vill man göra detta?
Tänk dig att du t.ex har en webbsida som använder en CSS stilmall för att sköta design och layout. På sidan finns följande div-tagg innanför <body>:

filnamn: index.html
<div id="pageHeader">Titel här</div>

som innehåller en bakgrundsbild med följande kod inkluderad i stilmallen:

filnamn: styles.css
#pageHeader {
background-image: url(/images/headers/bigblue.png);
}

Då har alla undersidor med det div-ID samma bakgrundsbild och det kan vara lite krångligt att ändra manuellt. Då kom jag på att man kan ange i koden för den aktuella webbsidan en sökväg till den bild man vill ha som bakgrundsbild som då används istället för originalbilden.

Detta är användbart i följande exempel: Du har t.ex en webbsida om ett populärt resmål men vill även ha en undersida som innehåller historia om resmålet. Då tycker du att det hade passat med en annan bild som visar hur området såg ut förr.

Hur Javascriptet fungerar
Skriptet fungerar som så att det söker igenom den aktuella webbsidan efter ett unikt ID som innehåller en sökväg till en bild som ska byta ut den som redan visas på sidan. Om inget ID hittas så lämnas originalet oförändrad.

Placera följande kod som inkluderar skriptet innan taggen :
<script type="text/javascript" src="changeheader.js"></script>

Här är koden för skriptet:

filnamn: changeheader.js

//
// cross browser getElementById()
// -- väldigt smidigt sätt men det finns andra implementeringar --
function getObject(id) {
var object = null;
if( document.layers ) {
object = document.layers[id];
} else if( document.all ) {
object = document.all[id];
} else if( document.getElementById ) {
object = document.getElementById(id);
}
return object;
}

/**
* En funktion för cross-browser kompatiblititet när vi lägger till
* events på sidan.
* Den stödjer endast javascript funktioner som har 'on'
* framför (t.ex onLoad).
*/
function addEvent(element, evType, func, useCapture)
{
// Firefox?
if (element.addEventListener)
{
element.addEventListener(evType, func, useCapture);
return true;
}
// Internet Explorer?
else if (element.attachEvent)
{
var ret = element.attachEvent("on"+evType, func);
return ret;
}
else
{
// Visa ett meddelande för besökaren att webbläsaren
// måste uppgraderas för att stödja javascript
// funktionalitetet fullt ut.
var msg = "Your webbrowser doesn't support the Javascript used on this page.\n";
msg += "Please upgrade to be able to use full functionality.\n\n";
msg += "//Staff";
alert(msg);
}
}

//
// Change the headerbackground image
// -- Här är den specifika koden som ändrar bakgrunden --
//
// Copyright &copy 2008 - Waschman
// License: Open Source
//
function changeHeader()
{
// The div-header
headerBox = getObject("headerBox");
// The div that contains the path
headerPlaceholder = getObject("dynamicHeaderImage");

// Did we fint the right object?
if (headerPlaceholder == null) {
/*alert("Skriptet vet inte vilken bild som ska användas som sidhuvud!\nVar vänlig kontakta support");*/
return false;
}

// Get the path
pathToImage = headerPlaceholder.innerHTML;

// uncomment to hide placeholder if no inline-css is used
//headerPlaceholder.style.display = "none";

// change image
headerBox.style.backgroundImage = "url("+ pathToImage +")";
}

//
// Body onload
// -- Denna kod kör funktionen “changeHeader” vid body onLoad --
addEvent(window, "load", changeHeader);

Så, det var koden och nu återstår bara att lägga in följande kodsnutt innanför <body> som aktiverar ändringen. Tänk på att bara lägga in denna kod på de sidor som du vill ska ha en specifik bakgrundsbild som "header".

filnamn: historia.html
<div id="dynamicHeaderImage" style="display: none">/images/headers/new_header_red.png</div>

Det är här ni anger vilken ny bild ni vill använda. För att se ett exempel kan ni ladda ner ett komprimerat zip-paket med några testfiler.


(Tillägg 25/7-09) Flytande ramar - IFrame
Om man vill kunna komma åt dynamicHeaderImage som är placerad i en iframe, från huvudsidan, kan man använda följande changeheader.js istället.

Varning!
Observera att koden inte riktigt fungerar som den ska. Allt fungerar förutom att man måste ladda om index sidan manuellt för att bakgrundsbilden ska visas. Detta för att changeHeader() körs vid body onload(). Om något vet hur man fixar detta så skriv gärna en kommentar.

Filnamn: changeheader.js
Beskrivning: Används endast för de som använder iframes. Inte testad med vanliga ramar.
//
// cross browser getElementById()
// -- väldigt smidigt sätt men det finns andra implementeringar --
function getObject(id) {
var object = null;
if( document.layers ) {
object = document.layers[id];
} else if( document.all ) {
object = document.all[id];
} else if( document.getElementById ) {
object = document.getElementById(id);
}
return object;
}

function getIframeObject(oIframe, id) {

var newIframe = getObject(oIframe);
var innerDoc = newIframe.contentDocument || newIframe.contentWindow.document;

if( innerDoc.layers ) {
object = innerDoc.layers[id];
} else if( innerDoc.all ) {
object = innerDoc.all[id];
} else if( innerDoc.getElementById ) {
object = innerDoc.getElementById(id);
}
return object;
}

/**
* En funktion för cross-browser kompatiblititet när vi lägger till
* events på sidan.
* Den stödjer endast javascript funktioner som har 'on'
* framför (t.ex onLoad).
*/
function addEvent(element, evType, func, useCapture)
{
// Firefox?
if (element.addEventListener)
{
element.addEventListener(evType, func, useCapture);
return true;
}
// Internet Explorer?
else if (element.attachEvent)
{
var ret = element.attachEvent("on"+evType, func);
return ret;
}
else
{
// Visa ett meddelande för besökaren att webbläsaren
// måste uppgraderas för att stödja javascript
// funktionalitetet fullt ut.
var msg = "Your webbrowser doesn't support the Javascript used on this page.\n";
msg += "Please upgrade to be able to use full functionality.\n\n";
msg += "//Staff";
alert(msg);
}
}

//
// Change the headerbackground image
// -- Här är den specifika koden som ändrar bakgrunden --
//
// Copyright © 2008 - Waschman
// License: Open Source
//
function changeHeader()
{
// The div-header
headerBox = getObject('headerBox');
// The div that contains the path
headerPlaceholder = getIframeObject('iframeContent', 'dynamicHeaderImage');

// Did we fint the right object?
if (headerPlaceholder == null) {
//alert("Skriptet vet inte vilken bild som ska användas som sidhuvud!\nVar vänlig kontakta support");
return false;
}

// Get the path
pathToImage = headerPlaceholder.innerHTML;

// uncomment to hide placeholder if no inline-css is used
//headerPlaceholder.style.display = "none";

// change image
headerBox.style.backgroundImage = "url("+ pathToImage +")";
}

//
// Body onload
// -- Denna kod kör funktionen “changeHeader” vid body onLoad --
addEvent(window, "load", changeHeader);

Använd denna kod för att visa iframe:
<iframe id="iframeContent" name="iframeContent"></iframe>

Koden är nästan likadan som den förra men funktionen 'changeHeader' har modifierats och en ny funktion 'getIframeObject' har lagts till.

Lycka till!

9 kommentarer:

Viktor.S sa...

Tjo! Appropå ingenting trillade jag in här och såg att du går den linje jag tänkt hoppa på i höstas, men avstod.
Hade varit kul att diskutera lite närmre rörande kursen då jag eventuellt hoppar på den nu till våren.

Förvisso har den ett annat namn, men jag är tämligen säker på att det är i stortsett samma.
http://www.hh.se/utbildning/hittadinutbildning/sokprogram.2532.html?url=752680950%2Fse_proxy%2Futb_program.asp%3FPtKod%3DTADNT09v&sv.url=12.3e6aa0ee11663924bae800012053

Har läst runt lite i din blogg och förstått att det är väldigt stora grupper och att kursen är på engelska.
Hur funkar det tycker du?

Mvh
Viktor.S

Waschman sa...

Den du tänker välja är mer inriktad på magister och satsar mer på ämnet forskning tillsammans med grupperna som nämns på hemsidan. Den kursen jag går heter Nätverksdesign och Datordrift.

Kurshemsidan för min kurs är: http://www.hh.se/computernetworks1 t.o.m. http://www.hh.se/computernetworks6

Lite information från två av instruktörerna

I stort sett är det samma kursinnehåll men kan inte riktigt säga vad som skiljer. Tror det ingår samma kurser.

Jag har lärt mig jättemycket och tycker det är en grymt intressant och rolig kurs. Jag själv tycker att Cisco är bäst och möjligheterna för jobb är stora. Instruktörerna är verkligen jätteduktiga och har mycket hög kompetensnivå. I nuläget är det för många studenter och det är ganska jobbigt för instruktörerna att lägga ner tid på att hjälpa alla. Mycket är självständigt och teorin tar aldrig slut - känns det som.

Hoppas du finner ett val som passar just dig. Lycka till!

Petter Öhman sa...

Hej!
Försöker använda detta script för min sida men stöter på patrull då jag använder iframe på sidan. Om du har möjlighet skulle jag vara jättetacksam om du hade någon metod för att få detta att fungera!

Med vänlig hälsning
Petter Öhman

Waschman sa...

Hej Petter!
Just ramar och flytande ramar är jag inte så bra på för jag har slutat använda det men hur vill du göra?

Har du en webbsida där en liten ruta är en iframe? Vill du ändra bakgrundsbilden i iframe-innehållet?

Jag är inte helt säker men testa sätt ett ID på din iframe och kalla den från Javascriptet med

var ramdata = getObject("iframe_id");

Sedan kan du testa läsa lite på denna webbsida Working with IFRAME in Javascript och se om du finner något användbart.

Petter Öhman sa...

Hej!

Jag har en indexsida på vilken header området ligger där bakgrunden ska ändras. På denna indexsidan finns menyn som öppnar respektive sida i en iframeram. Problemet blir då att den inte kan ge någon "dynamicHeaderImage". Ska försöka med det du sa men har själv bara läst en universitetskurs i java så det är ingen hög kvalité på kunskaperna.

MVH
Petter

Waschman sa...

Hej igen!
Jag har uppdaterat artikeln och lagt till lite ändringar i slutet för hur man kan göra om man använder iframe's. Observera att det inte fungerar till 100%. Man måste ladda om index.html manuellt.

Petter sa...

Underbart, det är en god början! Får hoppas du hittar en lösning så index inte behöver laddas om.. ;)

Petter sa...

En tanke.
Om länken ger något slags id vid klick?

Waschman sa...

Hmm, jag vet inte riktigt. Saken är den att hur jag än försöker så vet jag inte hur man använder Javascript för att ta reda på när en iframe har laddats färdigt (alltså när DOM för iframe är helt tillgänglig).

Har för mig att jag har sett lösningar för detta om man använder biblioteket jQuery.

Notis: Det går inte att manipulera DOM på fjärrsidor (ej lokala webbsidor).

Om jag hittar någon lösning som fungerar tvekar jag inte att publicera den här åt dig.

Välkomna till bloggen

Välkomna ska ni vara kära besökare. Jag skriver om IT för att det är kul och för att jag vill dela med mig av information och kunskap. Jag försöker hålla bloggen så kategoriserad som möjligt för att ni enklare ska hitta intressanta länkar och artiklar.