瀏覽器內核css
支撐瀏覽器運行的最核心的程序html
IE 瀏覽器內核 Trident內核,也是俗稱的IE內核
Chrome 瀏覽器內核 統稱爲 Chromium 內核或 Chrome 內核,之前是 Webkit 內核,如今是 Blink 內核
Firefox 瀏覽器內核 Gecko 內核,俗稱 Firefox 內核
Safari 瀏覽器內核 Webkit 內核
Opera 瀏覽器內核 最初是本身的 Presto 內核,後來是 Webkit,如今是 Blink 內核編程
360瀏覽器、獵豹瀏覽器內核:IE+Chrome雙內核;
搜狗、遨遊、QQ瀏覽器內核:Trident(兼容模式)+Webkit(高速模式);
百度瀏覽器、世界之窗內核:IE內核;
2345瀏覽器內核:之前是IE內核,如今也是IE+Chrome雙內核;數組
主線程,從上而下執行代碼,將代碼產生的相關任務分配給對應的分線程瀏覽器
分線程 每當有 事件回調函數 在知足必定條件後,加入回調隊列的末尾網絡
js 執行完全部代碼之後,js 開啓輪詢,會不斷地 輪詢回調隊列,執行隊列中的回調函數多線程
主線程:異步
js 引擎模塊 負責 js 程序的編譯與運行ide
html/css 文檔解析模塊 負責 頁面文本 的解析異步編程
DOM/CSS 模塊 負責 DOM 和 css 在內存中的處理
佈局和渲染模塊 負責頁面的佈局和效果的繪製(內存中的對象)
分線程:
定時器模塊 負責定時器的管理
DOM事件響應模塊 負責事件的管理
網絡請求模塊 負責 AJAX 的請求
進程
程序的一次執行,佔有一片獨有的內存空間
單進程
多進程,同一時間可作多件事
線程
調度 CPU 執行具體程序,是CPU的最小調度單元
是進程內的一個獨立執行單元
應用程序必須運行在某個進程的某個線程上
一個進程至少有一個運行的線程——主線程,進程啓動後自動建立
一個進程內的數據 是能夠被多個線程直接共享的
進程與進程之間的數據是不共享的
線程池: 保存多個線程對象的容器,實現線程對象的反覆利用
H5 規範提供了 js 分線程——Web Workers
需求: 主線程 若是再進行大量計算任務時,沒法執行其餘任務
1. index.js 使用分線程
var newWorker = new Worker(./worker.js); // 開啓一個分線程 // 綁定接受分線程消息的事件 newWorker.onmessage = function(e){ console.log("分線程: "+e.data); }; btn.onclick = function(){ newWorker.postMessage(number.value); // 主線程 通知分線程 開始執行 };
2. worker.js 寫 分線程 接收主線程發送的消息
var onmessage = function(event){ // 接收消息的回調函數 event var data = event.data; var result = fibonacci(+data); // 計算 postMassage(result); };
function fibonacci(num){
return (num < 3)?1:(fabonacci(num-1)+fabonacci(num-2));
}
1. 事件 Event
事件的本質是: 程序各個組成部分之間的一種通訊方式,也是 異步編程 的一種實現
DOM 的事件操做 分爲: 監聽 和 觸發 都定義在 EventTarget 接口____
全部節點對象都部署了 EventTarget 接口,其餘一些須要事件通訊的瀏覽器內置對象(好比,XMLHttpRequest、AudioNode、AudioContext)也部署了這個接口。
.addEventListener(); 綁定事件的監聽函數
.removeEventListener(); 移除事件的監聽函數
.dispatchEvent(); 觸發事件
用於在當前節點或對象上,定義一個特定事件的監聽函數。
一旦這個事件發生,就會執行監聽函數。
能夠爲針對當前對象的同一個事件,添加多個不一樣的監聽函數。這些函數按照添加順序觸發,即先添加先觸發。
若是爲同一個事件屢次添加同一個監聽函數,該函數只會執行一次,多餘的添加將自動被去除(沒必要使用removeEventListener方法手動去除)。
eventType 事件名稱,大小寫敏感。
listener 監聽函數。事件發生時,會調用該監聽函數。
btn.addEventListener('click', { handleEvent: function (event) { console.log('click'); } }, false);
[useCapture] 是否在捕獲階段(capture)觸發(參見後文《事件的傳播》部分),默認爲 false(監聽函數只在冒泡階段被觸發)。該參數可選
useCapture
,還能夠是一個屬性配置對象capture: 布爾值,表示該事件是否在捕獲階段觸發監聽函數。
once: 布爾值,表示監聽函數是否只觸發一次,而後就自動移除。
passive: 布爾值,表示監聽函數不會調用事件的 preventDefault 方法。默認爲 true 若是監聽函數調用了,瀏覽器將忽略這個要求,並在監控臺輸出一行錯誤。
ele.addEventListener('click', function (event) { // 只執行一次的代碼 }, {once: true});
var box = document.getElementById('div1'); box.addEventListener('click', function () { myPrint('Hello'); }, false); function myPrint(x) { console.log(x); }
用來移除 .addEventListener() 方法添加的事件監聽函數。
該方法沒有返回值
listener 在綁定時是 匿名函數,那麼將沒法直接用 .removeEventListener() 移除。
在當前節點上觸發指定事件,從而觸發監聽函數的執行。
只要有一個監聽函數調用了 Event.preventDefault(),則返回值爲 false,不然爲 true
ele.addEventListener('click', hello, false); var event = new Event('click'); ele.dispatchEvent(event); // 主動觸發 click 事件
2. 瀏覽器的事件模型
就是經過監聽函數(listener)對事件作出反應。
事件發生後,瀏覽器監聽到了這個事件,就會執行對應的監聽函數。
____這是事件驅動編程模式(event-driven)的主要編程方式
在 html 標籤 中直接綁定
<body onload="doSomething()"> <!-- 等同於 document.body.setAttribute("onload", "doSomething()"); --> <div id="box" onclick="console.log('觸發事件')"> // this 輸出 box
在 js 代碼中,給元素對象 的事件屬性綁定監聽函數
window.onload = doSomething; div.onclick = function (event) { console.log('觸發事件'); };
使用 EventTarget.addEventListener() 綁定
window.addEventListener('DOMContentLoaded', doSomething, false);
除了 DOM 節點,其餘對象(好比window、XMLHttpRequest等)也有這個接口,等因而整個 JavaScript 統一的監聽函數接口
可以指定在哪一個階段(捕獲階段仍是冒泡階段)觸發監聽函數
同一個事件能夠添加多個監聽函數
3. 事件的傳播
使得同一個事件會在多個節點上觸發
「捕獲階段」(capture phase) 從 window 對象 傳導到 目標節點
「目標階段」(target phase) 在目標節點上觸發
「冒泡階段」(bubbling phase) 從 目標節點 傳導回 window對象
var phases = { 1: 'capture', 2: 'target', 3: 'bubble' }; var div = document.querySelector('div'); var p = document.querySelector('p'); div.addEventListener('click', callback, true); div.addEventListener('click', callback, false); p.addEventListener('click', callback, true); p.addEventListener('click', callback, false); function callback(event) { console.log("Tag: " + event.currentTarget.tagName, "EventPhase: " + phases[event.eventPhase]); }; // 點擊之後的結果 // Tag: 'DIV'. // EventPhase: 'capture' // Tag: 'P' // EventPhase: 'target' // Tag: 'P' // EventPhase: 'target' // Tag: 'DIV' //EventPhase: 'bubble'
瀏覽器老是假定 click 事件的目標節點,就是點擊位置嵌套最深的那個節點
事件傳播的最上層對象是window,接着依次是document,html(document.documentElement)和body(document.body)
也就是說,上例的事件傳播順序,
在捕獲階段依次爲window、document、html、body、div、p
在冒泡階段依次爲p、div、body、html、document、window。
把子節點的監聽函數定義在父節點上,由父節點的監聽函數統一處理多個子元素的事件
只要定義一個監聽函數,就能處理多個子節點的事件,而不用在每一個<li>節點上定義監聽函數
並且之後再添加子節點,監聽函數依然有效
stopPropagation()
方法可是,stopPropagation方法只會阻止事件的傳播,
不會阻止該事件觸發 <p> 節點的其餘 click 事件的監聽函數。
也就是說,不是完全取消click事件
p.addEventListener('click', function (event) { event.stopPropagation(); console.log(1); // 不會觸發 }); p.addEventListener('click', function(event) { // 會觸發 console.log(2); });
4. Event 對象
Event 對象自己就是一個構造函數,能夠用來生成新的實例
event = new Event(type, options);
接收兩個參數:
該對象主要有下面兩個屬性
若是不是顯式指定 bubbles 屬性爲 true,生成的事件就只能在 「捕獲階段」 觸發監聽函數
即可否用 event.preventDefault() 取消這個事件。
一旦事件被取消,就好像歷來沒有發生過,不會觸發瀏覽器對該事件的默認行爲
Event.bubbles
表示當前事件是否會冒泡。
返回一個布爾值,除非顯式聲明,Event
構造函數生成的事件,默認是不冒泡的。
該屬性爲只讀屬性,用來判斷 Event 實例是否能夠冒泡
Event.eventPhase
表示事件目前所處的階段。
返回一個整數常量,該屬性只讀
0,事件目前沒有發生。
1,事件目前處於捕獲階段,即處於從祖先節點向目標節點的傳播過程當中。
2,事件到達目標節點,即 Event.target 屬性指向的那個節點。
3,事件處於冒泡階段,即處於從目標節點向祖先節點的反向傳播過程當中。
Event.cancelable
表示事件是否能夠取消。
返回一個布爾值,該屬性爲只讀屬性,
通常用來判斷 Event 實例是否能夠被取消
/**** 封裝 禁止瀏覽器默認行爲 ****/
function preventEvent(event) { if (event.cancelable) { event.preventDefault(); } else { console.warn('This event couldn\'t be canceled.'); console.dir(event); } }
Event.cancelBubble
阻止事件的傳播。 若是設爲true,至關於執行Event.stopPropagation()
是一個布爾值
Event.defaultPrevented
表示該事件是否調用過 Event.preventDefault() 方法。
返回一個布爾值,該屬性只讀。
Event.currentTarget
返回 事件當前所在的節點,即正在執行的監聽函數所綁定的那個節點,隨事件傳播過程而變化
Event.target
返回 原始觸發事件的那個節點,即事件最初發生的節點,事件傳播過程當中是固定不變的
Event.type
表示事件類型。
返回一個字符串,事件的類型是在生成事件的時候。
該屬性只讀
Event.timeStamp
返回一個毫秒時間戳,表示事件發生的時間。
它是相對於網頁加載成功開始計算的。
var previousX; var previousY; var previousT; window.addEventListener('mousemove', function(event) { if (previousX !== undefined && previousY !== undefined && previousT !== undefined ){ var deltaX = event.screenX - previousX; // 獲取 當前的 xOffset var deltaY = event.screenY - previousY; // 獲取 當前的 yOffset var deltaD = Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2)); var deltaT = event.timeStamp - previousT; console.log(deltaD / deltaT * 1000); // 速度 = 路程 / 時間 }; previousX = event.screenX; // 獲取移動前的 x previousY = event.screenY; // 獲取移動前的 y previousT = event.timeStamp; // 獲取當前時間戳 });
Event.isTrusted
表示該事件是否由真實的用戶行爲產生。
返回一個布爾值
好比,用戶點擊連接會產生一個 click 事件,該事件是用戶產生的;Event 構造函數生成的事件,則是腳本產生的。
Event.detail
該屬性返回一個數值,表示事件的某種信息。
只有瀏覽器的 UI (用戶界面)事件才具備此屬性。
具體含義與事件類型相關。
好比,
對於 click 和 dbclick 事件,Event.detail 是鼠標按下的次數(1表示單擊,2表示雙擊,3表示三擊);
對於鼠標滾輪事件,Event.detail 是滾輪正向滾動的距離,負值就是負向滾動的距離,返回值老是 3 的倍數。
Event.preventDefault()
取消瀏覽器對當前事件的默認行爲。
好比點擊連接後,瀏覽器默認會跳轉到另外一個頁面,使用這個方法之後,就不會跳轉了;
再好比,按一下空格鍵,頁面向下滾動一段距離,使用這個方法之後也不會滾動了。
再好比,瀏覽器的默認行爲是單擊會選中單選框,取消這個行爲,就致使沒法選中單選框
該方法生效的前提是,事件對象的 cancelable 屬性爲true,若是爲 false,調用該方法沒有任何效果
注意,該方法只是取消事件對當前元素的默認影響,不會阻止事件的傳播。
若是要阻止傳播,可使用 event.stopPropagation() 或 event.stopImmediatePropagation() 方法
// HTML 代碼爲 // <input type="text" id="my-input" /> var input = document.getElementById('my-input'); input.addEventListener('keypress', checkName, false); function checkName(e) { if (e.charCode < 97 || e.charCode > 122) { e.preventDefault(); } }
上面代碼爲文本框的 keypress
事件設定監聽函數後,將只能輸入小寫字母,不然輸入事件的默認行爲(寫入文本框)將被取消,致使不能向文本框輸入內容
Event.stopPropagation()
阻止事件在 DOM 中繼續傳播,防止再觸發定義在別的節點上的監聽函數,
可是不包括在當前節點上其餘的事件監聽函數
Event.stopImmediatePropagation()
阻止同一個事件的全部監聽函數被調用,無論監聽函數定義在當前節點仍是其餘節點。
也就是說,該方法阻止事件的傳播,比Event.stopPropagation()更完全
Event.composedPath()
返回一個節點數組,成員是事件的最底層節點和依次冒泡通過的全部上層節點