ECMAScript(核心) | 描述了JS的语法和基本对象。 |
---|---|
文档对象模型 (DOM) | 处理网页内容的方法和接口 |
浏览器对象模型(BOM) | 与浏览器交互的方法和接口 |
(1) DOM 是 W3C 的标准; [所有浏览器公共遵守的标准]
(2) BOM 是 各个浏览器厂商根据 DOM在各自浏览器上的实现;[表现为不同浏览器定义有差别,实现方式不同]
(3) window 是 BOM 对象,而非 js 对象;javacsript是通过访问BOM(Browser Object Model)对象来访问、控制、修改客户端(浏览器)
2、DOM事件流包括三个阶段
(1). 事件捕获阶段 : 当事件发生时,首先发生的是事件捕获,为父元素截获事件提供了机会。它认为当某个事件发生时,父元素应该更早接收到事件,具体元素则最后接收到事件。
(2). 处于目标阶段 : 事件到了具体元素时,在具体元素上发生,并且被看成冒泡阶段的一部分。随后,冒泡阶段发生,事件开始冒泡,然后逐级传播到较为不具体的节点。
(3). 事件冒泡阶段 : 事件冒泡过程,是可以被阻止的。防止事件冒泡而带来不必要的错误和困扰。这个方法就是: stopPropagation()
。
当然,由于时代更迭,事件冒泡方式更胜一筹。所以放心的使用事件冒泡,有特殊需要再使用事件捕获即可。
var el = document.getElementById('test')
el.addEventListener('click', function (e) {
alert(11)
}, true)
el.addEventListener('click', function (e) {
alert(33)
}, false)
运行结果:网页先后三次弹出警示框,顺序为:11 --> 22 --> 33
4、网页错误监控
window.onerror是一个全局变量,默认值为null。当有js运行时错误触发时,window会触发error事件。
addEventListener('error')监听js运行时错误事件,会比window.onerror先触发,与onerror的功能大体类似,不同的是它还可以可以全局捕获资源(如img,css...)加载异常的错误。
5、网页性能、错误监控代码
网页代码:
monitor.js: 需放到head标签先于可能抛错误代码执行
// 保存监控信息
let monitor = {
performance: {}, // 性能监控
resources: {}, // 资源监控
errors: [], // 错误监控
user: {
// Screen 对象包含有关客户端显示屏幕的信息。
screen: screen.width, // 屏幕的总宽度
height: screen.height,
// Navigator 对象包含有关浏览器的信息
platform: navigator.platform, // 运行浏览器的操作系统
userAgent: navigator.userAgent, // 浏览器用于 HTTP 请求的UA头的值
language: navigator.language // 浏览器 UI 的语言
}
}
// 性能监控
const getPerformance = () => {
if (!window.performance) return
const timing = window.performance.timing
const performance = {
redirect: timing.redirectEnd - timing.redirectStart, // 最后一个HTTP重定向完成时 - 第一个HTTP重定向开始时
whiteScreen: timing.domLoading - timing.navigationStart, // 当前网页DOM结构开始解析时 - 上一个文档卸载(unload)结束时
dom: timing.domComplete - timing.domLoading, // 当前文档解析完成 - 当前网页DOM结构开始解析时
load: timing.loadEventEnd - timing.navigationStart, // 加载事件完成时 - 上一个文档卸载(unload)结束时
unload: timing.unloadEventEnd - timing.unloadEventStart, // unload事件处理完成时 - unload事件抛出时
request: timing.responseEnd - timing.requestStart, // 浏览器从服务器收到(或从本地缓存读取,或从本地资源读取)最后一个字节时 - 浏览器向服务器发出HTTP请求时(或开始读取本地缓存时)
time: new Date().getTime()
}
return performance
}
// 资源监控
const getResources = () => {
if (!window.performance) return
const data = window.performance.getEntriesByType('resource')
const resource = {
xmlhttprequest: [],
css: [],
other: [],
script: [],
img: [],
link: [],
fetch: [],
time: new Date().getTime()
}
data.forEach(item => {
const arr = resource[item.initiatorType]
arr && arr.push({
name: item.name, // 资源URL
duration: item.duration.toFixed(2), // fetch资源耗时
size: item.transferSize, // fetch获取资源的大小,遇到本地缓存资源或跨域资源时返回0
protocol: item.nextHopProtocol // 获取资源的网络协议
})
})
return resource
}
// 错误监控
addEventListener('error', e => {
const target = e.target
console.log(target);
if (target != window) {
monitor.errors.push({
type: target.localName,
url: target.src || target.href,
msg: (target.src || target.href) + 'is load error',
time: new Date().getTime()
})
}
console.log('所有的错误信息--捕获JS执行时错误、资源加载错误');
console.log(monitor.errors);
}, true)
window.onerror = function (msg, url, row, col, error) {
monitor.errors.push({
type: 'javascript',
row: row,
col: col,
msg: error && error.stack ? error.stack : msg,
url: url,
time: new Date().getTime()
})
console.log('所有的错误信息--捕获JS执行时错误');
console.log(monitor.errors);
}
addEventListener('unhandledrejection', e => {
monitor.errors.push({
type: 'promise',
msg: (e.reason && e.reason.msg) || e.reason || '',
time: new Date().getTime()
})
console.log('所有的错误信息--捕获Promise异常未处理错误');
console.log(monitor.errors);
})
window.onload = () => {
if (window.requestIdleCallback) {
// requestIdleCallback方法 将在浏览器的空闲时段内调用的函数排队
window.requestIdleCallback(() => {
monitor.performance = getPerformance()
monitor.resources = getResources()
console.log('页面性能信息');
console.log(monitor.performance)
console.log('页面资源信息');
console.log(monitor.resources)
})
} else {
setTimeout(() => {
monitor.performance = getPerformance()
monitor.resources = getResources()
console.log('页面性能信息');
console.log(monitor.performance)
console.log('页面资源信息');
console.log(monitor.resources)
}, 0)
}
}