簡體   English   中英

Chrome DevTools擴展:如何從內容腳本中的元素面板中獲取所選元素?

[英]Chrome DevTools extension: how to get selected element from elements panel in content script?

我已經完成了我的研究並且在這方面掙扎了一段時間,但我需要你的幫助。

我正在構建Chrome DevTools擴展程序。 它應該從“Elements”面板傳遞當前選定的元素, 作為對內容腳本中定義的JS對象的引用

重要的是我將引用傳遞給所選元素,或者從內容腳本中識別元素的其他方式。

我了解Chrome DevTools中“孤立世界”的工作流程。 我也理解擴展頁面,后台頁面和內容腳本之間的消息傳遞。 這只發生在JSON原語中,因此沒有JS范圍傳遞。

如何將devtools Elements面板中選定的元素傳遞給檢查頁面中的內容腳本?

編輯

這是我目前所知道的:

獲取對所選元素的引用:

chrome.devtools.inspectedWindow.eval("(" + function(){ console.log($0) }.toString() + ")()")
  • 該函數表達式將在被檢查頁面的上下文中運行,而不是在devtools擴展的上下文中運行,而不是在內容腳本的“孤立世界”的上下文中運行。 我不相信可以使用閉包傳遞對不同上下文的引用。

  • 無法返回對所選DOM元素$0的引用,因為由於循環引用而無法將其序列化為JSON。

  • chrome.devtools命名空間在devtools擴展頁面之外不可用。 $0 chrome.devtools.inspectedWindow引用不能在chrome.devtools.inspectedWindow的計算表達式之外使用

解決方法

作為一種解決方法,我選擇使用共享DOM來使用數據屬性標記所選元素,並使用它在內容腳本的上下文中重新選擇它。 消息傳遞用於傳遞數據屬性標記。

這是代碼的簡化版本:

devtools擴展頁面中:

// setup a communication port
port = chrome.runtime.connect({name: "devtools"});

chrome.devtools.panels.elements.onSelectionChanged.addListener(function(){

  // expression to run in the context of the inspected page
  var expression = "(" + mark.toString() + ")()"

  // evaluate the expression and handle the result
  chrome.devtools.inspectedWindow.eval(expression, dispatchToContentScript)
});


function mark(){

  // mark the currently selected element
  $0.setAttribute('data-selected')

  // send the marker to the callback
  return { marker: 'data-selected' }
}

function dispatchToContentScript(data){

  // dispatch data to the content script which is listening to the same port.
  port.postMessage(data)
}

內容腳本中

var port = chrome.runtime.connect({name: "devtools"});

port.onMessage.addListener(function(data) {

  // re-select the element in the context of the content script
  var el = document.querySelector('['+ data.marker +']')
})

這不是一個干凈的解決方案,但我可以根據我的需要使用它。

有沒有更簡單的方法來實現相同的結果 - 從內容腳本中識別在devtools'Elements'面板中選擇的元素?

chrome.devtools.inspectedWindow的API 已更新,以支持在內容腳本的上下文中執行腳本。

官方Chrome API中的此更新廢棄了我們上面描述的黑客攻擊。 我們現在可以通過以下方式實現預期結果

chrome.devtools.inspectedWindow.eval("aContentScriptFunction($0)", 
    { useContentScriptContext: true });

$0參數將引用在“ 元素”面板中選擇的元素

我這樣做也是一種黑客攻擊...你可以注入一個腳本標簽,而不是注入你的擴展中定義的內容腳本,或者在本地,相對於檢查的html注入你的文件:

//devtools.js
var str = "var s = document.createElement('script');" +
      "s.src = 'http://extentionDomain/extentionFile.js';" +
      "document.body.appendChild(s);";
chrome.devtools.inspectedWindow.eval(str);

在線文件定義全局:

var myExtention = { doStuff: function(selectedElement){ ..}}

和devtools可以調用它並將選中的元素傳遞給它:

chrome.devtools.panels.elements.onSelectionChanged.addListener(function(){
    chrome.devtools.inspectedWindow.eval('myExtention.doStuff($0)');});

但是,我沒有找到一種方法,通過此設置將檢查窗口中的引用發送回devtools擴展。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM