Author:MarkKahn
ManydevelopershavealargelibraryofJavaScriptcodeattheirfingertipsthattheydeveloped,theircolleguesdeveloped,orthatthey'vepiecedtogetherfromscriptsallovertheInternet.Haveyoueverthoughtthatitwouldbenicetonothavetosearchthroughallthosefilesjusttofindthatonefunction?ThisarticlewillshowyouhowdynamicallyincludeanyJavaScriptfile,atruntime,bysimplycallingafunctioninthatfile!
Here'sanexample:Youhaveafunctionfoo()infilebar.js.Inyourcode,youknowthatfoo()mightbecalled,butitprobablywon'tbebecausemostpeopledonotuseitsfunctionality.Youdon'twanttoforcetheusertodownloadbar.jsunlessit'sgoingtobeusedbecauseit'safairlylargefile.Hereyou'lllearnhowtomakeafakefoo()functionthatactuallyloadsbar.jsontheflyandthencallstherealfoo()function.
DynamicallyLoadingaScript
Asmanydevelopersknow,thereareatleasttwodifferentwaystodynamicallyloadascriptatruntime.Thefirstistocreateascriptobjectandappendittothedocument.ThesecondistouseanXMLHTTPrequesttograbthesourcecode,andtheneval()it.
Itisthissecondmethodthatwe'regoingtouse,andwe'regoingtoexploitthefactthatanXMLHTTPrequesthasthecapabilitytocompletelystallanyscriptactivity.
First,somebasics:howtocreateanXMLHTTPObject.Thereareasmanydifferentfunctionstoreturnacross-browserXMLHTTPObjectastherearedevelopersthatworkwithAJAX.Ihappentohavemyownaswell,andhere'sasimplifiedexampleofthat:
复制代码 代码如下:
functiongetXMLHttpObj(){
if(typeof(XMLHttpRequest)!='undefined')
returnnewXMLHttpRequest();
varaxO=['Msxml2.XMLHTTP.6.0','Msxml2.XMLHTTP.4.0',
'Msxml2.XMLHTTP.3.0','Msxml2.XMLHTTP','Microsoft.XMLHTTP'],i;
for(i=0;i
returnnewActiveXObject(axO[i]);
}catch(e){}
returnnull;
}
MostbrowsersotherthanInternetExplorer5or6haveabuilt-inXMLHttpRequestobject.InternetExplorer7,whenit'sreleased,willalsohavethisobjectnatively.Thefirstthingwedoischecktoseeifthisobjectexists.Ifitdoes,wecreateaninstanceofitandthat'sit.Iftheobjectdoesn'texist,weattempttocreateoneofseveralActiveXObjects.Wedon'tknowwhatobjectsourusershaveinstalled,soweattempttocreateseveraldifferentXMLHTTPobjects,startingwiththenewestones.
Nowinordertodynamicallyloadfunctions,wefirstneedtodefinethem.Wecoulddothisonefunctionatatime,butinsteadofhard-codingdozensoffunctions,wecanchoosetojustmakeanobjectorarraywithallthefilenamesandthefunctionsyouwanttohaveauto-included:
复制代码 代码如下:
varautoIncludeFunctions={
'scripts/file1.js':['function1','function2','function3'],
'scripts/file2.js':['function4','function5','function6'],
'scripts/file3.js':['function7','function8','function9']
}
OurautoIncludeFunctionsobjectshouldcontainalistofJavaScriptfiles,aswellasalistoffunctionsinthosefiles.HereweareusingshorthandJavaScriptnotationtocreateboththeobjectandthearrays,butthesamethingcouldbeaccomplishedinmanydifferentways.
These.jsfilescancontainanycodeyouhaveavailable,suchasJavaScriptmenus,animations,etc.Thesimplestexamplewouldbeafiletitled"file1.js"thatonlycontained"functionfunction1(){alert('Hello,World!');}".
Notethatifanyofthesefilescontainfunctionswiththesamenameasanotherfile,onlythelastfunctionlistedwillbeused.
Tomakethingsabiteasier,we'regoingtomakeafunctionthatwillpullaJavaScriptfiledownandexecuteit.It'sveryimportant,inourcase,thatthethirdparamatersenttotheXMLHTTPobjectbefalse.Thisforcesthescripttowaitfortheresponsetodownloadasopposedtocontinuingonwithothercode.
复制代码 代码如下:
functionloadScript(scriptpath,functions){
varoXML=getXMLHttpObj();
oXML.open('GET',scriptpath,false);
oXML.send('');
eval(oXML.responseText);
for(vari=0;i
}
TheloadScriptfunctionexpectstwoarguments:scriptpathandfunctions."scriptpath"shouldcontaintheURLtoyourJavaScriptfile,and"functions"isthearrayoffunctionsthatexistinthisJavaScriptfile.
Asyoucansee,thecodetopullandexecuteascriptisstraightforward.Thebrowserfirstdownloads,andtheninterpretstheJavaScriptfile.Ifyou'vereadanyotherarticlesonAJAXdevelopment,youmightrememberthatinmostcasesthethirdargumentsenttotheopen()functionofanXMLHTTPobjectisusually"true."Inourcasewehaveitsetto"false."ThisargumentcontrolsthestateoftheXMLHTTPobject.Ifsettotrue,theobjectrunsasynchrounously,meaningthatallotherJavaScriptcodecontinueswhiletheobjectisloading.Whilethisisagoodthinginmanycircumstances,ifweimplementedithereourcodewouldreturnbeforeourfilewasdoneloading.Sincewewantourcodetowaituntilthisfileiscomplete,wesetthisthirdargumenttofalse,thuspausingourJavaScriptexecutionuntilwearereadytocontinue.
WhenthecodeisevaluatedfromtheresponseText,it'sexecutedinthelimitedscopeoftheloadScriptfunctionandbecauseofthis,noneofthesefunctionswillbeavailableoutsideoftheloadScriptfunction.Inorderdogetaroundthis,theforloopaddseachfunctiontothewindowobject,thusmakingitgloballyavailable.
It'simportanttonotethatonlyscriptsonthesameserverasthecurrentpagecanbecalledinthismanner.ThisisinherenttotheXMLHTTPObjectandisanecessarymeasuretoincreasegeneralbrowsersecurity.