day 01
一、BOM的常用对象
1、history对象:
保存了当前窗口的历史纪录(过去的url)
前进:history.go(1);
后退:history.go(-1);
刷新:history.go(0);
2、location对象:
保存了当前窗口的正在打开的url(现在的url)
程序员常识:
一个url由几部分组成?分别每个部分有什么用? - 以后再学习服务器端和数据库的时候会有很大的帮助。
5部分:
1、协议:*https(加密)/*http(未加密)/ftp(传输文件)/ws(直播)... 前两个都属于叫做请求-响应模型
2、主机号|IP地址|域名:域名是需要花钱购买的,主机号|IP地址是免费,127.0.0.1才真的是叫做主机号,只能自己访问自己
3、端口号:https默认端口为443,http默认端口为80,只有默认端口可以省略不写
4、文件的相对路径|路由:百度加密了
5、查询字符串|请求消息:前端传输到后端的东西,前端对后端说的话,就是form表单提交带来的东西
属性:
获取url的5个部分的内容,但是不需要记忆,你直接输入location对象即可查看
协议:location.protocal
域名:location.hostname
端口:location.port
路由:location.pathname
请求消息:location.search
跳转:
location="新url" - 替换当前窗口,可以后退
跳转后,禁止后退:location.replace("新url") - 替换当前窗口,禁止后退
刷新:location.reload()
二、原本DOM是可以操作一切结构化文档的,但是再某一个升级后,为了方便各类程序员将DOM分为了3方面:
1、核心DOM:
无敌的,即可以操作HTML又可以操作XML,但是语法相对比较繁琐
2、HTML DOM:
只可以操作HTML,不能访问一切自定义的东西,但是语法简单
3、XML DOM:
只可以操作XML,被淘汰了,被JSON数据格式代替了。
三、查找元素
1、通过关系找元素
2、直接找元素
(1)document.getElementsByXXXX();
返回的是一个动态集合HTMLCollection
(2)2个:
1、var elem=document.querySelector("任意css选择器的");
query-查询 selector-选择器:查询css选择器
缺陷:只能找到单个元素,如果匹配到了多个,也只会返回第一个,没找到null,一次只能操作一个元素
2、var elems=document.querySelectorAll("任意css选择器的");
优点:
1、找到了是一个集合,没找到是一个空集合
2、复杂查找时,非常简单
3、返回的是一个静态集合NodeList
面试题:
document.getXXX 和 document.queryXXX的区别?
1、后者更适合复杂查找
2、动态集合和静态集合的区别?
(1)动态集合:每一次DOM发生变化,他都会悄悄的再次查找,让页面和数据保持一致,但是效率也就低下了 - 不支持forEach
(2)静态集合:每一次DOM发生变化,他不会悄悄的再次查找,让页面和数据没有保持一致,但是效率也就高了 - 支持使用forEach
四、操作样式
1、内联样式
2、样式表样式
//获取你想要操作的样式表
var sheet=document.styleSheets[i]
//获取此样式表中所有的样式规则
var rules=sheet.cssRules
//数出你想要操作的那个规则的
var rule=rules[i]
//操作
console.log(rule.style.css属性名)
rule.style.css属性名="css属性值"
五、操作属性
1、获取属性值:
核心DOM:elem.getAttribute("属性名")
HTML DOM:elem.属性名
2、设置属性值:
核心DOM:elem.setAttribute("属性名","属性值");
HTML DOM:elem.属性名="属性值";
3、删除属性:
设置属性值为空字符串,确实某些属性可以算是删除,但是只是删除了属性值,属性名还在,而有的属性哪怕只有一个属性名,也会具有作用(比如:href、disabled、readonly)
核心DOM:elem.removeAttribute("属性名");
HTML DOM:elem.属性名=""; - 属性节点删不干净
4、判断有没有:
垃圾,只能判断有没有,不能判断是什么,推荐用elem.getAttribute("属性名");去获取到值,自己再写比较运算。
核心DOM:elem.hasAttribute("属性名");
HTML DOM:elem.属性名!="";
以后建议:
优先HTML DOM,HTML DOM实现不了的再用核心DOM补充!
缺陷:
1、class必须写为className
2、自定义的东西都操作不了
五、操作内容:
innerHTML/innerText/Value
六、5、如何创建元素以及上树:3步
1、创建空标签:
var elem=document.createElement("标签名")
2、为其设置必要的属性和时间
elem.属性名=“属性值”;
elem.on事件名=function(){}
3、上树(3种):
*父元素.appendChild(elem);
父元素.insertBefore(elem,已有子元素);
父元素.replaceChild(elem,已有子元素);
六、删除元素:elem.remove()
拓展:
1、创建变量
新增的一个let关键字:
let 变量名=值;
作用:
1.解决了声明提前
2.带来了块级作用域,一个{}就是一个块,此变量只能在那个{}里面使用
3.如果用let去当作下标绑定时间,那么他会记录你当前元素的下标,不再需要自定义下标了-其实forEach那个形参i就是let创建的。
2、类数组转为普通转为普通数组
接住=Array.from(类数组对象);
day 02
一、递归
简单来说就是再函数之中再一次调用了函数自己,迟早有一天会停下来:
何时:专门用于【遍历层级不明确的情况】-DOM树和数据(childern只能找到儿子层,找不到孙子层)
如何使用(2步):
function 函数名(root){
1、第二层要做什么直接做
2、判断有没有下一层,如果有下一层则再次调用此方法,只不过传入的实参是自己的下一层
}
函数名(实际的根)
算法:深度优先!优先遍历当前节点的子节点,子节点遍历完毕才会跳到兄弟节点
缺陷:不要过多使用,性能相对较差,同时开启大量函数调用,浪费内存,我们只在一个情况:【层级不明确】
递归 vs 纯循环
递归:
优点:简单易用
缺点:难得一批
纯循环:
优点:几乎不占性能
缺点:难
二、绑定事件(3种):
1.在HTML上书写事件属性
<elem on事件名=“函数名(实参)”></elem>
缺点:
1.不符合内容与样式与行为分离的原则
2.无法动态绑定,一次只能绑定一个元素
3.不支持绑定多个 函数对象
2.在js中使用时间处理函数属性
elem.on事件名=function(){操作}
优点:
1.符合内容与样式,行为的分离原则
2.动态绑定,一次能绑定多个元素
缺点:
1.不支持绑定多个函数对象
3.在js中使用事件API:如果不用考虑老ie
主流:elem.addEventListener("事件名",callback);
老IE:elem.attachEvent("on事件名",callback);
兼容:
if(elem.addEventListener){
elem.addEventListener("事件名",callback);
}else{
elem.attachEvent("on事件名",callback);
}
优点:
1、符合内容与样式与行为的分离原则
2、动态绑定
3、支持绑定多个函数对象
缺点:有兼容性问题
拓展
1、select&option只有他们可以简化创建元素&上树:
select.add(new Option("innerHTML","value"));
day 03
属于BOM(重点只有两个):
定时器 + event(事件对象)
一、事件周期:
从事件发生,到所有事件处理函数执行完毕的全过程
1、3个阶段:
(1)捕获阶段
由外向内,记录要发生的事件有哪些
(2)你表优先触发
目标元素->当前点击的的实际发生事件的元素
(3)冒泡触发
二、获取事件对象event
主流:会自动作为事件处理函数的第一个形参传入
老IE:event;
兼容:event;
1、event能做什么
(1)获取鼠标的坐标
获取鼠标相对于屏幕的坐标:e.screenX/Y
获取鼠标相对于窗口/客户端/文档显示区域的坐标:e.clientX/Y
获取鼠标相对网页的坐标:e.pageX/Y
(2)阻止事件冒泡(笔试题):
主流:e.topPropagation()
老IE:e.cancelBubble=true
兼容: e.cancelBubble=true
//老ie可用,主流也可用
(3)利用冒泡/事件委托
开发中常用,提升网页性能,有了它我们的事件函数也可以换为箭头函数了。
1、优化
如果多个子元素定义了相同或相似的事件操作,最好只给父元素定义一次
2、为什么
每一次绑定一个事件函数,其实都是创建了一个事件对象,创建事件对象越多,网站性能就越差。
淘汰了this
认识一个目标元素target:你点击的是哪一个,他永远就是那一个,不会变化的。
主流: e.target;
老ie:e.srcElement;
兼容:e.srcElement; //第3次见到小三上位
(4)阻止浏览器的默认行为
比如:a标签默认就可以跳转,提交按钮可以提交表单,右键自带一个弹出框,F12自带一个控制台,F11自带全屏功能,F5自带刷新功能
主流:e.preventDefault()
老IE:e.returnValue=false
兼容:e.returnValue=false
新事件:
1.有件事件-window.oncontextmenu
2.键盘事件:一般来说用于游戏开发较多+都要搭配上键盘的键码
window.onkeydown-按住和按下,任何键盘按键都可以触发
window.onkeypress-按住和按下,只有字母、数字、回车、空格可以触发,其他按键不行
window.onkeyup - 松开,任何键盘按键都可以触发(比手速的游戏)
(5)获取键盘的键码
e.keyCode;-可以获取到你按了那个健,每个键都有自己对应的键位,但是不需要记忆,需要输出看。
event可以说是BOM之中最最重要的一个点,其他点就算你不用,你也要知道,笔试面试只要考BOM多半都是event
老IE:不支持HTML5和CSS3和ES5+
day04
一、事件的取消绑定
1、使用的elem.onclick
取消:elem.onclick=null
2、使用的elem.addEventListener("事件名",回调函数)
取消:elem.removeEventListener("事件名",回调函数);-事件名和回调函数,必须和添加时一摸一样
二、this指向:很多
单个元素绑定事件this->这个元素
多个元素绑定事件this->当前元素
箭头函数中的this->外部对象
函数中this->当前正在调用函数的这个人
定时器的this->window
三、ES5强制改变this指向
1、call/apply:临时的替换了函数的this-借用
(1)语法:
函数名.call(借用的对象,实参,。。。);-单独传入每个实参数
(3)强调
call/apply:相当于立刻调用函数,立即执行的
2、bind:
永久替换了函数中的this(3件事)
1、创建了一个和原函数功能完全相同的新函数
2.将新函数的this永久绑定为指定对象,别人都借不走
3.将新函数的部分参数永久固定
(1)语法
var 新函数=函数名.bind(永久对象,永久实参,。。。); 不是立刻执行,需要自己调用
(2)强调
bind绑定的新函数没办法被call/apply再次接走
三个固定套路
1.Math.max/min.apply(Math,arr)也可以支持数组
2.Object.prototype.toString.call/apply(x)==="[object Array]";
3.数组转换成普通数组
接住=Array.prototype.slice.call/apply(类数组对象)
接住=Array.from(类数组对象)
四、ES6
1、学过了:
let、const、箭头函数
2、模版字符串:
可以直接识别变量,不在需要+运算去拼接了,而且实现了一个简单的js含经。甚至支持在里面书写API
例:`我的名字叫${name}`
3、解构赋值
顾名思义:解析结构再进行赋值-赋值额度新方式,并且得到加强
如果赋值符号,左右两边的结构一样的,就会悄悄的揭开/脱掉结构再一一的进行赋值
语法:
1.类似数组的解构赋值
let [a,b,c]=[1,2,3]
console.log(a)
console.log(b)
console.log(c)
2、类似对象的解构赋值
let {a,b=默认值,c}={c:3,a:1,b:2}
console.log(a)
console.log(b)
console.log(c)
//形参可以设置默认值,如果自己传入了,就用自己的
3、调用函数时,传递实参的顺序无所谓了
function zwjs({name,age,hobby="女"}){
return `我的名字叫${name},今年${age}岁,喜欢${hobby}`;} console.log(zwjs({hobby:"学习",age:18,name:"袍哥"}));
4、函数的返回的结果,可以有多个
function f1(){
var a=1
var b=2
return [a,b]
}
var [a,b]=f1()
console.log(a,b)
只要以后见到:方法名({里面放着键值对就是使用了ES6的解构赋值})
4、Set和Map新的数据类型:
(1)*Set:类似于数组的一种数据格式 - 【去重数组,然后再转回数组】
var s=new Set(arr);
...s - 三个点扩展运算符,可以脱掉数组的外套
一句话完成:[...new Set(arr)] - 不用记忆任何API
(2)Map:类似于对象的一种数据格式
var m=new Map();
添加:m.set("键","值");
获取:m.get("键");
清空:m.clear();
删除:m.delete("键");
5.新的循环:垃圾
for(var v of arr){
v;
}
缺陷:
1、没有提供过下标,意味着不能修改原数组
2、只能遍历索引数组,不能遍历hash数组,意味着也不能遍历对象
day05
一、正则表达式:
定义字符串中字符出现规则的表达式
1、何时使用:
切割 替换 【验证】
2、如何使用
语法:/正则表达式/
(1)最简单的正则
关键字原文 "no" -> /no/后缀
后缀:g:找全部
i:忽略大小写
(2)备选字符集:
/^[备选字符集]$/
强调:
一个中括号,只有一位字符串
问题
正则表达式默认只要满足就不管后续了,而我们做验证的人,希望用户从头到尾按照我们的要求来,希望从头到尾完全匹配
解决
前面加^,后main加$,两者同时使用,代表要求从头到尾完全匹配/^[备选字符集]$/ - 只要做验证必加!
特殊
如果备选字符集中的ascii码是连续的,那么可用-省略掉中间部分
比如:
一位数字:[0-9]
一位字母:[A-Za-z]
一位数字、字母、下划线:[0-9A-Za-z_]
一位汉字:[\u4e00-\u9fa5]
除了xxx之外的:[^0-9] - 很少使用,范围太广了
(3)3、预定义字符集:
提前定义了一些字符集,方便我们程序员 - 简化了备选字符集
一位数字:\d ===>[0-9]
一位数字、字母、下划线:\w ===> [0-9A-Za-z_]
一位空白字符:\s
一位除了换行外的任意字符:. - 很少使用,范围太广了
建议:优先使用预定义字符集,预定义满足不了我们再用备选字符集补充
问题:不管是备选字符集,还是预定义字符集,一个都只管一位
(4)量词:
规定一个字符集出现的次数:
1.有明确数量
字符集{n,m}:前边相邻的字符集,至少n个,最多m个
字符集{n,}:前边相邻的字符集,至少n个,多了不限
字符集{n}:前边相邻的字符集,必须n个
2.无明确数量
字符集?:前边相邻的字符集,可有可无,最多1个
字符集*:前边相邻的字符集,可有可无,多了不限
字符集+:前边相邻的字符集,至少一个,多了不限
(5)选择和分组
选择:在多个规则中选一个
规则1|规则2
分组:将多个字符集临时组成一组子规则
(规则1|规则2)
(6)指定匹配位置
^:开头
$:结尾
特殊:两者同时使用,前加^,后加$,表示从头到尾要求完全匹配 - 【验证】
(7)密码强度验证:
2-4位,可以输入数字、字母,但是必须出现一位大写和一位数字的组合
/^[0-9A-Za-z]{2,4}$/
预判公式:
(?![0-9]+$) -> 不能全由数字组成,可能有大写、小写、汉字、日文、特殊符号...
?![a-z]+$) -> 不能全由小写组成,可能有数字、大写、汉字、日文、特殊符号...
(?![0-9a-z]+$) -> 不能全由数字组成、也不能全由小写组成、也不能全由数字和小写的组合组成
一、支持正则表达式的字符串API
1、切割
var arr=str.split("固定切割符"/REGEXP)
2、替换:很有可能出现在笔试题中
(1)基本替换法
str=str.replace();
(2)高级替换法
str=str.replace(/正则表达式/后缀,function(a,b,c){
return 判断a关键字的长度,而返回不同的星星数量
});
(3)格式化
var id="500103198602215933";
var reg=/(\d{6})(\d{4})(\d{2})(\d{2})(\d{4})/;
id.replace(reg,function(a,b,c,d,e,f,g,h){
})
格式化:手机号
var phone="13452390312";
总结:何时前加^后加$,何时又该添加后缀g?
1、前加^后加$ - 验证
2、替换,你希望替换所有 - 必须加g
2、正则对象
创建:
1、直接量:var reg=/正则表达式/后缀
2、构造函数:var reg=new RegExp("正则表达式","后缀")
API:
1、验证:var bool=reg.test(用户输入的)