一、Javascript組成包括如下3個部分:javascript
ECMAScript(核心) | 描述了JS的語法和基本對象。 |
---|---|
文檔對象模型 (DOM) | 處理網頁內容的方法和接口 |
瀏覽器對象模型(BOM) | 與瀏覽器交互的方法和接口 |
(1) DOM 是 W3C 的標準; [全部瀏覽器公共遵照的標準]
(2) BOM 是 各個瀏覽器廠商根據 DOM在各自瀏覽器上的實現;[表現爲不一樣瀏覽器定義有差異,實現方式不一樣]
(3) window 是 BOM 對象,而非 js 對象;javacsript是經過訪問BOM(Browser Object Model)對象來訪問、控制、修改客戶端(瀏覽器)css
如圖所示(截圖W3CSchool目錄):
java
二、DOM事件流包括三個階段
(1). 事件捕獲階段 : 當事件發生時,首先發生的是事件捕獲,爲父元素截獲事件提供了機會。它認爲當某個事件發生時,父元素應該更早接收到事件,具體元素則最後接收到事件。
(2). 處於目標階段 : 事件到了具體元素時,在具體元素上發生,而且被當作冒泡階段的一部分。隨後,冒泡階段發生,事件開始冒泡,而後逐級傳播到較爲不具體的節點。
(3). 事件冒泡階段 : 事件冒泡過程,是能夠被阻止的。防止事件冒泡而帶來沒必要要的錯誤和困擾。這個方法就是: stopPropagation()
。segmentfault
固然,因爲時代更迭,事件冒泡方式更勝一籌。因此放心的使用事件冒泡,有特殊須要再使用事件捕獲便可。跨域
<div id="test"> <button onclick="alert(22)">DOM事件流</button> </div> var el = document.getElementById('test') el.addEventListener('click', function (e) { alert(11) }, true) el.addEventListener('click', function (e) { alert(33) }, false) 運行結果:網頁前後三次彈出警示框,順序爲:11 --> 22 --> 33
如圖所示(圖片源於網絡,若侵權請告知):
promise
如圖所示(圖片源於網絡,若侵權請告知):
緩存
四、網頁錯誤監控
window.onerror是一個全局變量,默認值爲null。當有js運行時錯誤觸發時,window會觸發error事件。
addEventListener('error')監聽js運行時錯誤事件,會比window.onerror先觸發,與onerror的功能大致相似,不一樣的是它還能夠能夠全局捕獲資源(如img,css...)加載異常的錯誤。服務器
五、網頁性能、錯誤監控代碼
網頁代碼:網絡
<head> <script src="./monitor.js"></script> </head> <body> <button onclick="throw new Error({message: '手動拋出錯誤1'})">錯誤測試按鈕1</button> <button onclick="Promise.reject('promise error')">錯誤測試按鈕2</button> <button onclick="throw('手動拋出錯誤2')">錯誤測試按鈕3</button> </body>
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) } }