宝哥软件园

动态加载脚本的js方法实例概要

编辑:宝哥软件园 来源:互联网 时间:2021-09-28

本文描述了js动态加载脚本的方法。分享给大家参考,如下:

最近公司的前端地图产品需要进行模块划分,期望用户使用哪个功能再加载哪个模块,从而提升用户体验。

所以,到处查资料研究js动态脚本的加载真的很可悲。网上几乎一样的文章,方法有四种。我讨厌抄袭别人成果的人,也不加原文链接。嘿!关键是最后一种方法还有些错误。经过两天的研究,我将在这里与大家分享。

首先,我们需要一个加载的js文件。我在一个固定的文件夹中创建了一个package.js,打开之后,我在里面写了一个方法functionOne。很简单,代码如下:

functionOne(){ alert('成功加载');}以下html文件都是在同一目录下创建的。

方法1:直接写文档

使用以下代码在同一文件夹下创建function1.html:

Html title/title脚本类型=' text/JavaScript ' function init(){//加载js脚本文档. write(' script src=' package . js ' /script ');//加载按钮文档. write(' input type= ' button ' value= ' test running effect ' onclick= ' operation() ' /');//如果马上使用就找不到了,因为还没有加载,这里会报错:functionOne();} function operation() {//可以运行,显示“成功加载”functionOne();}/script/head body输入类型=' button ' value=' initialization loading ' onclick=' init()'//body/html您可以通过document.write的方式将脚本写入页面,如代码所示,点击按钮“initialization loading”即可加载package.js文件。但是,如果立即运行方法functionOne,则不会找到此方法并报告错误,而是单击第二个按钮(“Test Running Effect”由document.write动态创建)并发现它可以执行。此时,脚本已经加载。因为这种方式是异步加载(在继续执行下面的代码时,会打开一个额外的线程来执行要加载的脚本),document.write会重写接口,这显然是不切实际的。

方法2:动态改变现有脚本的src属性。

使用以下代码在同一文件夹下创建function2.html:

htmlhead title/title脚本类型=' text/JavaScript ' id=' YY ' src=' http : '/脚本脚本类型=' text/JavaScript ' function init(){ YY . src=' package . js ';//如果马上使用就找不到了,因为还没有加载,这里会报错:functionOne();} function operation() {//可以运行,显示“成功加载”functionOne();}/script/head body input type=' button ' value=' test button ' onclick=' init()'/input type=' button ' value=' test running effect ' onclick=' operation()'//body/html此方法的优点是不会更改或重写接口元素,但也是异步加载的。

方法3:动态创建脚本元素(异步)。

使用以下代码在同一文件夹下创建function3.html:

html head title/title script type=' text/JavaScript ' function init(){ var Myscript=document . create element(' script ');myscript . type=' text/JavaScript ';myscript . src=' http : package . js ';document . body . appendchild(Myscript);//如果马上用就找不到了,因为functionOne()还没有加载;} function operation() {//可以运行,显示“成功加载”functionOne();}/script/head body input type=' button ' value=' test button ' onclick=' init()'/input type=' button ' value=' test running effect ' onclick=' operation()'//body/html与第二种方法相比,这种方法的优点是不需要在界面的开头写脚本标签,而它的缺点。

这三个方法都是异步执行的,所以在加载这些脚本时,主页的脚本会继续运行。如果使用上述方法,下面的代码将不会得到预期的效果。

但是你可以通过在functionOne前面添加一个提醒来阻止主页面脚本的运行,然后你发现functionOne可以运行,或者你后面的代码需要在另一个按钮下,一步一步的执行,或者定义一个定时器,在固定的时间后执行下面的代码,但是在项目中使用这些方法肯定是不可能的。

事实上,第三种方法有一点变化,变成了同步加载。

方法4:脚本元素的动态创建(同步)。

使用以下代码在同一文件夹下创建function4.html:

html head title/title script type=' text/JavaScript ' function init(){ var Myscript=document . create element(' script ');myscript . type=' text/JavaScript ';myscript . appendchild(document . createtextnode(' function function one(){ alert( '成功运行 ')));}'));document . body . appendchild(Myscript);//这里发现functionOne()可以运行;}/script/head body输入类型=' button ' value=' test button ' onclick=' init()'//body/html此方法不加载外部js文件,而是将子项添加到myScript中。在火狐、Safari、Chrome、Opera和IE9中,这些代码都能正常运行。但是,它会导致IE8及以下版本的错误。脚本被视为一种特殊元素,不允许DOM访问其子节点。但是,您可以使用script元素的text属性来生成js代码,如下例所示:

var Myscript=document . create element(' script ');myscript . type=' text/JavaScript ';myscript . text=' function function one(){ alert( '成功运行 ');}';document . body . appendchild(Myscript);//可以在这里运行functionOne();修改后的代码可以在IE、火狐、Opera和Safari3及更高版本中运行。3.0之前的Safari3.0没有正确支持文本属性,但它允许使用文本节点技术来指定代码。如果您需要与早期版本的Safari兼容,可以使用以下代码:

var Myscript=document . create element(' script ');myscript . type=' text/JavaScript ';var code=' function function one(){ alert( '成功运行 ');}';请尝试{ myscript . appendchild(document . createtextnode(代码));} catch(ex){ Myscript . text=code;} document . body . appendchild(Myscript);//这里发现functionOne()可以运行;在这里,首先尝试标准的DOM文本节点方法,因为除了IE8及以下的所有浏览器都支持这种方法。如果这一行代码抛出了一个错误,它意味着IE8及以下,所以您必须使用text属性。整个过程可以用下面的函数来表示:

函数loadScriptString(代码){ var myScript=document . createelement(' script ');myscript . type=' text/JavaScript ';请尝试{ myscript . appendchild(document . createtextnode(代码));} catch(ex){ Myscript . text=code;} document . body . appendchild(Myscript);}然后您可以在其他地方使用此方法加载您需要使用的代码。事实上,以这种方式执行代码与在全局操作中将相同的字符串传递给eval()是一样的。但是,我们在这里只能使用字符串形式的代码,这也有局限性。用户通常希望以loadScriptAddress('package.js ')的形式提供方法,因此我们需要继续讨论。

方法5: XMLHttpRequest/ActiveXObject异步加载。

使用以下代码在同一文件夹下创建function5.html:

htmlhead标题/标题脚本类型='text/javascript '函数init() { //加载package.js文件,设置脚本的编号为yy ajaxPage('yy ','包。js’);//此方法为package.js里面的方法,此处执行方法成功functionOne();}函数ajaxPage(sId,URL){ var oxmlHttp=GetHttprequest();oxmlhttp。onreadystatechange=function(){//4代表数据发送完毕if (oXmlHttp.readyState==4 ) { //0为访问的本地,200代表访问服务器成功,304代表没做修改访问的是缓存if(oxmlHttp。status==200 | | oxmlHttp。status==0 | | oxmlHttp。status==304){ includeJS(SiD,oxmlHttp。response text);} else { } } } oXmlHttp.open('GET ',url,true);oxmlHttp。发送(null);}函数getHttpRequest() { if(window .ActiveXObject)//IE {返回新的ActiveXObject('MsXml2 .XmlHttp’);} else if(窗口. XMLHttpRequest)//其他{返回新的XMlhttprequest();} }函数includeJS(sId,source) { if((source!=null)(!document.getElementById(sId)).项目(0);var Myscript=document。创建元素(“脚本”);我的脚本。语言=' JavaScript我的脚本。type=' text/JavaScript ';myScript.id=sId请尝试{ myscript。appendchild(文档。createtextnode(source));} catch(ex){ Myscript。text=source} MyHead。append child(Myscript);} }/脚本/床头输入类型='按钮'值='测试按钮onclick=' init()'//body/HTMl ActiveX对象只有工业管理学(工业工程)里面才有,其他浏览器大部分支持XMLHttpRequest,通过此办法我们可以实现动态加载脚本了,不过是异步加载,也没法运行功能一,第二次就可以运行了,但是可惜的是在工业工程,火狐、Safari下可以运行,在歌剧、铬下会出错铬合金下的错误如下:

不过只要发布之后在铬和歌剧下就不会出现错误了。

其实这里把打开里面设置为错误的就是同步加载了,同步加载不需要设置onreadystatechange事件。

方法六:XMLHttpRequest/ActiveXObject同步加载

在这里我把一些情况考虑在内,写成了一个方法,封装为loadJS.js,方便以后直接调用,代码如下:

/** * 同步加载射流研究…脚本* @param id需要设置的脚本标签的id * @param url js文件的相对路径或绝对路径* @ return {布尔值}返回是否加载成功,真的代表成功,假的代表失败*/function loadJS(id,URL){ var XMlhttp=null;如果(窗口. ActiveXObject)//IE { try { //IE6以及以后版本中可以使用xmlHttp=新的ActiveX对象(' Msxml 2 .XMLHTTP’);} catch (e) { //IE5.5以及以后版本可以使用xmlHttp=新的ActiveX对象(' Microsoft .XMLHTTP’);} } else if(窗口. XMLHttpRequest)//火狐、Opera 8.0、Safari、Chrome { xmlHttp=new XMLHttpRequest();} //采用同步加载xmlHttp.open('GET ',url,false);//发送同步请求,如果浏览器为铬或歌剧,必须发布后才能运行,不然会报错xmlhttp。发送(null);//4代表数据发送完毕if (xmlHttp.readyState==4 ) { //0为访问的本地,200到300代表访问服务器成功,304代表没做修改访问的是缓存if(((xmlhttp。状态=200 xmlhttp。状态300)| | xmlhttp。status==0 | | xmlhttp。status==304){ var MyHead=document。getelementsbytagname(' HEAD ').项目(0);var Myscript=document。创建元素(“脚本”);我的脚本。语言=' JavaScript我的脚本。type=' text/JavaScript ';myScript.id=id试试{ //IE8以及以下不支持这种方式,需要通过文本属性来设置我的脚本。appendchild(文档。createtextnode(xmlhttp。response text));} catch(ex){ Myscript。text=XMlhttp。响应文本;} MyHead。append child(Myscript);返回真;} else { return false } } else { return false } }此处考虑到了浏览器的兼容性以及当为铬合金、歌剧时必须是发布,注释还是写的比较清楚的,以后需要加载某个射流研究…文件时,只需要一句话就行了,如loadJS('myJS ',' package.js ')。方便实用。

如果想要实现不发布还非要兼容所有浏览器,至少我还没找出这样的同步加载的办法,我们只能通过异步加载开出回调函数来实现。

方法七:回调函数方式

在同一个文件夹下面创建一个function7.html,代码如下:

htmlhead标题/标题脚本类型='text/javascript '函数init() { //加载package.js文件,设置脚本的编号为yy loadJs('yy ',' package.js ',回调函数);}函数回调函数(){ functionOne();}函数loadJs(sid,jsurl,回调){ var nodeHead=document。GetElementsBytagname(' head ')[0];var nodeScript=nullif(文档。getelementbyid(sid)==null){ nodeScript=document。create element(' script ');nodeScript.setAttribute('type ',' text/JavaScript ');nodeScript.setAttribute('src ',js URL);nodeScript.setAttribute('id ',sid);如果(回调!=null){ nodescript。onload=nodescript。onreadystatechange=function(){ if(nodescript。ready){ return false;} if(!nodescript。readystate | | nodescript。ready state==' loaded ' | | node script。ready state==' complete '){ node script。ready=true回调();} };} nodehead。appendchild(节点脚本);} else { if(回调!=null){ callback();} } }/脚本/床头输入类型='按钮'值='测试按钮onclick='init()'//body/html这种方式所有浏览器都支持,但是后面的代码必须放在回调函数里面,也就是异步加载了。看需求使用把!我还是比较喜欢第六种方法的。如果是异步加载的话,方法还有好几种,不过我的出发点是希望实现同步加载,这里就不对异步加载做总结了。

希望本文所述对大家Java脚本语言程序设计有所帮助。

更多资讯
游戏推荐
更多+