#每日一記#開發(fā)微博的 Chrome 插件 快捷鍵問題

每日一記 - 但并不日更

最近在開發(fā) chrome 的插件,方便微博用戶下載圖片和視頻。

開發(fā)的過程中遇到很多問題,這邊就記錄一下關(guān)于快捷鍵的問題。方便遇到相同問題的小伙伴能參考。

現(xiàn)有問題

在 chrome 插件開發(fā)過程中,需要在既有網(wǎng)頁里插入一個(gè)界面,這個(gè)界面需要輸入一些內(nèi)容,當(dāng)輸入的時(shí)候就會(huì)觸發(fā)微博的快捷鍵。

觸發(fā)了微博的快捷鍵
為什么體驗(yàn)可以這么差

這種體驗(yàn)用戶肯定接受不了,那么就要想辦法控制這個(gè)快捷鍵的觸發(fā)。

解決思路

想要看結(jié)果的接著往下翻?這里講整個(gè)過程

一開始為了解決問題,需要了解一下微博的快捷鍵邏輯是怎么設(shè)計(jì)的。

快捷鍵功能的是通過 keydown 和 keyup 事件觸發(fā)的

所以先去看一下 dom 上哪里監(jiān)聽了這兩個(gè)事件,在 html 節(jié)點(diǎn)上找到了3個(gè)監(jiān)聽

bingo

通過這里鏈接的源碼,最后分析出

微博快捷鍵通過 STK.hotKey 接口來注冊(cè)和移除

屏幕快照 2018-03-30 下午2.26.23.png

既然找到了監(jiān)聽的位置,接著就想能不能移除這些監(jiān)聽。

Chrome 插件是無法獲取網(wǎng)頁 window 對(duì)象的,只能獲取到 dom 對(duì)象

由于 chrome 插件開發(fā)在安全方面的考慮,插件沒法得到 window 對(duì)象,那么通過微博接口破解就沒有辦法了。

只得想辦法通過 dom 來處理。去查一下文檔看看有沒有什么新發(fā)現(xiàn)。

Element

Element 繼承了EventTarget,那么接著看看這個(gè)上面有什么方法.

EventTarget

Sad,這里除了 add 和 remove 沒有更多的方法了,removeEventListener 是沒有辦法使用的

要通過 removeEventListener 移除監(jiān)聽就必須要有注冊(cè)監(jiān)聽時(shí)的函數(shù)對(duì)象。

有點(diǎn)無路可走的心情,有點(diǎn)無法理解為什么無法獲取到一個(gè) dom 上綁定的監(jiān)聽列表,也沒有辦法簡單的移除一個(gè)監(jiān)聽。(大概是安全考慮吧)

在網(wǎng)路上各種搜索后,發(fā)現(xiàn)了一絲線索,關(guān)于事件的傳遞。

事件既然可以傳遞,那么就有相應(yīng)的方法攔截

事件的傳遞方式有兩種:捕獲和冒泡
阻止事件的傳遞有兩個(gè)方法:stopPropagation 和 stopImmediatePropagation

event.stopPropagation() 可以從下一個(gè)節(jié)點(diǎn)阻止事件傳播

event.stopImmediatePropagation() 可以從當(dāng)前節(jié)點(diǎn)阻止事件傳播
但是當(dāng)前節(jié)點(diǎn)已經(jīng)觸發(fā)的事件無法阻止

這是什么意思呢,就是如果能成為節(jié)點(diǎn)上第一個(gè)注冊(cè)的事件,那就有權(quán)利阻止隨后注冊(cè)的事件被觸發(fā)(同一個(gè)事件名)

知道有這樣的方法后就有辦法解決了,讓 chrome 插件在網(wǎng)頁加載前加載,并成為 html 元素上第一個(gè)注冊(cè) keydown keyup 事件,那么就可以在需要的時(shí)候禁止快捷鍵被觸發(fā)。

解決方法

// chrome 插件 manifest 配置
// 在網(wǎng)頁加載前運(yùn)行插件
"content_scripts": [
  {
    "js": [
      "jquery.min.js"
      "app.js"
    ],
    "run_at": "document_start"
  }
]
// chrome 插件 content_scripts
// app.js
$(document).ready(function () {
  window.Weibo = {
    disableKeyEvent: false
  }

  document.querySelector('html').addEventListener('keyup', function keydown (e) {
    if (window.Weibo.disableKeyEvent) {
      e.stopImmediatePropagation();
    }
  })
  document.querySelector('html').addEventListener('keydown', function keydown (e) {
    if (window.Weibo.disableKeyEvent) {
      e.stopImmediatePropagation();
    }
  })
})
不受快捷鍵影響

在 window(插件的 window)上綁定了一個(gè)變量來控制是否禁止快捷鍵功能,這樣技能保留微博快捷鍵的功能,也能在我需要輸入文本的時(shí)候不打擾用戶體驗(yàn)。

總結(jié)

  • 快捷鍵功能的是通過 keydown 和 keyup 事件觸發(fā)的
  • 微博快捷鍵通過 STK.hotKey 接口來注冊(cè)和移除
  • Chrome 插件是無法獲取網(wǎng)頁 window 對(duì)象的,只能獲取到 dom 對(duì)象
  • event.stopPropagation() 可以從下一個(gè)節(jié)點(diǎn)阻止事件傳播
  • event.stopImmediatePropagation() 可以從當(dāng)前節(jié)點(diǎn)阻止事件傳播
    但是當(dāng)前節(jié)點(diǎn)已經(jīng)觸發(fā)的事件無法阻止

JSbin

demo 源碼

羅小黑寫寫文字

如果喜歡文章 請(qǐng)留下一個(gè)贊~
如果喜歡文章 分享給更多人~

掘金中關(guān)注我
簡書中關(guān)注我

自由轉(zhuǎn)載-非商用-非衍生-保持署名(創(chuàng)意共享3.0許可證
轉(zhuǎn)載時(shí)請(qǐng)保留原文鏈接 以保證可及時(shí)獲取對(duì)文章的訂正和修改

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • ??JavaScript 與 HTML 之間的交互是通過事件實(shí)現(xiàn)的。 ??事件,就是文檔或?yàn)g覽器窗口中發(fā)生的一些特...
    霜天曉閱讀 3,684評(píng)論 1 11
  • 本節(jié)介紹各種常見的瀏覽器事件。 鼠標(biāo)事件 鼠標(biāo)事件指與鼠標(biāo)相關(guān)的事件,主要有以下一些。 click 事件,dblc...
    許先生__閱讀 2,838評(píng)論 0 4
  • js之事件機(jī)制 1、事件初探 1.1 js事件的概述 JavaScript事件:JavaScript是基于事件驅(qū)動(dòng)...
    道無虛閱讀 2,630評(píng)論 0 2
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,893評(píng)論 25 709
  • 親愛的吳太太,很高興可以參加今天的婚禮。很開心也很感動(dòng)。從Miss到Mrs。哇~~~我已經(jīng)開始幻想未來的模樣...
    努吶嘿閱讀 158評(píng)論 0 0

友情鏈接更多精彩內(nèi)容