首页
关于
Search
1
给你10个市场数据调研报告的免费下载网站!以后竞品数据就从这里找!
182 阅读
2
php接口优化 使用curl_multi_init批量请求
144 阅读
3
《从菜鸟到大师之路 ElasticSearch 篇》
107 阅读
4
2024年备考系统架构设计师
104 阅读
5
PHP 文件I/O
92 阅读
php
thinkphp
laravel
工具
开源
mysql
数据结构
总结
思维逻辑
令人感动的创富故事
读书笔记
前端
vue
js
css
书籍
开源之旅
架构
消息队列
docker
教程
代码片段
redis
服务器
nginx
linux
科普
java
c
ElasticSearch
测试
php进阶
php基础
登录
Search
标签搜索
php函数
php语法
性能优化
安全
错误和异常处理
问题
vue
Composer
Session
缓存
框架
Swoole
api
并发
异步
正则表达式
php-fpm
mysql 索引
开发规范
协程
dafenqi
累计撰写
786
篇文章
累计收到
28
条评论
首页
栏目
php
thinkphp
laravel
工具
开源
mysql
数据结构
总结
思维逻辑
令人感动的创富故事
读书笔记
前端
vue
js
css
书籍
开源之旅
架构
消息队列
docker
教程
代码片段
副业
redis
服务器
nginx
linux
科普
java
c
ElasticSearch
测试
php进阶
php基础
页面
关于
搜索到
6
篇与
的结果
2023-08-28
JavaScript的异步加载
JavaScript的异步加载js的异步加载JavaScript是单线程执行,即代码会一行一行自上而下执行,正常来讲,浏览器是同步加载js代码的,但是一旦遇到网速不好,或者加载的js代码文件过大,容易造成页面阻塞,整个网站将等待js加载而不进行后续的渲染工作,影响交互体验。如:HTML元素按照其页面出现顺序渲染,此时js获取DOM对象,若DOM结构还没有加载完成,就会获取到空对象。<head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script type="text/javascript"> const ul = document.querySelector('ul') console.log(ul) // null const li = document.createElement('li') li.innerHTML = '123' ul.appendChild(li) // Uncaught TypeError: Cannot read properties of null (reading 'appendChild') </script> </head> <body> <ul></ul> </body>这是因为js是一行一行代码执行,js加载执行在DOM结构之前,故为null。解决:通常把< script >放在后面DOM结构后面。js异步加载 就是 等页面加载完成之后再加载js文件 。有助于提高页面故加载速度。js异步加载的三种方式①defer异步加载特点:需要等到dom文档全部解析完才会被执行,ie特有<script type = 'text/javascript' src = tools.js' defer = 'defer'></script> <script type = 'text/javascript' src = tools.js' defer ></script> ②async异步加载特点:加载完就执行,async只能加载外部脚本,不能把js写在script标签里面<script type = 'text/javascript' src = 'tools.js' async="async"></script>③动态创建script标签//tools.js function test() { console.log('hello world') }//在页面中引入tools.js,并执行里面的方法<script script type = 'text/javascript'> const script = document.createElement('script'); script.type = 'text/javascript'; script.src = 'tools.js'; document.head.appendChild(script); test () // Uncaught ReferenceError: test is not defined </script>问题当程序执行至 test() 时,前面的 script.src="tools.js" 还没加载完毕。解决①设置在1秒之后执行,即等js下载完后再执行<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>②监听是否加载完毕// 兼容性好,但不适用于ie <script script type = 'text/javascript'> const script = doccumrnt.createElement('script'); script.type = 'text/javascript'; script.src = 'tools.js'; script.onload = function (){ test(); } document.head.appendChild(script); </script> // 适用于ie <script script type = 'text/javascript'> const script = doccumrnt.createElement('script'); script.type = 'text/javascript'; script.src = 'tools.js'; script.onreadystatechange = function(){ if(script.readyState == 'complete || script.readyState == 'loaded'){ test(); } } </script>兼容性写法<body> <script type='text/javascript'> function scriptLoad(url, callback) { const script = document.createElement('script'); script.type = 'text/javascript'; if (script.readyState) { script.onreadystatechange = function() { if (script.readyState == 'complete' || script.readyState == 'loaded') { callback(); } } } else { script.onload = function() { callback(); } } script.src = url; // 防止出现网速太快造成事件监听不到变化 document.head.appendChild(script); } scriptLoad('index.js', test) // Uncaught ReferenceError: test is not defined </script> </body> 报错原因:页面用到 test()时, script.src 还没有加载。解决:将 test,js 写成对象形式//tools.js // function test() { // console.log('hello world') // } const tools = { test: function() { console.log('hello world') } } <body> <script type='text/javascript'> function scriptLoad(url, callback) { const script = document.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('index.js', 'test') </script> </body>有时候为了将DOM文档解析完之后执行js代码,便将js写在DOM文档结构之后,但是这样写不够美观。解决:监听页面是否加载完成window.addEventListener('load',function(){.....}); // 1、页面所有的东西加载并且执行完之后才执行的方法,假如页面其中任何一个src的资源没被加载,该onload事件便无法执行。运行效率慢 document.addEventListener('DOMContentLoaded',function(){.....},false); // 2、当纯 HTML 被完全加载以及解析时,事件会被触发,而不必等待样式表,图片或者子框架完成加载。 效率较高 在你的脚本有机会运行前,DOMContentLoaded可能就已经被触发。所以在决定添加一个事件监听器前最好先检查一下。只能用addEventListener来监听时间是否触发 function doSomething() { console.info('DOM loaded'); } if (document.readyState === 'loading') { // 此时加载尚未完成 document.addEventListener('DOMContentLoaded', doSomething); } else { // 此时`DOMContentLoaded` 已经被触发 doSomething(); }了解js加载时间线浏览器在开始运行一个页面时,会初始化js功能,当js开始作用时,记录了一系列浏览器按照顺序做的事情,也就是一个执行顺序。js时间线:1、创建Document对象,开始解析web页面,解析HTML元素和文本内容后,添加Element对象和Text节点到文档中,这个节点document.readyState="loading"2、遇到 link 外部 css,创建线程,进行异步加载,并继续解析文档。3、遇到 script 外部 js,并且没有设置 async、defer,浏览器同步加载,并阻塞,等待 js 加载完成并执行该脚本,然后继续解析文档。4、遇到 script 外部 js,并且设置有 async、defer,浏览器创建线程异步加载,并继续解析文档。(异步禁止使用 document.write())注意:1、async 属性的脚本,脚本加载完成后立即执行。defer属性脚本要等到dom解析完成后再执行。2、异步禁止使用 document.write():因为整个文档解析到差不多,再调用document.write(),会把之前所有的文档流都清空,用它里面的文档代替。除了异步禁止,而且当内容全部加载完毕后也要禁止使用document.write(),也就是window.onload。5、遇到 img 等(带有 src),先正常解析 dom 结构,然后浏览器异步加载 src,并继续解析文档。看到标签直接生产 dom 树,不用等着 img 加载完 src。6、当文档解析完成(domTree 建立完毕,不是加载完毕,解析在加载之前),document.readyState = 'interactive'。7、文档解析完成后,所有设置有 defer 的脚本会按照顺序执行。(注意与 async 的不同,但同样禁止使用 document.write());8、文档解析完成后,document 对象触发 DOMContentLoaded 事件,这也标志着程序执行从同步脚本执行阶段,转化为事件驱动阶段。9、当所有 async 的脚本加载完成并执行后、img 等加载完成后(页面所有的都执行加载完之后),document.readyState = 'complete',window 对象触发 load 事件。10、从此,以异步响应方式处理用户输入、网络事件等。
2023年08月28日
11 阅读
0 评论
0 点赞
1
2