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

每日一記 - 但並不日更

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

開發的過程當中遇到不少問題,這邊就記錄一下關於快捷鍵的問題。方便遇到相同問題的小夥伴能參考。html

##現有問題 在 chrome 插件開發過程當中,須要在既有網頁裏插入一個界面,這個界面須要輸入一些內容,當輸入的時候就會觸發微博的快捷鍵。java

觸發了微博的快捷鍵

爲何體驗能夠這麼差

這種體驗用戶確定接受不了,那麼就要想辦法控制這個快捷鍵的觸發。jquery

解決思路

想要看結果的接着往下翻⬇這裏講整個過程chrome

一開始爲了解決問題,須要瞭解一下微博的快捷鍵邏輯是怎麼設計的。json

快捷鍵功能的是經過 keydown 和 keyup 事件觸發的安全

因此先去看一下 dom 上哪裏監聽了這兩個事件,在 html 節點上找到了3個監聽app

bingo

經過這裏連接的源碼,最後分析出dom

微博快捷鍵經過 STK.hotKey 接口來註冊和移除函數

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

既然找到了監聽的位置,接着就想能不能移除這些監聽。

Chrome 插件是沒法獲取網頁 window 對象的,只能獲取到 dom 對象

因爲 chrome 插件開發在安全方面的考慮,插件無法獲得 window 對象,那麼經過微博接口破解就沒有辦法了。

只得想辦法經過 dom 來處理。去查一下文檔看看有沒有什麼新發現。

Element

Element 繼承了EventTarget,那麼接着看看這個上面有什麼方法.

EventTarget

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

要經過 removeEventListener 移除監聽就必需要有註冊監聽時的函數對象。

有點無路可走的心情,有點沒法理解爲何沒法獲取到一個 dom 上綁定的監聽列表,也沒有辦法簡單的移除一個監聽。(大概是安全考慮吧)

在網路上各類搜索後,發現了一絲線索,關於事件的傳遞。

事件既然能夠傳遞,那麼就有相應的方法攔截

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

event.stopPropagation() 能夠從下一個節點阻止事件傳播

event.stopImmediatePropagation() 能夠從當前節點阻止事件傳播 可是當前節點已經觸發的事件沒法阻止

這是什麼意思呢,就是若是能成爲節點上第一個註冊的事件,那就有權利阻止隨後註冊的事件被觸發(同一個事件名)

知道有這樣的方法後就有辦法解決了,讓 chrome 插件在網頁加載前加載,併成爲 html 元素上第一個註冊 keydown keyup 事件,那麼就能夠在須要的時候禁止快捷鍵被觸發。

解決方法

// chrome 插件 manifest 配置
// 在網頁加載前運行插件
"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)上綁定了一個變量來控制是否禁止快捷鍵功能,這樣技能保留微博快捷鍵的功能,也能在我須要輸入文本的時候不打擾用戶體驗。

總結

  • 快捷鍵功能的是經過 keydown 和 keyup 事件觸發的
  • 微博快捷鍵經過 STK.hotKey 接口來註冊和移除
  • Chrome 插件是沒法獲取網頁 window 對象的,只能獲取到 dom 對象
  • event.stopPropagation() 能夠從下一個節點阻止事件傳播
  • event.stopImmediatePropagation() 能夠從當前節點阻止事件傳播 可是當前節點已經觸發的事件沒法阻止

##JSbin

demo 源碼

羅小黑寫寫文字

若是喜歡文章 請留下一個贊~ 若是喜歡文章 分享給更多人~

掘金中關注我 在簡書中關注我

自由轉載-非商用-非衍生-保持署名(創意共享3.0許可證) 轉載時請保留原文連接 以保證可及時獲取對文章的訂正和修改

相關文章
相關標籤/搜索