JS Web API
-
DOM
- DOM是那种数据结构
树(DOM树) - DOM操作的常用API
见知识点 - attr和property的区别
property:修改对象属性,不会提现到html结构中
attribute:修改html属性,会改变html结构,两者都可能引起DOM重新渲染
- 一次性插入多个DOM节点,考虑性能
使用fragment,DOM节点缓存
- DOM是那种数据结构
-
BOM
- 如何识别浏览器的类型
网上搜索UA方案 - 分析拆解URL各个部分
查看location相关API
- 如何识别浏览器的类型
-
事件
- 编写一个通用的事件监听函数
function bindEvent(ele, type, selector, fn) { if (fn == null) { fn = selector selector = null } ele.addEventListener(type, function (e) { const target = e.target; if (selector) { // 代理 if (target.matches(selector)) { fn.call(target, event) } } else { // 普通 fn.call(target, event) } }) }
- 事件冒泡的流程
见知识点2 - 无限下拉的图片列表,如何监听每个图片的点击
见知识点3
DOM知识点
- DOM本质
DOM本质是一棵类似于xml结构的树,全称为Document Object Model - DOM节点操作
- 获取DOM节点:如document.getElementById(‘div’)
- property: 节点的原生属性,如imgDom.src
- attribute: 节点的自定义属性,如imgDom.setAttribute(‘index’, 1)
- DOM结构操作
- createElement
- appendChild
- removeChild
- DOM性能
- 避免频繁地操作DOM
- 对DOM查询做缓存,举个例子:
// 缓存查询结果 const pList = document.getElementsByClassName('p'); const length = pList.length; for (let i = 0; i < length; i++) { // 只进行一次DOM查询 }
- 将频繁操作改为一次操作,举个例子:
const fragment = document.createDocumentFragment(); for (let i = 0; i < 10; i++) { // 只进行一次DOM查询 let li = document.createElement('li') li.innerHTML = i + ''; fragment.appendChild(li) } document.getElementById('list').appendChild(fragment)
BOM知识点
- navigator
用于识别浏览器的api - screen
查看屏幕相关信息 - location
用于查看浏览器url信息,location.protocol,location.host,location.search - history
用于设置浏览器后退和前进,history.back()、history.forward()
事件知识点
- 事件绑定
function bindEvent(ele, type, fn, options = false) {
if (ele.addEventListener) {
ele.addEventListener(type, fn, options)
} else if (ele.attachEvent) {
ele.attachEvent(`on${type}`, fn)
} else {
ele[`on${type}`] = fn
}
}
const a = document.getElementById('link');
bindEvent(a, 'click', e => {
e.preventDefault(); // 阻止默认行为
alert('clicked')
})
- 事件冒泡
事件冒泡即对付元素绑定的点击事件,子元素被点击时,事件会向上冒泡,最终父元素的点击事件也会被触发。举个例子
<div class="container">
<p>文本一</p>
<p>文本二</p>
<p>文本三</p>
</div>
<script>
const body = document.body
const container = document.getElementsByClassName('container')
bindEvent(container, 'click', function (e) {
console.log('container cliced', e.target)
})
bindEvent(body, 'click', function (e) {
// p标签被点击时,该事件也会被触发
console.log('body cliced', e.target)
})
// 冒泡顺序是从里到外,p clicked => container clicked => body clicked
// 阻止冒泡需要使用e.stopPropagation
</script>
- 事件代理
时间代理基于事件冒泡,多用于处理多个元素绑定事件,代码简洁,减少了浏览器内存消耗,但是不要滥用,举个例子
<div class="container">
<a href="#">a1</a>
<a href="#">a2</a>
<a href="#">a3</a>
<a href="#">a4</a>
<a href="#">a5</a>
<a href="#">a6</a>
<a href="#">a7</a>
</div>
<script>
bindEvent(body, 'click', function (e) {
e.preventDefault()
if(e.target.tagName === 'A') {
console.log('anchor has been clicked')
}
})
</script>