談?wù)刯s點(diǎn)擊之后發(fā)生了什么

前言

????之所以突然想寫這個(gè)文章,主要是之前看到一篇有意思的博文麸澜,《探究點(diǎn)擊事件在JavaScript事件循環(huán)中的表現(xiàn)》秽褒,有趣的地方在于JS點(diǎn)擊事件加入回調(diào)的并不是點(diǎn)擊事件的回調(diào)方法趴酣,而是點(diǎn)擊事件本身(點(diǎn)擊位置等描述點(diǎn)擊的)欢峰。

點(diǎn)擊不是加入回調(diào)而不是加入事件

<body style="height: 2000px">
    <button class="a">打開控制臺(tái)葬荷,快速點(diǎn)擊三次</button>
    <br />
    <button class="b" style="height: 1000px;width: 1000px">按鈕b</button>
    <script>
      var btn = document.querySelector(".a");
      btn.onclick = function() {
        console.log("click a");
        setTimeout(function() {
          //頁面失去響應(yīng)2s。
          var time = new Date().getTime();
          while (new Date().getTime() - time < 2000) {}
          window.scrollTo(100, 500); //滾動(dòng)到第二個(gè)按鈕上纽帖。
          console.log("timeout");
        });
      };

      var btn1 = document.querySelector(".b");
      btn1.onclick = function() {
        console.log("click b");
      };
    </script>
  </body>

當(dāng)我們連續(xù)點(diǎn)擊button.a兩次的時(shí)候宠漩,結(jié)果卻是

click a
timeout
click b

明明是點(diǎn)擊的button.a,為什么會(huì)觸發(fā)button.b的事件抛计?

????可見哄孤,點(diǎn)擊并沒有直接把回調(diào)推入事件循環(huán)(對(duì)事件循環(huán)不了解,可以先去了解一下)的吹截,而是推入了點(diǎn)擊事件(推測(cè)就是點(diǎn)擊位置瘦陈、事件類型...),當(dāng)我們觸發(fā)點(diǎn)擊的時(shí)候波俄,js會(huì)去點(diǎn)擊位置尋找相應(yīng)的事件晨逝,在上面的例子中,我們?cè)邳c(diǎn)擊button.a之后執(zhí)行了一個(gè)setTimeout滾動(dòng)頁面到button.b的位置懦铺,之后執(zhí)行第二次點(diǎn)擊的事件捉貌,在該位置button.a已經(jīng)不見了,而是button.b冬念,所以會(huì)執(zhí)行button.b的回調(diào)事件趁窃。

事件機(jī)制

????無論通過onclick還是addEventListener實(shí)現(xiàn)事件綁定,我懷疑綁定機(jī)制是一樣的急前,因?yàn)樵趯?shí)際測(cè)試中醒陆,我發(fā)現(xiàn)onclick執(zhí)行順序和addEventListener是一樣的,也就是什么時(shí)候綁定裆针,那么就在第幾個(gè)執(zhí)行刨摩。
????addEventListeneronclick不同,不是直接給dom綁定屬性世吨,并且我在dom節(jié)點(diǎn)上也沒有看到任何相應(yīng)的對(duì)象用于保存事件澡刹,可見addEventListener是不同的機(jī)制,參考EventEmitter耘婚,試著去實(shí)現(xiàn)一個(gè)addEventListener

// es6的Map可以使用對(duì)象作為鍵值對(duì)的鍵值
var listeners = new Map(); // 保存dom和其對(duì)應(yīng)的事件

function addEventListener(dom, type, callback) {
  if(listeners.has(dom)) {
    listeners.get(dom)[type].push(callback);
  } else {
     listeners.set(dom, {
      [type]: [callback]
     })
  }
}
// 點(diǎn)擊之后做了什么
// 1. 保存事件(事件類型: 'click', 觸發(fā)位置)
...
// 2. 事件循環(huán)到觸發(fā)的時(shí)候罢浇,根據(jù)點(diǎn)擊

總結(jié)

通過上面分析,總結(jié)一下

點(diǎn)擊一個(gè)dom之后發(fā)生了什么沐祷?

  1. 保存事件
    向事件循環(huán)隊(duì)列中添加事件對(duì)象嚷闭,主要是(事件類型: 'click', 觸發(fā)位置: {x:,y:}戈轿,...)
  2. 事件循環(huán)到觸發(fā)
    根據(jù)點(diǎn)擊事件對(duì)象去dom樹中找到該dom(不在乎是不是點(diǎn)擊的那個(gè)凌受,只是當(dāng)前該位置的dom)
  3. 執(zhí)行
    通過listeners找到該dom對(duì)應(yīng)的回調(diào),并且執(zhí)行
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末思杯,一起剝皮案震驚了整個(gè)濱河市胜蛉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌色乾,老刑警劉巖誊册,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異暖璧,居然都是意外死亡案怯,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門澎办,熙熙樓的掌柜王于貴愁眉苦臉地迎上來嘲碱,“玉大人金砍,你說我怎么就攤上這事÷缶猓” “怎么了恕稠?”我有些...
    開封第一講書人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)扶欣。 經(jīng)常有香客問我鹅巍,道長(zhǎng),這世上最難降的妖魔是什么料祠? 我笑而不...
    開封第一講書人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任骆捧,我火速辦了婚禮,結(jié)果婚禮上髓绽,老公的妹妹穿的比我還像新娘敛苇。我一直安慰自己,他們只是感情好梧宫,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開白布接谨。 她就那樣靜靜地躺著,像睡著了一般塘匣。 火紅的嫁衣襯著肌膚如雪脓豪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,182評(píng)論 1 299
  • 那天忌卤,我揣著相機(jī)與錄音扫夜,去河邊找鬼。 笑死驰徊,一個(gè)胖子當(dāng)著我的面吹牛笤闯,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播棍厂,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼颗味,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了牺弹?” 一聲冷哼從身側(cè)響起浦马,我...
    開封第一講書人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎张漂,沒想到半個(gè)月后晶默,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡航攒,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年磺陡,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡币他,死狀恐怖坞靶,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情圆丹,我是刑警寧澤滩愁,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布躯喇,位于F島的核電站辫封,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏廉丽。R本人自食惡果不足惜倦微,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望正压。 院中可真熱鬧欣福,春花似錦、人聲如沸焦履。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嘉裤。三九已至郑临,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間屑宠,已是汗流浹背厢洞。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留典奉,地道東北人躺翻。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像卫玖,于是被迫代替她去往敵國和親公你。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • ??JavaScript 與 HTML 之間的交互是通過事件實(shí)現(xiàn)的。 ??事件笨触,就是文檔或?yàn)g覽器窗口中發(fā)生的一些特...
    霜天曉閱讀 3,490評(píng)論 1 11
  • 22懦傍、JQ的基礎(chǔ)語法、核心原理和項(xiàng)目實(shí)戰(zhàn) jQ的版本和下載 jQuery版本 1.x:兼容IE6-8芦劣,是目前PC端...
    萌妹撒閱讀 1,745評(píng)論 0 0
  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5粗俱? 答:HTML5是最新的HTML標(biāo)準(zhǔn)。 注意:講述HT...
    kismetajun閱讀 27,474評(píng)論 1 45
  • Dom事件 事件是一種異步編程的實(shí)現(xiàn)方式虚吟,本質(zhì)上是程序各個(gè)組成部分之間的通信寸认。DOM支持大量的事件 (一) Eve...
    woow_wu7閱讀 1,773評(píng)論 0 1
  • 聲明:本文來源于http://www.webzsky.com/?p=731我只是在這里作為自己的學(xué)習(xí)筆記整理一下(...
    angryyan閱讀 7,006評(píng)論 1 6