DOM:
核心dom:可以操作HTML和XML
HTML DOM:只能操作HTML,不能访问自定义属性
XML DOM:只能操作XML,已淘汰
查找元素
1、关系:父、子、兄弟
2、直接找元素:特性
let elem=document.getElementByXXXX()//返回的是一个动态集合(HTMLcollection)
通过CSS选择器进行查找:
let elem=document.querySelector("任意CSS选择器")
缺点:只能找到第一个元素
let elem=document.querySelectorALL("任意选择器")
优点:找到了是一个集合,没找到是一个空集合
2、查找复杂元素很舒服、方便
3、返回的是一个静态集合(Nodelist)
面试题:docunment.getXXX与document.querySelector的对比?
1、后者更适合查找复杂元素
2、前者是一个动态集合,后者是静态集合
静态集合与动态集合的区别?
1、动态:每一个DOM发生变化的时候,都会悄悄地查找一遍页面元素,让页面与数据保持一致,效率降低,且不支持forEach
2、静态:DOM发生变化的时候并不会查找页面,效率提高,且支持forEach
操作样式
1、内联
获取:elem.style.属性名
设置:elem.style.属性名="属性值"
2、样式表:过于麻烦,建议不用
1、获取样式表:
let sheet=document.stylesheet[i]
2、获取所有的样式规则:
let rules=sheet.cssRules
3、数出你要操作的第几个样式:
let rule=rules[i]
4、操作
rule.style.属性名="属性值"
操作属性
1、获取属性值
核心DOM:elem.getAttribute("属性名")
HTML DOM:elem.属性名
2、删除属性:设置为空字符串只是说明属性值被删除了,但是属性名还在,有一些属性并不需要属性值就能够生效(checked/readonly/href)
核心DOM:elem.removeAttribute("属性名");
HTML DOM:elem.属性名=""
3、操作内容
innerHTML/innerText/value
4、如何创建元素以及上树
①、创建空标签:
let elem=document.creatElement("标签名")
②、为其设置必要的属性和事件
elem.属性名="属性值"
elem.on事件名=function(){}
③上树:
1、父元素.appendChild(elem)//父元素的末尾加上
2、父元素.insertBefore(elem,已有子元素)//在父元素中的已有子元素之前添加
3、父元素.replaceChild(elem,已有子元素)//替换掉你的已有子元素
删除
elem.remove();
扩展:
1、inuput/textarea的两个专属事件:onfocus(获取焦点)onblur(失去焦点)
2、创建: let变量名=值;
作用:解决了声明提前
②带来了块级作用域;{}就是一个块
③如果使用let当作下标去绑定事件,会记录着你的下标,不需要再自定义下标了,forEach的i也是let创建的
3、类数组对象转为普通数组:
x=Array.from(类数组)
递归
简单的来说就是在函数中再调用一次自己;
使用:专门用来遍历层级不明确的dom树或者数据的
function 函数名(root){
1、第一层做操作,直接做
2、判断是否有下一层,若是有下一层就再次调用自己,但是传入的实参要变成下一层
}
函数名(根节点)
算法:深度优先算法,优先遍历当前节点的子节点,子节点遍历完之后才会遍历兄弟节点
缺陷:性能相对较差,同时开启了大量的数据调用
递归VS纯循环:
递归较为简单,性能低,纯循环比较难,性能高
2、绑定事件
1、在HTML上直接书写:不推荐
<elem on事件名=function()></elem>
2、在js中
elem.on事件名=function(){操作}
优点:①、符合内容与样式的分离
②、动态绑定,一个可绑定多个元素
③、无兼容问题
3、在JS中使用事件API
主流:elem.addEventListener("事件名",callback)
老IE:elem.attachEvent("事件名",callback)
优点:①、符合内容与样式的分离
②、动态绑定,一个可绑定多个元素 ③、支持绑定多个函数对象
缺点:兼容问题
扩展:
select&option可简化创建上树
select.add(new Option("innerHTML","value"))
event(事件对象):
1、事件周期:三个阶段
①捕获阶段:由外向内
②目标优先触发:目标元素->当前点击的实际发生的元素
③冒泡触发:由内向外
2、获取事件对象event:
主流:会自动作为事件处理函数的第一个形参传入e,老IE使用event,兼容使用event
①获取鼠标的位置/坐标:
相对于屏幕的坐标:e.screenX/Y
相对于浏览器:e.clientX/Y
相对于网页:e.page.X/Y
②阻止冒泡
主流:e.stopPropagation
老IE(兼容):e.cancel.Bubble
③事件委托
优化:如果多个子元素绑定了相同/相似的事件,最好只给父元素绑定一次
主流:e.target
老IE(兼容):e.srcElement
④阻止浏览器的默认行为;
主流:e.preventDefault
老IE(兼容):e.returnValue=false
新学的事件:
1、右键事件:window.oncontextmenu;
2、键盘事件:
window.onkeydown---按下和按住任何键都会触发
window.onkeypress---按下或者按住字母数字空格回车触发
window.onkeyup---松开任意键的时候触发
3、获取键盘的键码:
e.keyCode---获取键码,百度查看e.keyCode表
事件的取消绑定: 1、elem.on事件名=()=>{};那么想要取消就要:elem.on事件名=null
2、如果你使用的是elem.addEventListener("事件名",f1),如果要取消就使用:elem.removeEventListener("事件名",f1),事件名和回调函数必须一模一样,f1是调用函数,但是不加()
this的指向:
①单个元素绑定,指代当前元素
②多个元素绑定:当前触发的元素
③箭头函数,指外部对象
④函数中的this->当前正在调用函数的人
⑤定时器:window
ES5强制改变this的指向:
call/apply:临时替代了函数中的this
语法:
1.函数名.call(借用的对象,实参....)-单独传入每个参数
2.函数名.apply(借用的对象,数组)只能传入一个实参数组
强调:call/apply相当于立刻调用函数,会立刻执行
bind:永久的替换了函数中的this
语法
let 新函数名=函数名.bind(指定对象,永久固定的实参)
三件事:
①创建了一个与原函数功能完全相同的新函数
②将新函数的this永久绑定为了指定对象,别人接不走
③将新函数的部分实参永久固定
强调:bind绑定的新函数无法被call/apply借用,不会立刻调用,需要手动调用
固定套路:
1.Math.max/min.apply(Math,数组)
2.类数组->数组
①Array.from(类数组)
②x=Array.protoType.slice.call/apply
3.判断x是不是数组
Object.prototype.toString.call(x)=="[object Array]"true就是一个数组
ES6
1、let
2、const 常量名=值
3、箭头函数:简化一切回调函数
4、模板字符串:可以直接识别变量,不用+再去进行凭借操作
`我的名字叫${name}`
5、解构赋值:解析结构再进行赋值
使用:1、类数组的解构赋值
let[a,b,c]=[1,2,3]
2、类似对象的解构赋值:
let {a,b=默认值,c}={a:1,c:3}
3、调用函数时,传递的实参顺序无所谓
function({形参,...}){}
函数名({实参,...})=>无所谓顺序
4、函数的返回结果,可以有多个
function f1(){
let a=1,b=2
return[a,b]
}
let[a,b]=f1()
5、Set与MAp set可以用来数组去重
[...new Set(arr)]
正则表达式
使用:
最简单的正则就是关键字原文:"no"->/no/
后缀g找全部 i忽略大小写
2、备选字符集:/[备选字符集]/
强调:一个中括号代表一位字符
2、前面加^后面加$,两者同时使用代表从头到尾完全匹配
/^[备选字符集]$/
特殊:如果备选字符集的ASCII码是连续的可以使用-
一位数字:[0-9]
一位字母:[A-Za-z]
一位汉字:[\u4e00-\u9fa5]
除了XXX以外:[^]
3、预定义字符集:
一位数字:\d
一位数字、字母、下划线:\w
一位空白字符:\s
一位除了换行以外的元素:.
建议:优先使用预定义
4、量词:规定一个字符出现的次数:
1/{n,m}至少出现n个,至多出现m个
2/{n,}至少出现n个,上无限制
3/{n}只能出现n个
4/?可有可无,最多一个
5/*可有可无,上限制
6/+至少一个,上无限制
5、选择和分组:
选择:
规则1|规则2
分组:(规则1|规则2)
6.开头^结尾$
7、预判:(?!+$)
(?![0-9]+$)不能全数字
(?![0-9a-z]+$)不能全数字,不能全小写,也不能全数字和小写的组合
2、支持正则的API
一、切割:
let arr=str.splice(RegExp)
二、替换
基础替换:
let newstr str.replace(RegExp,"新内容")
高级替换:
let newstr=str.replace(/reg/,function(key,i,str){
key是关键字
i是下标
str是原文本身
})
三、格式化:
let newwstr=str.replace(reg,function(a,b,c,d){
若是正则中出现了分组,那么会得到更多的形参,第一个为关键字,第二个形参为第一个分组的内容、倒数第二个是下标,最后一个是原文
})
3、正则对象
1、直接量:
let reg=/正则表达式/后缀
2、构造函数:
let reg=new RegExp("正则表达式","后缀")
API
验证:let bool=reg.test(str);true为成功,false为失败