2016-11-07 315 views
0

我正在嘗試做一個簡單的Chrome擴展程序,我將通過用簡短文本替換它來「阻止」網站Reddit的內容。這是我到目前爲止有:Chrome瀏覽器擴展程序:修改網頁的內容

manifest.json的

{ 
"manifest_version": 2, 

"name": "BlockIt", 
"description": "Block Reddit, increase productivity!", 
"version": "1.0", 

"browser_action": { 
    "default_icon": "icon.png", 
    "default_title": "BlockIt" 
}, 

"permissions": [ 
    "storage", "tabs", 
    "http://www.reddit.com/*" 
], 

"content_scripts": [ 
    { 
    "matches": [ "*://reddit.com/*" ], 
    "js": ["content-script.js"] 
    } 
] 
} 

popup.html

<!doctype html> 
<html> 
    <head> 
    <style> 
     body { 
     font-family: Verdana, Arial, Helvetica, Tahoma, sans-serif; 
     background-color:#EFF7FF; 
     margin: 5px 5px 5px 5px; 
     width: 110px; 
     height: 100%; 
     text-align:center; 
     } 
    </style> 
    <!--Scripts--> 
     <script src="popup.js"></script> 
    </head> 
    <body> 
    <h2>BlockIt!</h2> 
    <div id="en"><label for="enable">Enable BlockIt</label> <input id="enable" type="checkbox" style="vertical-align:middle; position:relative; bottom: 1px;"/> 
    </div> 
    </body> 
</html> 

popup.js

document.addEventListener('DOMContentLoaded', function() { 
    document.querySelector('#enable').addEventListener('change', changeHandler); 
}); 

function changeHandler() { 
    if (enable.checked) { 
     chrome.storage.sync.set({ 'enable': true }, function() { }); 
    } 
} 

內容的script.js

var content = document.getElementsByTagName("body"); 
var text = "BlockIt enabled (to disable, click on the icon)."; 
//TODO: replace content with text 

我有兩個主要問題,現在:我不知道我應該如何去在修改網頁的內容,並與上述text替換它,並且我不確定如何在popup.html複選框被選中時注入content-script.js。我如何着手解決這個問題?

編輯:我做了如下修改我的代碼:

內容的script.js

chrome.storage.sync.get({ enable: false }, items=> { 
    if (items.enable) { 
     document.body.textContent = "BlockIt enabled (to disable, click on the icon)."; 
    } 
}); 

它成功地改變了網頁的正文中,但現在的問題是popup.html的內容也改變爲相同的文字。什麼似乎是問題?

編輯2: 我在popup.html刪除content-scrip.js。複選框的狀態仍然不會持續。這似乎是這樣一個簡單的解決方案,但我似乎無法修復它。任何幫助,將不勝感激。

+0

這實際上是兩個截然不同的問題。首先,我們需要知道你想要取代什麼。您是否想要替換整個''(例如'document.body.textcontent = text;'),整個「」等?阻止'webRequests'到'redit.com'可能更容易。 – Makyen

+0

@Makyen我想替換輸入'body'。阻止'webRequests'時可以顯示自定義消息嗎? – coriandres

+0

是的,您可以顯示阻止「webRequest」的自定義消息。但是,你這樣做的方式是不同的。您可以將請求重定向到您的擴展中的HTML文件,該文件將具有阻止消息。 – Makyen

回答

0

一種可能是使用chrome.storage.sync.get()內容script.j注入頁面的時間來啓用的狀態:

內容的script.js

chrome.storage.sync.get({enable:false}, items=> { 
    if(items.enable) { 
     document.body.textContent="BlockIt enabled (to disable, click on the icon)."; 
    } 
}); 

這對當前頁面不可逆。鑑於您的用戶可能希望該塊可以在無需重新加載頁面的情況下進行翻轉,您可能需要考慮實現塊的另一種方法,而不是替換所有內容。

此外,這將僅替換<body>用於在塊啓用後加載的頁面。它不會影響已經加載的頁面。您可能需要使用chrome.tabs.query()以獲取當前顯示reddit.com的選項卡列表。然後您需要使用chrome.tabs.executeScript()再次注入腳本。

喜歡的東西:

//This requires the "tabs" permission. 
//Execute after you have stored the data to chrome.storage.sync (e.g. in the callback) 
chrome.tabs.query({url:"*://reddit.com/*"},tabs=>{ 
    tabs.forEach(tab=>{ 
     chrome.tabs.executeScript(tab.id,{file:"content-script.js"}); 
    }); 
}); 
+0

感謝您的幫助。只要確定,'=>'應該是函數名稱的一部分? – coriandres

+0

不,'items => {}'是編寫'function(items){}'的較簡單的方法。它們被稱爲[Arrow功能](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)。它們是ES6中引入的JavaScript中的新事物。您不應該將它們用於常規JavaScript編程,因爲所有瀏覽器都不支持該語法。不過,對於Chrome擴展程序,我們知道它將在支持語法的Chrome上運行。我使用它,因爲它寫得更快。如果你願意,我可以改變使用'function(...){...}'的答案。 – Makyen

+0

這很好,你不必改變答案,因爲你向我解釋它是什麼。再次感謝:) – coriandres

0

很可能要多得多的資源高效利用webRequest API請求重定向阻止。

比方說,您有一個頁面blocked.html代替內容顯示。

然後,再次假設擴展狀態存儲在chrome.storage.sync中,如在Mayken的答案中。您需要同步緩存該值,因爲重定向必須是同步的。

// Background script 
var enabled; 

function cacheEnabled() { 
    chrome.storage.sync.get({enable: false}, data => { 
    enabled = data.enable; 
    }); 
} 

cacheEnabled(); 
chrome.storage.onChanged.addListener(cacheEnabled); 

chrome.webRequest.onBeforeRequest.addListener(
    details => { 
    if (enabled) { 
     return { redirectUrl: chrome.runtime.getURL("blocked.html") }; 
    } 
    }, 
    { 
    urls: ["*://*.reddit.com/*"], 
    types: ["main_frame", "sub_frame"] 
    }, 
    ["blocking"] 
); 

這需要權限"webRequest", "webRequestBlocking", "*://*.reddit.com/*"

注意:這不是一個最佳解決方案:取決於enabled,註冊/取消註冊偵聽器更好,而不是在偵聽器內部(它應該儘可能快)進行檢查。這留作練習。

相關問題