JavaScript API
File
当选择一个文件时,可以获得这个文件的描述对象
<input type="file" id="file" />
<script>
const file = document.getElementById('file')
file.addEventListener('change', (e) => {
console.dir(e.target.files[0])
})
</script>
File
lastModified: 1646398643613
lastModifiedDate: Fri Mar 04 2022 20:57:23 GMT+0800 (中国标准时间) {}
name: "world6.jpg"
size: 1179107
type: "image/jpeg"
webkitRelativePath: ""
[[Prototype]]: File
URL.createObjectURL()
该方法多数用于图片预览
实例,通过 input 上传图片预览出上传的图片:
<input type="file" accept="image/*" />
<img src="" alt="" />
<script>
const inp = document.querySelector('input')
const img = document.querySelector('img')
inp.onchange = function () {
const blob = URL.createObjectURL(inp.files[0])
img.setAttribute('src', blob)
}
</script>
MutationObserver 接口
描述
MutationObserver 接口
可以在 DOM 被修改时移步执行回调,使用 MutationObserver
可以观察整个文档、DOM 树的一部分或者元素。此外还可以观察元素的属性、子节点、文本,或者前三者的组合变化。
基本使用
MutationObserver
的实例要通过 MutationObserver
的构造函数,接收一个回调参数来创建
const mut = new MutationObserver(() => console.log('123'))
console.log(mut)
observe()
新创建的 MutationObserver
并不会关联 DOM 的任何部分,想要把 MutationObserver
和 DOM 关联起来,需要使用 observe()
方法。
这个方法必须接收两个参数,第一个是要观察其变化的 DOM 节点,以及一个 MutationObserverInit
对象。
<div id="app"></div>
<script>
const app = document.getElementById('app')
const mut = new MutationObserver(() => console.log('div 改变了'))
mut.observe(app, { attributes: true })
app.setAttribute('class', 'box') // 改变之后执行 mut 的回调
</script>
回调函数中的参数
MutationObserver
回调可以接收的一个参数,是一个数组,记录了当前那些部分发生了变化
<div id="app"></div>
<script>
const app = document.getElementById('app')
const mut = new MutationObserver((MutationRecord) =>
console.log(MutationRecord)
)
mut.observe(app, { attributes: true })
app.setAttribute('class', 'box')
app.setAttribute('data-app', 'add')
</script>
打印结果
(2) [MutationRecord, MutationRecord]
0: MutationRecord
addedNodes: NodeList []
attributeName: "class"
attributeNamespace: null
nextSibling: null
oldValue: null
previousSibling: null
removedNodes: NodeList []
target: div#app.box
type: "attributes"
[[Prototype]]: MutationRecord
1: MutationRecord
addedNodes: NodeList []
attributeName: "data-app"
attributeNamespace: null
nextSibling: null
oldValue: null
previousSibling: null
removedNodes: NodeList []
target: div#app.box
type: "attributes"
[[Prototype]]: MutationRecord
length: 2
[[Prototype]]: Array(0)
MutationObserver
接收的第二个参数是观察变化的 MutationObserver
的实例
const mut = new MutationObserver((MutationRecord, mutationObserver) => {
console.log(mut === mutationObserver) // true
})
disconnect()
默认情况下,只有元素不被垃圾回收,MutationObserver
的回调函数就会响应 DOM 变化事件,从而执行。使用 disconnect()
可以提前终止回调函数,也会抛弃已经加入任务队列的项目
<div id="app"></div>
<script>
const app = document.getElementById('app')
const mut = new MutationObserver(() => console.log('改变了'))
mut.observe(app, { attributes: true })
app.setAttribute('class', 'box')
mut.disconnect()
app.setAttribute('data-app', 'add')
// 没有日志输出
</script>
如果想让已经加入任务队列的项目执行完再调用可以使用 setTimeout()
来解决
<div id="app"></div>
<script>
const app = document.getElementById('app')
const mut = new MutationObserver(() => console.log('改变了'))
mut.observe(app, { attributes: true })
app.setAttribute('class', 'box') // 改变了
setTimeout(() => {
mut.disconnect()
app.setAttribute('data-app', 'add') // 没有日志输出
}, 0)
</script>
重用 MutationObserver
调用 disconnect()
的时候并不会结束 MutationObserver
的生命。还是可以重用这个观察者的,只需要将他在关联到目标节点即可。
<div id="app"></div>
<script>
const app = document.getElementById('app')
const mut = new MutationObserver((a) => console.log(a.map((x) => x.target)))
mut.observe(app, { attributes: true })
setTimeout(() => {
mut.disconnect() // 断开连接
app.setAttribute('class', 'box') // 没有日志输出
}, 0)
setTimeout(() => {
mut.observe(app, { attributes: true }) // 重新连接
app.setAttribute('class', 'box') // [div#app.box]
}, 0)
</script>
观察属性
MutationObserver.observe
可以接收两个参数,第二个参数为以及一个 MutationObserverInit
对象。可以观察节点属性的添加、删除、修改。需要属性变化注册回调,需要字啊 MutationObserverInit
对象中将 attributes
设置为 true
。
但是将 attributes
设置为 true
默认是观察所有的属性,如果想要观察几个或者多个属性,可以使用 attributeFilter
属性设置白名单,即一个属性名的数组集合
<div id="app"></div>
<script>
const app = document.getElementById('app')
const mut = new MutationObserver((a) => console.log(a.map((x) => x.target)))
mut.observe(app, { attributeFilter: ['food'] }) // 设置 food 为白名单
app.setAttribute('class', 'box') // [div#app.box]
app.setAttribute('food', 'admin') // 没有日志输出
</script>
如果想要在变化的记录中保存原来的值,可以将 attributeOldValue
设置为 true
<div id="app"></div>
<script>
const app = document.getElementById('app')
const mut = new MutationObserver((a) => console.log(a.map((x) => x.oldValue)))
mut.observe(app, { attributeOldValue: true })
app.setAttribute('class', 'box')
app.setAttribute('food', 'admin')
app.setAttribute('id', 'ccc')
// [null, null, 'app']
</script>
观察字符数据
将 characterData
设置为 true
可以为观察字符,当字符修改、删除、添加时,都可以触发回调
<div id="app">app</div>
<script>
const app = document.getElementById('app')
const mut = new MutationObserver((a) => console.log(a))
app.firstChild.textContent = '张三' //设置文本
mut.observe(app.firstChild, { characterData: true })
app.firstChild.textContent = 'abc'
app.firstChild.textContent = 'admin'
app.firstChild.textContent = 'ppt'
// 三次修改都被记录下来了
// (3) [MutationRecord, MutationRecord, MutationRecord]
</script>
如果想要在变化的记录中保存原来的值,可以将 characterDataOldValue
设置为 true
<div id="app">app</div>
<script>
const app = document.getElementById('app')
const mut = new MutationObserver((a) => console.log(a.map((x) => x.oldValue)))
app.firstChild.textContent = '张三' //设置文本
mut.observe(app.firstChild, { characterDataOldValue: true })
app.firstChild.textContent = 'abc'
app.firstChild.textContent = 'admin'
app.firstChild.textContent = 'ppt'
// 修改过的值都被记录下来了
// (3) ['张三', 'abc', 'admin']
</script>
观察子节点
将 childList
设置为 true
可以观察子节点,当子节点修改、删除、添加时,都可以触发回调
<div id="app"></div>
<script>
const app = document.getElementById('app')
const mut = new MutationObserver((a) => console.log(a))
mut.observe(app, { childList: true })
app.appendChild(document.createElement('p'))
// [MutationRecord]
</script>
观察子树
上述 将 childList
设置为 true
可以观察子节点,但是子节点的内部就观察不到了,所以还需要将 subtree
设置为 true
,即可扩展到这个元素的子树,所有后代节点。
<div id="app"></div>
<script>
const app = document.getElementById('app')
const mut = new MutationObserver((a) => console.log(a))
mut.observe(app, { attributes: true, subtree: true })
app.appendChild(document.createElement('p'))
app.querySelector('p').setAttribute('class', 'text')
// [MutationRecord]
</script>
但是有意思的是:观察子树的节点被移出子树之后,仍然可以触发变化事件
<div id="app"></div>
<script>
const app = document.getElementById('app')
const mut = new MutationObserver((a) => console.log(a))
const div1 = document.createElement('div')
mut.observe(app, { attributes: true, subtree: true }) // 观察子树
app.appendChild(div1) // 将新建的 div 放进 app 容器
document.body.insertBefore(div1, app) // 修改新建 div 的位置
div1.setAttribute('class', 'box1') // 改变属性
// 观察子树的节点被移出子树之后,仍然可以触发变化事件
// [MutationRecord]
</script>
takeRecords()
takeRecords()
方法可以清空 MutationObserver
的记录队列,取出并返回所有 MutationObserver
实例
<div id="app">哈哈</div>
<script>
const app = document.getElementById('app')
const mut = new MutationObserver((a) => console.log(a.map((x) => x.oldValue)))
mut.observe(app.firstChild, { characterDataOldValue: true })
app.firstChild.textContent = 'abc'
app.firstChild.textContent = 'admin'
app.firstChild.textContent = 'ppt'
console.log(mut.takeRecords()) // (3) [MutationRecord, MutationRecord, MutationRecord]
console.log(mut.takeRecords()) // []
</script>
这在希望断开与观目标的联系,但又希望处理由于调用 disconnect()
而被抛弃的记录队列中的 MutationObserver
实例还是比较有用的。
XMLHttpRequest
创建
创建方式
const xhr = new XMLHttpRequest()
open()
XHR 对象首先调用 open
方法,接受三个参数,请求类型,请求 URL,是否为异步
const url =
'https://infinitymcn.com/web/0705_renova_list/back_end/Renova_List/public/index.php/backstage/color/color'
xhr.open('get', url, false)
send()
要发送定义好的请求需要使用 send
方法
const url =
'https://infinitymcn.com/web/0705_renova_list/back_end/Renova_List/public/index.php/backstage/color/color'
xhr.open('get', url, false)
xhr.send(null)
send
可以作为请求体发送数据,如果不需要传入请求体,则必须传入 null
status
响应的 HTTP 状态
const url =
'https://infinitymcn.com/web/0705_renova_list/back_end/Renova_List/public/index.php/backstage/color/color'
xhr.open('get', url, false)
xhr.send(null)
console.log(xhr.status)
statusText
响应的 HTTP 状态描述
const url =
'https://infinitymcn.com/web/0705_renova_list/back_end/Renova_List/public/index.php/backstage/color/color'
xhr.open('get', url, false)
xhr.send(null)
console.log(xhr.status)
console.log(xhr.statusText)
SpeechSynthesisUtterance
可使用语音读出传入的文字内容
<button>say</button>
<script>
document.querySelector('button').addEventListener('click', () => {
const text = '你好,请问你是谁?'
const msg = new SpeechSynthesisUtterance(text)
window.speechSynthesis.speak(msg)
})
</script>
Document.createDocumentFragment()
可创建文档片段,如果一次性需要在 DOM 中添加多个元素,可以先试用它来创建一个临时的文档片段,最终统一将需要添加的节点插入 DOM 树,避免频繁修改 DOM 树导致大量重绘
<div class="app"></div>
<script>
const setChild = () => {
const fragment = document.createDocumentFragment()
for (let i = 0; i < 100; i++) {
const div = document.createElement('div')
div.innerText = i
fragment.appendChild(div)
}
document.querySelector('.app').appendChild(fragment)
}
setChild()
</script>
Crypto.randomUUID()
用于通过密码学安全的随机数生成器生成
console.log(crypto.randomUUID()) // f99f4d17-816f-4cbe-8c66-9a059c84410e