Avatar billede davidfossil Nybegynder
10. august 2005 - 11:40 Der er 11 kommentarer og
3 løsninger

Flere window.onload funktioner

Følgende script vil resultere i, at der vises en alertbox med teksten "B".

window.onload = function()
{
  window.alert("A");
}

window.onload = function()
{
  window.alert("B");
}

Mit ønske er at få begge alertboxe frem, men af tekniske årsager er det nødvendigt at holde de to funktioner adskilt.

Det synes umiddelbart ikke muligt at bruge += til at sætte flere metoder på window.onload, men kan det gøres på en anden måde? Jeg er godt klar over at jeg kan lave en onload der kalder de to andre metoder, men det er ikke muligt i mit setup da de to metoder skal kunne tilføjes fuldstændig uafhængigt af hinanden...
Avatar billede roenving Novice
10. august 2005 - 14:42 #1
Ja, onload er en property på window-objektet, så når du udfører den anden, vil den overskrive den første, men så må du bare kalde den anden som en almindelig funktion:

window.onload = function()
{
  window.alert("A");
  myFunction();
}

function myFunction()
{
  window.alert("B");
}

'-)
Avatar billede softspot Forsker
10. august 2005 - 19:35 #2
Ok, nok en sindssyg idé, men kunne man ikke lave et objekt som pakkede et array af funktioner som man kaldte. Objektet kunne så understøtte at man tilføjede nye funktioner efterhånden som behovet opstod. Noget i stil med dette (ikke testet... endnu):

function functionBuilder() {
  this.funcCalls = new Array();
}

functionBuilder.prototype.Add = function(functionCode) {
  this.funcCalls[this.funcCalls.length] = functionCode;
}

functionBuilder.prototype.Execute = function() {
  for(var i = 0; i < this.funcCalls.length; i++) {
    eval(this.funcCalls[i]);
  }
}

// eksempel på brugen af objektet
var objFuncBuild = new functionBuilder();
objFuncBuild.Add("firstFunction();");
objFuncBuild.Add("secondFunction();");
document.onload = objFuncBuild.Execute();


Nu få jeg sikkert at vide at det da kan gøres på en anden meget smartere og indbygget måde... og hey! - så har jeg også lært noget idag :D
Avatar billede softspot Forsker
10. august 2005 - 19:36 #3
OK, hvis det sidste bare skal have den mindste chance for at fungere som forventet, så skal onload-eventet nok sættes op på denne måde:

window.onload = objFuncBuild.Execute;
Avatar billede softspot Forsker
10. august 2005 - 23:08 #4
Hmm... det lader til at det ikke vil fungere under alle omstændigheder, da

window.onload = objFuncBuild.Execute;

tilsyneladende opretter et nyt objekt (selvom jeg da synes at objFuncBuild er ret globalt?), hvorpå den udfører Execute... eller måske er det bare fordi den udfører funktionen uden noget objekt som kontekst...(?)
Avatar billede softspot Forsker
10. august 2005 - 23:12 #5
Meeeen, man kan da gøre sådan så:

window.onload = new function() {objFuncBuild.Execute();}
Avatar billede softspot Forsker
10. august 2005 - 23:34 #6
det kan faktisk godt være du i stedet skal skrive:

window.onload = function() {objFuncBuild.Execute();}

Jeg havde en anden sær idé, nemlig om man lavede en daisy-chain, når man tilføjede en ny funktion til onload-handleren, dvs. man sørger automatisk for at det nuværende kald som onload-udfører, kaldes efter (eller før) man udfører den nye kode. Så er du inde i noget kode á la det som roenving viste, bare dynamisk genereret. Det kræver dog at du kan finde starten eller slutningen af en funktion, for at kunne indsætte den ønskede kode... nå, den idé er nok lidt for ambitiøs :)
Avatar billede softspot Forsker
11. august 2005 - 00:45 #7
Prøvede lige at lege lidt med det der Daisy Chain-koncept og kom frem til flg. kode:

function functionDaisyChain(obj, theEvent, funcCode) {
    var codeBefore = arguments[3] == true;
    var prevFuncBody = "";
    if(eval("obj." + theEvent) != null) {
        var funcBody = eval("obj." + theEvent + ".toString();");
        prevFuncBody = funcBody.substr(funcBody.indexOf("{"));
    }
    var newCode = "function() {" + (codeBefore?funcCode:"") + prevFuncBody + (!codeBefore?funcCode:"") + "}";
    eval("obj." + theEvent + "=" + newCode);
}
       
function firstFunction() { alert('første'); }
function secondFunction() { alert('anden'); }
function enAndenFunc() { alert('enAndenFunc'); }
       
var debug = "on";
window.onload = firstFunction;
functionDaisyChain(window, "onload", "alert('HEP!');");
functionDaisyChain(window, "onload", "if(debug == \"on\") enAndenFunc();", true);


Funktionen "functionDaisyChain" tager 4 argumenter (hvoraf de 3 er obligatoriske), som angiver objektet hvorpå eventet skal udvides med den kode man angiver. I tilgift kan man vælge om koden skal udføres før eller efter. Hvis man ikke angiver hvorvidt koden skal udføres først eller sidste, bliver den som standard udført sidst...

Det kan nok ikke bruges til noget, men det var da sjovt nok at lege med... :)
Avatar billede per1291 Nybegynder
11. august 2005 - 11:27 #8
Jeg har ikke rigtig forstået ideen med anonyme funktioner (dvs funktioner uden navn).
Du kan altid navngive hver funktion, og så kalde dem i rækkefølge vha onload.

Altså:

function F1() {window.alert("A");}
function F2() {window.alert("B");}
window.onload = {F1(); F2()}

Hilsen Per
Avatar billede roenving Novice
11. august 2005 - 13:47 #9
Har du prøvet det, per ?-)

-- det virker nemlig fint men en anonym funktion:

window.onload = function(){F1(); F2()}

-- men ellers ikke !-)
Avatar billede per1291 Nybegynder
12. august 2005 - 02:34 #10
Nå. Men det virker i forbindelse med en body onload.

Jaja, man lærer hele tiden noget nyt. Tak.

Det vigtigste er, at davidfossil finder en brugbar løsning. Og en af forudsætningerne i opgaven er vist nok, at det ikke er sikkert at begge funktioner eksisterer på et givet tidspunkt.

Jeg har tænkt på, om det måske var muligt at gøre sådan her:
function F1() {window.alert("A");}
function F2() {window.alert("B");}
window.onload = function(){if (F1()){}; if (F2(){};}

Hensigten skulle være: Hvis funktionen F1 er defineret, så kald den; og derefter hvis funktionen F2 er defineret, så kald den.

Men måske er der en syntaksfejl i dét forslag... - Hilsen Per
Avatar billede davidfossil Nybegynder
14. august 2005 - 21:02 #11
Well, jeg er endt med at smide en script-blok i bunden af siden hvor jeg simpelthen kalder F1() hhv. F2() afhængigt af hvilke der er aktuelle på den givne side. I må meget gerne smide svar alle tre, så kan I dele points for de udemærkede forslag.
Avatar billede softspot Forsker
14. august 2005 - 21:06 #12
Der kom et :)
Avatar billede per1291 Nybegynder
15. august 2005 - 00:30 #13
Okay, jeg vil da gerne have lidt point. De kan jo bruges til at spørge med...
Hilsen Per
Avatar billede roenving Novice
16. august 2005 - 13:24 #14
-- og tak for point ;~}
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