- 作用域
浏览器加载HTML代码的时候,首先会提供一个供全局JS代码执行的环境 -->全局作用域(window/global),全局作用域当网页关闭时才会销毁,私有作用域当
返回一个函数并被外界引用,不会销毁,其他情况下销毁
复制代码
- js内存分类
栈内存:用来提供一个供js代码执行环境,作用域(全局作用域和私有作用域)
堆内存:用来存储引用数据类型的值,对象存储属性名和属性值,函数存储的是代码字符串
复制代码
- getBoundingClientRect
x:元素左上角相对于视口的横坐标
left:元素左上角相对于视口的横坐标,与x属性相等
right:元素右边界相对于视口的横坐标(等于x加上width)
width:元素宽度(等于right减去left)
y:元素顶部相对于视口的纵坐标
top:元素顶部相对于视口的纵坐标,与y属性相等
bottom:元素底部相对于视口的纵坐标
height:元素高度(等于y加上height)
注意,getBoundingClientRect方法的所有属性,都把边框(border属性)算作元素的一部分。也就是说,都是从边框外缘的各个点来计算。因此,width和height包括了元素本身 + padding + border。
复制代码
- 浏览器执行机制
由于 JavaScript 是可操纵 DOM 的,如果在修改这些元素属性同时渲染界面(即 JavaScript 线程和 UI 线程同时运行),那么渲染线程前后获得的元素数据就可能不一致了。为了防止渲染出现不可预期的结果,浏览器设置 UI 渲染线程与 JavaScript 引擎线程为互斥的关系,当 JavaScript 引擎线程执行时 UI 渲染线程会被挂起,UI 更新会被保存在一个队列中等到 JavaScript 引擎线程空闲时立即被执行。
DOM添加是同步的,但是dom渲染是异步的,js线程和ui线程是互斥的,故是异步
复制代码
- 三目运算符如果:后面不做任何操作,就写null
- DOM的基础知识
属性
Node.prototype.nextElementSibling 下一个element元素节点
Node.prototype.previousElementSibling 上一个element元素节点
ParentNode.firstElementChild
ParentNode.lastElementChild
Node.prototype.parentNode 返回当前节点的父节点
element.children返回子节点
方法
Node.prototype.appendChild()
var p = document.createElement('p');
document.body.appendChild(p);
Node.prototype.cloneNode()
var cloneUL = document.querySelector('ul').cloneNode(true); 克隆出来的新节点
Node.prototype.insertBefore()
var insertedNode = parentNode.insertBefore(newNode, referenceNode);
Node.prototype.removeChild()
divA.parentNode.removeChild(divA)
Node.prototype.replaceChild()
var replacedNode = parentNode.replaceChild(newChild, oldChild);
复制代码
- document节点
document节点对象代表整个文档,每张网页都有自己的document对象
document的获取
正常的网页,直接使用document或window.document。
iframe框架里面的网页,使用iframe节点的contentDocument属性。
document.documentElement 指的是html节点
document.querySelector(),
document.querySelectorAll()
document.getElementsByTagName()
document.getElementsByClassName()
document.getElementsByName()
document.getElementById()
document.createElement()
document.createTextNode()
document.createComment()
document.createDocumentFragment()
复制代码
- Element
Element.id: 指定元素的id属性
Element.tagName: 返回指定元素的大写标签名
Element.className,Element.classList
add():增加一个 class。
remove():移除一个 class。
contains():检查当前元素是否包含某个 class。
toggle():将某个 class 移入或移出当前元素。
item():返回指定索引位置的 class。
toString():将 class 的列表转为字符串。
Element.dataset: 自定义data-属性
Element.innerHTML
Element.clientHeight,Element.clientWidth width+padding
Element.clientLeft,Element.clientTop 边框宽度
Element.scrollHeight,Element.scrollWidth
Element.scrollLeft,Element.scrollTop 表示当前元素的水平滚动条向右侧滚动的像素数量 (可读写)
Element.offsetParent 返回最靠近当前元素的、并且 CSS 的position属性不等于static的上层元素
Element.offsetHeight,Element.offsetWidth
Element.offsetLeft,Element.offsetTop Element.offsetLeft返回当前元素左上角相对于Element.offsetParent节点的水平位移,Element.offsetTop返回垂直位移,单位为像素。通常,这两个值是指相对于父节点的位移。
Element.style
Element.children
Element.firstElementChild, Element.lastElementChild
Element.nextElementSibling,Element.previousElementSibling
实例方法
getAttribute():读取某个属性的值
getAttributeNames():返回当前元素的所有属性名
setAttribute():写入属性值
hasAttribute():某个属性是否存在
hasAttributes():当前元素是否有属性
removeAttribute():删除属性
Element.querySelector()
Element.querySelectorAll()
Element.getElementsByClassName()
Element.getElementsByTagName()
Element.closest()
事件相关方法
Element.addEventListener():添加事件的回调函数
Element.removeEventListener():移除事件监听函数
Element.getBoundingClientRect()
Element.insertAdjacentElement()
beforebegin:当前元素之前
afterbegin:当前元素内部的第一个子节点前面
beforeend:当前元素内部的最后一个子节点后面
afterend:当前元素之后
Element.remove()
Element.focus(),Element.blur()
Element.click()
复制代码
- 属性
getAttribute()
getAttributeNames()
setAttribute()
hasAttribute()
hasAttributes()
removeAttribute()
这六个方法对所有属性(包括用户自定义的属性)都适用。
复制代码
- Mutation Observer API
- 事件模型
click:按下鼠标(通常是按下主按钮)时触发。
dblclick:在同一个元素上双击鼠标时触发。
mousedown:按下鼠标键时触发。
mouseup:释放按下的鼠标键时触发。
mousemove:当鼠标在一个节点内部移动时触发。当鼠标持续移动时,该事件会连续触发。为了避免性能问题,建议对该事件的监听函数做一些限定,比如限定一段时间内只能运行一次。
mouseenter:鼠标进入一个节点时触发,进入子节点不会触发这个事件(详见后文)。
mouseover:鼠标进入一个节点时触发,进入子节点会再一次触发这个事件(详见后文)。
mouseout:鼠标离开一个节点时触发,离开父节点也会触发这个事件(详见后文)。
mouseleave:鼠标离开一个节点时触发,离开父节点不会触发这个事件(详见后文)。
contextmenu:按下鼠标右键时(上下文菜单出现前)触发,或者按下“上下文菜单键”时触发。
wheel:滚动鼠标的滚轮时触发,该事件继承的是WheelEvent接口。
MouseEvent.clientX,MouseEvent.clientY
MouseEvent.pageX,MouseEvent.pageY
复制代码
- 进度事件
error:由于错误导致外部资源无法加载时触发。
load:外部资源加载成功时触发。
复制代码
- 表单事件
input事件的一个特点,就是会连续触发,比如用户每按下一次按键,就会触发一次input事件。
change在元素失去焦点时发生
复制代码
- URL 的编码和解码
encodeURI()
encodeURI('http://www.example.com/q=春节')// "http://www.example.com/q=%E6%98%A5%E8%8A%82"
encodeURIComponent() //不能直接编码url
encodeURIComponent('http://www.example.com/q=春节')// http%3A%2F%2Fwww.example.com%2Fq%3D%E6%98%A5%E8%8A%82
decodeURI()
decodeURIComponent()
复制代码
- History
在历史移动
History.back()
History.forward()
History.go()
History.pushState()
History.replaceState()
事件
popstate 事件
复制代码
- 渲染引擎处理网页,通常分成四个阶段
解析代码:HTML 代码解析为 DOM,CSS 代码解析为 CSSOM(CSS Object Model)。
对象合成:将 DOM 和 CSSOM 合成一棵渲染树(render tree)。
布局:计算出渲染树的布局(layout)。
绘制:将渲染树绘制到屏幕。
复制代码
- 重流和重绘
布局发生变化是重流,颜色等发生变化是重绘
重流和重绘并不一定一起发生,重流必然导致重绘,重绘不一定需要重流。比如改变元素颜色,只会导致重绘,而不会导致重流;改变元素的布局,则会导致重绘和重流。
优化技巧
读取 DOM 或者写入 DOM,尽量写在一起,不要混杂。不要读取一个 DOM 节点,然后立刻写入,接着再读取一个 DOM 节点。
缓存 DOM 信息。
不要一项一项地改变样式,而是使用 CSS class 一次性改变样式。
使用documentFragment操作 DOM
动画使用absolute定位或fixed定位,这样可以减少对其他元素的影响。
只在必要时才显示隐藏元素。
使用window.requestAnimationFrame(),因为它可以把代码推迟到下一次重流时执行,而不是立即要求页面重流。
使用虚拟 DOM(virtual DOM)库。
复制代码
- slice
用法:arrayObj.slice(start,end)
arrayObj - 原始数组;
start - 必填;设定新数组的起始位置;如果是负数,则表示从数组尾部开始算起(-1
指最后一个元素,-2 指倒数第二个元素,以此类推)。
end - 可选;设定新数组的结束位置;如果不填写该参数,默认到数组结尾;如果是负数,则表示从数组尾部开始算起(-1 指最后一个元素,-2
指倒数第二个元素,以此类推)。
复制代码