【前端盲點】DOM事件流論證CSS盒模型是否具有厚度
前言
很久沒有扯淡了,我們今天來扯淡吧。
我今天思考了一個問題,我們頁面的dom樹到底是如何渲染的,而CSS盒模型與javascript是否有聯絡,於是便想到一個問題:
CSS的盒模型具有厚度麼???
該文只是一種幫助理解的說法,與官方定義不一定統一,權當扯淡
盒模型
稍微入門點的前端都知道CSS盒模型,於是我們不厭其煩的偷圖來用:
這個就是我們傳說中的盒模型,我們這裡先把盒模型放一放,來看我們的DOM事件流
DOM事件流
在上一篇部落格中,我們詳細說了下javascript的事件機制:【移動端相容問題研究】javascript事件機制詳解(涉及移動相容)
今天也不知道怎麼發神經了,突然對其中兩個事件引數產生興趣:
currentTarget
某事件處理程式當前正在處理的那個元素
target
事件目標(繫結事件那個dom),源事件觸發點
這兩個兄弟非常有意思,為了說明他的有意思,我寫了一段程式碼:
1 <html xmlns=”http://www.w3.org/1999/xhtml”>
2 <head>
3 <title></title>
4 <style type=”text/css”>
5 #p { width: 300px; height: 300px; padding: 10px; border: 1px solid black; }
6 #c { width: 100px; height: 100px; border: 1px solid red; }
7 </style>
8 </head>
9 <body>
10 <div id=”p”>
11 parent
12 <div id=”c”>
13 child
14 </div>
15 </div>
16 <script type=”text/javascript”>
17 var p = document.getElementById(`p`),
18 c = document.getElementById(`c`);
19 c.addEventListener(`click`, function () {
20 alert(`子節點捕獲`)
21 }, true);
22
23 c.addEventListener(`click`, function () {
24 alert(`子節點冒泡`)
25 }, false);
26
27 p.addEventListener(`click`, function () {
28 alert(`父節點捕獲`)
29 }, true);
30
31 p.addEventListener(`click`, function () {
32 alert(`父節點冒泡`)
33 }, false);
34 </script>
35 </body>
36 </html>
http://sandbox.runjs.cn/show/ij4rih6x
這個傢伙其實是非常有意思的,按照我們當時的邏輯:
① 點選parent,事件首先在document上然後parent捕獲到事件,處於目標階段然後event.target也等於parent,所以觸發捕獲事件
由於target與currentTarget相等了,所以認為到底了,開始冒泡,執行冒泡事件
② 點選child情況有所不同,事件由document傳向parent執行事件,然後傳向child最後開始冒泡
上面的解釋沒問題,我們很多朋友也都清楚,但是我今天突然問題就來了,CSS盒模型尼瑪到底是怎麼排布的???
猜想一:積木式=盒模型
首先,也是最簡單的猜想,盒模型就是堆積木(其實根據上圖來看,這個想法自然而然)
這個想法簡單,而且直觀,也和我們一般的思維類似,但是問題馬上來了:
事件捕獲會先於事件冒泡發生
事件捕獲:由最先接收到事件的元素然後傳向最裡邊
雖然是中文翻譯,我們可以得到兩個重要資訊(點選child div、忽略document):
① parent div 應該先於child div觸發
② “最裡面”,這個最裡面應該如何理解需要關注!!!
悖謬
按照上圖的理解,我們這裡就該child div事件先觸發呢,情況卻是parent div先觸發,這與常理不合,所以CSS盒模型不應該是這個樣子
於是,我這裡推翻了猜想一,這裡進行猜想二。
猜想二:盒子=盒模型
這個猜想也比較直接,因為盒模型嘛。。。。。。
最初,我在想盒模型是這個樣子,他能很好的解釋為什麼會先觸發parent的click事件而不是child的,但是他仍有一個讓我難受的地方:
我body或者parent div如果有顏色,我裡面的元素豈不是看不到了???這與現實不合啊???
於是我再一次陷入僵局,於是進入猜想三,也是最終猜想
最終幻想:盒模型=具有厚度一面透明盒子
其實用盒子來形容盒模型是非常貼切的,而且
CSS盒模型是具有厚度的
我們這裡有一個很好的形容詞來形容CSS盒模型:捅不破的XX膜!
PS:這裡本來想畫一個圖的但是,確實畫不出來,各位將就點聽我描述吧,我覺得
這個應該是我們的盒模型了,由此我們就可以更好的說明我們的答案了:
① 點選parent區域時,我們首先觸發一次點選,流程如下:
document=》body=》parent div=開始冒泡=》parent div=》body=》document
我們因為在parent div上註冊了事件,所以他會執行
② 點選child區域時
document=》body=》parent div=》child div=開始冒泡=》child div =》parent div=》body=》document
這裡情況也比較明顯了,我們一次點選滑鼠會點破透明膜,然後一次會碰到上面的元素(離開時候會記住碰到的最深dom也就是target)
底層事件模擬(純粹幻想)
好了,我們這裡來做一次詳細的事件模擬:
① 首先我們組織我們的dom樹,為dom繫結事件(這裡繫結事件我就當向hash中傳入了值)
1 el.addEventListener(type, fn, useCapture);
2 //每個dom在瀏覽器中肯定會具有一個唯一標識,我不知道是什麼,暫且認為是uuid
3 //於是上面的程式碼在瀏覽器中大概是這個意思
4
5 var hashCapture = {};//儲存捕獲事件集合
6 var hashBubble = {};//儲存冒泡事件集合
7
8 if (useCapture) {
9 //裝載捕獲時的click事件
10 pushSet(el, type, fn, hashCapture);
11 } else {
12 //裝載冒泡時的click事件
13 pushSet(el, type, fn, hashCapture);
14 }
15
16 function pushSet(el, type, fn, hashSet) {
17 hashSet[el.uuid] = {};
18 hashSet[el.uuid][type].push(fn);
19 }
PS:注意,此處完全是一種假想,我並不知道系統底層如何實現
按照上述思想,其實儲存了兩個物件:
一個關於捕獲時期dom(el)click事件的集合()——hashCapture
一個關於冒泡時期dom(el)click事件的集合()——hashBubble
② 我們開始點選,然後記錄點選過程中,手指碰到的元素(我們這裡簡化去掉document)
body=》parent div=》child div=》child div =》parent div=》body
按照上面的邏輯,我首先碰到了body,離開前碰到了child div,我們最好觸碰的dom就是target,所以
1 var Event = {};
2 //捕獲時碰到的dom
3 Event.captureDoms = [];
4 //冒泡時候碰到的dom
5 Event.captureDoms = [];
6 Event.target = dom;//最後碰到的元素
所以上面的target永遠都是child div,而currentTarget卻會不斷變化
captureDoms裝的是body,parent div, child div
而captureDoms 與他一致,只不過順序是反的,最好就只剩下執行事件了
PS:當我們滑鼠離開window時,判斷為一次點選,於是:
1 for (var i = 0, len < Event.captureDoms.length; i < len; i++) {
2 var el = Event.captureDoms[i];
3 var uuid = el.uuid;
4 //獲取捕獲中儲存的click事件集合
5 for (var j = 0, len1 < hashCapture[uuid].click.length; j < len1; j++) {
6 hashCapture[uuid][`click`][j](Event);//執行儲存的click事件
7 }
8 }
然後執行冒泡時候的相同邏輯即可,於是就我們的猜想結束……
firefox模型
firefox dom結構如此,但是與我的猜想好像不一樣……
結語
我們的盒模型具有厚度嗎?我認為是具有的,而且他很好的解釋了我遇到的問題,所以我認為他是具有的,我能自圓其說……
您可以考慮給小釵發個小額微信紅包以資鼓勵
本文轉自葉小釵部落格園部落格,原文連結:http://www.cnblogs.com/yexiaochai/p/3468489.html如需轉載請自行聯絡原作者
相關文章
- 前端面試2:CSS盒模型前端面試CSS模型
- css 盒模型CSS模型
- CSS盒模型CSS模型
- 精通CSS盒模型CSS模型
- CSS盒模型深入CSS模型
- css之盒模型CSS模型
- css-盒模型CSS模型
- css 盒模型 文件流 幾種清除浮動的方法CSS模型
- 【Web前端HTML5&CSS3】06-盒模型Web前端HTMLCSSS3模型
- 前端筆記(關於css盒模型知識整理)前端筆記CSS模型
- css&&js盒模型CSSJS模型
- 盲盒社交電商的亮點
- Css規範整理:2、css盒模型CSS模型
- CSS的兩種盒模型CSS模型
- 【Web前端HTML5&CSS3】08-盒模型補充Web前端HTMLCSSS3模型
- 好程式設計師web前端技術分享css盒模型程式設計師Web前端CSS模型
- 盲盒商城小程式如何實現盲盒玩法
- 前端筆記之JavaScript(十)深入JavaScript節點&DOM&事件前端筆記JavaScript事件
- DOM 模型(文件物件模型)重點模型物件
- 前端面試之盒模型前端面試模型
- CSS系列 (04):盒模型詳解CSS模型
- 進擊的盲盒---盲盒跑圈的本質
- 脫單月老盲盒|交友盲盒系統原始碼原始碼
- css盒子模型與盒模型的浮動CSS模型
- js判斷dom節點是否存在JS
- 拆盒玩家NFT盲盒系統模型開發丨dapp丨Defi丨NFT模型APP
- JS的事件繫結和事件流模型JS事件模型
- 盲盒app原始碼APP原始碼
- 盲盒商城經濟
- css佈局系列1——盒模型佈局CSS模型
- DOM - 事件事件
- Dom事件事件
- DOM0事件和DOM2事件模型 —— JS中的設計模式和元件封裝事件模型JS設計模式元件封裝
- 前端知識點總結——DOM前端
- 盲盒系統的玩法
- 盲盒系統原始碼盲盒系統開發需要滿足哪些需求原始碼
- 海外版盲盒APP開發設計盲盒原始碼搭建佈署APP原始碼
- React 事件和 Dom 事件React事件
- 盲盒遊戲開發(功能)丨盲盒遊戲系統開發(規則及詳細)丨盲盒遊戲原始碼部署遊戲開發原始碼