javascript异步加载的三种方式以及如何动态创建script标签

什么是异步加载js?

javascript是一门弱数据类型的语言,从执行机制上来讲是单线程,即代码会一行一行自上而下往下执行。通常,我们日常生活中所讲的 同步 表示的是同一个时间段在做几件相互独立的事, 异步 表示做完一件事再去做另一件事,但是在计算机的世界中,同步异步的概念恰好与现实世界中相反,异步表示同一个时间段做几件相互独立的事。
异步加载js表示,浏览器在加载js文件的时候,也在进行着其他的工作,如渲染页面等

异步加载js的优点?
通常来讲,因为javascript是单线程的执行机制,所以浏览器是同步加载js代码的,但是一旦遇到网速不好,或者加载的js文件过大的话,往往会造成页面阻塞,整个网站将等待js加载而不进行后续的渲染工作,十分影响交互体验。所以,通常在这种情况下,异步加载js是一种很好的选择。

异步加载js的三种方式?

1.defer 异步加载

特点 :只有IE适用,需等到dom文档全部解析完(dom树生成完,才会被执行)
	<script type = 'text/javascript' src = tools.js' defer = 'defer'></script>
	<script type = 'text/javascript' src = tools.js' defer ></script>
	//注  :当key和value值一样是,直接写key值	

2.async 异步加载

特点:加载完就执行,async 只能加载外部脚本,不能把js代码写在script标签里
<script type = 'text/javascript' src = 'tools.js' defer></script>

3.动态创建script标签

	var script = doccumrnt.createElement('script');
	script.type = 'text/javascript';
	script.src = 'tools.js';
	document.head.appendChild(script);
  // 不写这一行,就只能加载,不执行

动态创建script标签的优点以及注意事项

在动态引入js文件后,可直接调用里面的方法执行

	//tools文件表示如下
	function test(){console.log('hello world')

	//在页面中引入tools文件,并执行里面的方法
<script script type = 'text/javascript'>
	var script = doccumrnt.createElement('script');
	script.type = 'text/javascript';
	script.src = 'tools.js';
	document.head.appendChild(script);
	test ()
</script>

执行后出现的问题

Uncaught ReferenceError: test is not defined

这是因为,当程序执行到test()时,前面的script.srd = 'tools.js’还没有下载完成
修改方法1:

<script script type = 'text/javascript'>
	var script = doccumrnt.createElement('script');
	script.type = 'text/javascript';
	script.src = 'tools.js';
	document.head.appendChild(script);
	setInterval(function(){
		test ();
	],1000)
</script>

当把函数设置为一秒后执行,即等js文件下载完后再执行,就不报错。

此时,我们想是否是一种方法能提醒我们js文件下载完成了,我们然后再执行函数

解决方式:

方法一:非ie方法 script.onload = function(){},触发 script.onload事件就代表下载完成了

<script script type = 'text/javascript'>
	var script = doccumrnt.createElement('script');
	script.type = 'text/javascript';
	script.src = 'tools.js';
	script.onload = function (){
		test();
	}
	document.head.appendChild(script);

</script>

方法二 : ie上有一个状态码,script.readyState,功能与script.onload相似

script.readyState = 'loading'  最开始的值
script.readyState = 'complete' || 'loaded" 表设计加载完成
监听这个方法的事件:onreadystatechange
<script script type = 'text/javascript'>
	var script = doccumrnt.createElement('script');
	script.type = 'text/javascript';
	script.src = 'tools.js';
	script.onreadystatechange = function(){
		if(script.readyState == 'complete || script.readyState == 'loaded'){
		test();
		}
	}
</script?

把以上两种加载js方法封装成一个loadScript函数

<script script type = 'text/javascript'>
	function loadScript(url,callback){
		var script = doccumrnt.createElement('script');
	  	script.type = 'text/javascript';
	
		if(script.readyState) {
			script.onreadystatechange = function(){
			if(script.readyState == 'complete' || script.readyState == 'loaded'){
				callback ();
				}
			}
		}else{
			script.onload = function(){
			callnack();
		}
	}
	script.src = 'url'; // 防止出现网速太快造成事件监听不到变化
	document.head.appendChild(script);
}
	scriptLoad(tools.js ,test)

此时会出现的问题

Uncaught ReferenceError: test is not defined

这是因为加载函数loadScript是并不会查看里面的代码,等到执行到 scriptLoad(tools.js ,test)时,找不到test

解决方法:把callback 变成字符串形式
方式一:使用eval (不推荐使用)

<script script type = 'text/javascript'>
	function loadScript(url,callback){
		var script = doccumrnt.createElement('script');
	  	script.type = 'text/javascript';
	
		if(script.readyState) {
			script.onreadystatechange = function(){
			if(script.readyState == 'complete' || script.readyState == 'loaded'){
				eval(callback);
				//能把字符串当代码执行
				}
			}
		}else{
			script.onload = function(){
			eval(callnack);
		}
	}
	script.src = 'url'; 
	document.head.appendChild(script);
}
	scriptLoad(tools.js ,'test')

方法二:需要配和js文件来使用

//tools代码文件如下
	var tools = {
		test :function(){
		console.log('hello world')
		}
	}
	
<script script type = 'text/javascript'>
	function loadScript(url,callback){
		var script = doccumrnt.createElement('script');
	  	script.type = 'text/javascript';
	
		if(script.readyState) {
			script.onreadystatechange = function(){
			if(script.readyState == 'complete' || script.readyState == 'loaded'){
				tools[callback]();
				}
			}
		}else{
			script.onload = function(){
			tools[callback]();
		}
	}
	script.src = 'url'; 
	document.head.appendChild(script);
}
	scriptLoad(tools.js ,'test')
  • 8
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值