json
- json是一种传输数据的格式(以对象为样板,本质上即使对象,但是用途有区别,对象就是本地用的,json是用来传输的)
- JSON.parse(); string—>json
- JSON.stringifg(); json—>string
异步加载js
- js 加载的缺点:加载工具方法没必要阻塞文档,过多 js 加载会影响页面的效率,一旦网速不好,那么整个网站将等待 js 加载 而不进行后续渲染等工作。
- 有些工具方法需要按需要加载,用到再加载,不用不加载
- javascript 异步加载的三种方案
- 1.defer 异步加载,但要等到dom文档全部解析完才会被执行。只有IE可用(IE9以下都可以用),也可以将代码写到内部。
- 2.async 异步加载,加载完就执行,async 只能加载外部脚本,不能把 js 写在 script 标签里
- 3.执行是也不阻塞页面
- 4.创建script,插入到DOM中,加载完毕后callBack
// demo.js function test() { console.log('a'); }
由以上思路封装的兼容性方法var script = document.createElement('script'); script.type = "text/javascript"; // 如果让demo.js异步加载,demo.js中的test()不能直接引用 // 因为如果说demo.js加载的速度没有调用到test来的快的话,就会找不到这个函数而报错 // 所以我们可以在onload中调用test,就是说在文档对象加载完成后再触发test方法,这样就不会报错了 // 但是又产生了另一个问题,就是IE不兼容onload,IE有自己的readyState来监听文档对象是否加载完成 if(script.readyState) {// 判断是否是亲爱的IE浏览器 script.onreadystatechange = function () {//onreadystatechange事件 readystate(状态码)变化时触发 if(script.readyState == "complete" || script.readyState == "loaded") { test(); } } } else { script.onload = function () {// 兼容Safari chrome firefox opera test(); } } script.src = "demo.js";// 为什么这个src要写在最后呢,因为考虑到一种情况,如果demo.js瞬间加载完成,readystate已经变成了complete,就不会触发onreadystatechange这个绑定事件
function asyncLoaded(url, callback) { var script = document.createElement('script'); script.type = "text/javascript"; if (script.readyState) {//IE script.onreadystatechange = function () { if(script.readyState == "complete" || script.readyState == "loaded") { obj[callback](); script.onreadystatechange = null; } } } else {// chrome safari firefox script.onload = function () { obj[callback](); } } script.src = url; document.head.appendChild(script); }
js加载时间线
- 创建Document对象,开始解析web页面,解析HTML元素和他们的文本内容后添加Element对象和Text节点到文档中。这个阶段Document。readyState = “loading”。
- 遇到link外部css,创建线程加载,并继续解析文档。
- 遇到script外部js,并且没有设置async , defer ,浏览器加载,并阻塞,等待js加载完成并执行该脚本,然后继续解析文档
- 遇到script外部js,并且设置有async,defer 浏览器创建线程加载,并继续解析文档,对于async属性的脚本,脚本加载完成后立即执行(异步禁止使用docuemnt.write())。
- 遇到img标签等,先正常解析dom结构,然后浏览器异步加载src,并继续解析文档
- 当文档解析完成,document.readyState = “interactive”;
- 文档解析完成后,所有设置有defer的脚本会按照顺序执行。
- 当文档解析完成之后,document对象触发DOMContentLoaded事件(document.addEventListener(‘DOMContentLoaded’, function(){…}),只有addEventListener才能触发),这也标志着程序执行从同步脚本执行阶段,转化为事件驱动阶段
- 当所有saync的脚本加载完成并执行后,img等加载完成后,document.readyState = “complete” window对象触发load事件
- 从此,页面以异步响应方式处理用户输入,网络事件等。
window.onload 和 $().ready这两个有什么区别呢?
window.onload要等到所有东西加载完才执行,而ready只要dom解析完成就执行了,所以ready比onload更快一点。
BOM
- BOM(Browser Object Model),定义了操作浏览器的借口
- 常用的BOM对象:Window, History,Navigator,Screen, Location等
- 由于浏览器厂商的不同,Bom对象的兼容性极低。
window
- 参考链接:https://www.w3school.com.cn/jsref/index.asp
- history对象
- Navigator对象
- Screen对象
- Location对象
- location.hash
- "#“后是对浏览器操作的,对服务器无效,实际发出的请求也不包含”#"后面的部分
- "#"被算作历史记录
- location.hash
正则表达式
正则表达式的作用:匹配特殊字符或有特殊搭配原则的字符串的最佳选择。
以后用的话最好看看w3school
w3school:
https://www.w3school.com.cn/js/jsref_obj_regexp.asp
如果遇到正则看不懂的话,JavaScript正则表达式可视化器:
https://jex.im/regulex/#
RegExp
- 两种创建方式
- 直接量
var reg = /abc/; - new RegExp();
var reg = new RegExp(“abc”);
- 直接量
- 个人推荐用直接量
Doctype
- 1.渲染模式
在多年以前(IE6诞生以前),各浏览器都处于各自比较封闭的发展中(基本没有兼容性可谈)。随着WEB的发展,兼容性问题的解决越来越显得迫切,随即,各浏览器厂商发布了按照标准模式(遵循各厂商制定的统一标准)工作的浏览器,比如IE6就是其中之一。但是考虑到以前建设的网站并不支持标准模式,所以各浏览器在加入标准模式的同时也保留了混杂模式(即以前那种未按照统一标准工作的模式,也叫怪异模式)。 - 三种标准模式的写法
- <!DOCTYPE html>
- <!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01//EN” “http://www.w3.org/TR/html4/strict.dtd”>
- <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Strict//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd”>
修饰符
- i 执行对大小写不敏感的匹配。
- g 执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。
- m 执行多行匹配。
i和g在w3school中都有介绍,就讲一讲m吧,多行匹配指的是在匹配到换行符的时候,会再次匹配var reg = /^a[A-z]*/g; var reg1 = /^a[A-z]*/gm; var str = "apricot\npear\napple\norange" console.log(str.match(reg))// ["apricot"] console.log(str.match(reg1))// ["apricot", "apple"]
笔记:
// RegExp
var reg = /^a[A-z]*/g;
var str = "apricot\npear\napple\norange"
str.match(reg);// ["apricot", "apple"]
reg.test(str);// true 只要有reg中能匹配到有符合的条件就为true
// \w === [0-9A-z_]
// \W === [^\w]
// \d === [0-9]
// \D === [^\d]
// \s === [\t\n\r\v\f ]
// \S === [^\s]
// \b === 单词边界
// \B === 非单词边界
var reg1 = /\bdef\b/g;
var str1 = "abc def ghi"
str1.match(reg1);// ["def"]
// . === [^\r\n]
检验一个字符串是否含有数字
var reg = /^\d|\d$/g;
exec:
var reg = /ab/g;// 不加g的话,lastIndex不会变,会一直为0
var str = "ababadab"
console.log(reg.lastIndex);// 0
console.log(reg.exec(str));// 匹配从lastIndex开始的字符串
console.log(reg.lastIndex);// 2
console.log(reg.exec(str));
console.log(reg.lastIndex);// 4
console.log(reg.exec(str));
console.log(reg.lastIndex);// 8
console.log(reg.exec(str));
console.log(reg.lastIndex);// 0
console.log(reg.exec(str));
XXXX形式和xxyy形式:
// 匹配xxxx格式的内容
var str = "aaaabbbb";
var reg = /(\w)\1\1\1/g;// \1匹配第一个表达式中相同的内容
// 匹配xxyy格式的内容
var str1 = "aabbccdd";
var reg1 = /(\w)\1(\w)\2/g;// \1匹配第一个表达式中相同的内容,\2匹配第二个表达式中相同的内容
console.log(str.match(reg));// ["aaaa", "bbbb"]
console.log(str1.match(reg1));// ["aabb", "ccdd"]
xxyy替换成yyxx:
// xxyy替换成yyxx
var reg = /(\w)\1(\w)\2/g;
var str = "aabb";
// 方法一
console.log(str.replace(reg, "$2$2$1$1"));// bbaa
// 方法二
console.log(str.replace(reg, function ($, $1, $2) {
// $是全局匹配到的内容
// $1是第一个子表达式的内容
// $2是第二个子表达式的内容
return $2 + $2 + $1 + $1;
}));// bbaa
the-first-name ===> theFirstName
var reg = /-(\w)/g;
var str = "the-first-name";
console.log(str.replace(reg, function ($, $1) {
return $1.toUpperCase();
}));
正向预查
var str = "abaaaa";
var reg = /a(?=b)/g;//["a"] a后面跟着b的结果,但是b不参与选择,它只参与修饰,所以只会选出第一个a
// 如果是(?!b) 意思就是a后面不跟b的全选出来
数字的货币格式,每三位一个逗号分隔:
var str = "100000000000000000";
var reg = /(?=(\B)(\d{3})+$)/g;// 找到一个非单词边界且后面为三的倍数个数字的一个空
console.log(str.replace(reg, ","));// 在这个空地方插入逗号