admin管理员组文章数量:1401790
So, I have the following code:
var clicks = 0; // click counter
// Make sure this only runs on facebook
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
if (tab.url.indexOf("facebook") > -1) {
chrome.pageAction.show(tabId);
}
});
// Called when the user clicks on the page action.
chrome.pageAction.onClicked.addListener(function(tab) {
if (clicks == 0) {
chrome.pageAction.setIcon({path: "dontlike.png", tabId: tab.id}); // Update icon
chrome.pageAction.setTitle({title: "idontlike", tabId: tab.id}); // Update title
chrome.tabs.executeScript({ // Hide like buttons
code: 'var like = document.getElementsByClassName("UFILikeLink"); for (index = 0; index < like.length; ++index) { like[index].style.display="none"; }'
});
}
else {
chrome.pageAction.setIcon({path: "like.png", tabId: tab.id}); // Update icon
chrome.pageAction.setTitle({title: "like", tabId: tab.id}); // Update title
chrome.tabs.executeScript({ // Show like buttons
code: 'var like = document.getElementsByClassName("UFILikeLink"); for (index = 0; index < like.length; ++index) { like[index].style.display=""; }'
});
}
// wrap coutner around
clicks++;
if (clicks > 1)
clicks = 0;
});
for a chrome extension that hides all "Like" buttons on facebook when a pageaction icon is clicked. This works; however, any time a new facebook url is loaded, the state of the extension is lost, e.g. if the button is in dislike mode (hide all likes), if I go to a new page, it is reset to like mode.
I had an idea to persist the state of the extension using the click counter, and to make the code more functional with something like the following
var clicks = 0; // click counter
function like() {
chrome.pageAction.setIcon({path: "like.png", tabId: tab.id}); // Update icon
chrome.pageAction.setTitle({title: "like", tabId: tab.id}); // Update title
chrome.tabs.executeScript({ // Show like buttons
code: 'var like = document.getElementsByClassName("UFILikeLink"); for (index = 0; index < like.length; ++index) { like[index].style.display="none"; }'
});
clicks++;
if (clicks > 1) {
clicks = 0;
}
}
function dislike() {
chrome.pageAction.setIcon({path: "like.png", tabId: tab.id}); // Update icon
chrome.pageAction.setTitle({title: "like", tabId: tab.id}); // Update title
chrome.tabs.executeScript({ // Show like buttons
code: 'var like = document.getElementsByClassName("UFILikeLink"); for (index = 0; index < like.length; ++index) { like[index].style.display=""; }'
});
clicks++;
if (clicks > 1) {
clicks = 0;
}
}
// Make sure this only runs on facebook
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
if (tab.url.indexOf("facebook") > -1) {
chrome.pageAction.show(tabId);
if (clicks == 0) {
like();
}
else {
dislike();
}
}
});
// Called when the user clicks on the page action.
chrome.pageAction.onClicked.addListener(function(tab) {
if (clicks == 0) {
like();
}
else {
dislike();
}
});
But that code doesn't work at all (when I click on the page action icon, nothing happens and no error messages appear in the chrome console).
I'm new to JS and Chrome Extensions. Is there an easy way to persist the state of my extension, and a better way to execute the script I need to hide all like buttons?
Thank you!
So, I have the following code:
var clicks = 0; // click counter
// Make sure this only runs on facebook
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
if (tab.url.indexOf("facebook.") > -1) {
chrome.pageAction.show(tabId);
}
});
// Called when the user clicks on the page action.
chrome.pageAction.onClicked.addListener(function(tab) {
if (clicks == 0) {
chrome.pageAction.setIcon({path: "dontlike.png", tabId: tab.id}); // Update icon
chrome.pageAction.setTitle({title: "idontlike", tabId: tab.id}); // Update title
chrome.tabs.executeScript({ // Hide like buttons
code: 'var like = document.getElementsByClassName("UFILikeLink"); for (index = 0; index < like.length; ++index) { like[index].style.display="none"; }'
});
}
else {
chrome.pageAction.setIcon({path: "like.png", tabId: tab.id}); // Update icon
chrome.pageAction.setTitle({title: "like", tabId: tab.id}); // Update title
chrome.tabs.executeScript({ // Show like buttons
code: 'var like = document.getElementsByClassName("UFILikeLink"); for (index = 0; index < like.length; ++index) { like[index].style.display=""; }'
});
}
// wrap coutner around
clicks++;
if (clicks > 1)
clicks = 0;
});
for a chrome extension that hides all "Like" buttons on facebook when a pageaction icon is clicked. This works; however, any time a new facebook url is loaded, the state of the extension is lost, e.g. if the button is in dislike mode (hide all likes), if I go to a new page, it is reset to like mode.
I had an idea to persist the state of the extension using the click counter, and to make the code more functional with something like the following
var clicks = 0; // click counter
function like() {
chrome.pageAction.setIcon({path: "like.png", tabId: tab.id}); // Update icon
chrome.pageAction.setTitle({title: "like", tabId: tab.id}); // Update title
chrome.tabs.executeScript({ // Show like buttons
code: 'var like = document.getElementsByClassName("UFILikeLink"); for (index = 0; index < like.length; ++index) { like[index].style.display="none"; }'
});
clicks++;
if (clicks > 1) {
clicks = 0;
}
}
function dislike() {
chrome.pageAction.setIcon({path: "like.png", tabId: tab.id}); // Update icon
chrome.pageAction.setTitle({title: "like", tabId: tab.id}); // Update title
chrome.tabs.executeScript({ // Show like buttons
code: 'var like = document.getElementsByClassName("UFILikeLink"); for (index = 0; index < like.length; ++index) { like[index].style.display=""; }'
});
clicks++;
if (clicks > 1) {
clicks = 0;
}
}
// Make sure this only runs on facebook
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
if (tab.url.indexOf("facebook.") > -1) {
chrome.pageAction.show(tabId);
if (clicks == 0) {
like();
}
else {
dislike();
}
}
});
// Called when the user clicks on the page action.
chrome.pageAction.onClicked.addListener(function(tab) {
if (clicks == 0) {
like();
}
else {
dislike();
}
});
But that code doesn't work at all (when I click on the page action icon, nothing happens and no error messages appear in the chrome console).
I'm new to JS and Chrome Extensions. Is there an easy way to persist the state of my extension, and a better way to execute the script I need to hide all like buttons?
Thank you!
Share Improve this question asked Aug 4, 2015 at 2:54 glcohenglcohen 1931 gold badge2 silver badges11 bronze badges 3- I Haven't very well understand what You're extension have to do. What I have understand is that you have to mode : a mode where "like" buttons are hidden, and an other one where "like" buttons are shown. And you can switch betwen this to state with a click on the page action button. Am I right ? – Emrys Myrooin Commented Aug 4, 2015 at 8:13
- @EmrysMyrooin that's right! – glcohen Commented Aug 4, 2015 at 12:51
- So I have made an answer, and I think for you'r use case that the second solution is the best because it will save the state over chrome sessions – Emrys Myrooin Commented Aug 4, 2015 at 12:58
2 Answers
Reset to default 9The question of states in chrome extension can have several answers. The choice depend of the situation. Whet I have understand in your case is that you only have tow states, so I will give you some idea.
1. Persistent background script
By default, background script is loaded at chrome startup, so it lives during the whole execution of chrome, until the user explicitly close chrome. In bination with Content Script, you can have a state full system.
So You can use this background script to save a state during the execution and inform listening content scripts of the changes :
background.js
var state = 0;
chrome.pageAction.onClicked.addListener(function(tab) {
if (state = 0) {
state = 1;
state0Actions(); //Do what you want
}
else {
state = 0;
state1Actions(); //Do what you want
}
//Inform content scripts that the state have changed
chrome.tabs.sendMessage(tab.id, {state : state});
});
//At initialisation, Content scipts will request the current state to background script.
chrome.runtime.onMessage(function(message, sender, callback){
if(message.getState) callback({state : state});
});
You can then inject a content script to all facebook pages by adding this to your manifest.json
file
"content_scripts" :
[
{
"matches": ["https://www.facebook./*","http://www.facebook./*"],
"all_frames": true,
"js": ["contentScript.js"]
}
]
It will automatically inject the contentScipt.js script to all page beginning with http(s)://www.facebook.
.
contenScript.js //the actions to do for each states function state0Actions() { //Do what you want for the state 0 }
function state1Actions()
{
//Do what you want for the state 1
}
//Message will be received at each update of state in the background page
chrome.runtime.onMessage.addListner(function(message, sender, callback))
{
//Check the message is valid
if(message.state == null)
{
console.log("Unreconized message");
return;
}
//Do actions for the right state
//You also can use if statements here... Switch are more used when there is lots of states
switch(message.state) {
case 0 : state0Actions(); break;
case 1 : state1Actions(); break;
}
}
//Request the current state to initialise the script
chrome.runtime.sendMessage({getState: true});
Here, the onMessage handler will be call a first time when he is loaded and then each time the background change the state.
Pay attention that the state will be reset at the chrome startup.
2. Chrome storage
You can use chrome.storage API to manage the state. The main point of this is that the state will be saved and will not be reset at chrome startup.
To do this, you have pretty the same background code :
chrome.pageAction.onClicked.addListener(function(tab) {
chrome.storage.local.get("state", function(result)
{
//First initialisation of the state in the local storage
if(result.state == null)
{
chrome.storage.local.set({state: 0});
state0Actions(); //Do what you want
}
else if (result.state == 0) {
result.state = 1;
state0Actions(); //Do what you want
}
else {
result.state = 0;
state1Actions(); //Do what you want
}
//Save the new state to the storage
chrome.storage.set({state: result.state});
}
});
And the content script will listen changes of the local storage instead of wating update notification from the background page :
//the actions to do for each states
function state0Actions()
{
//Do what you want for the state 0
}
function state1Actions()
{
//Do what you want for the state 1
}
chrome.storage.local.onChanged.addListener(function(changes, areaName)
{
if(areaName != "local" || changes.state == null) return;
switch(changes.state)
{
case 0 : state0Actions(); break;
case 1 : state1Actions(); break;
}
})
chrome.storage.local.get("state", function(result){
if(result.state == null) state0Actions(); //Do what you want if the state is not yet initialised
else if (result.state == 0) state0Actions(); //Do what you want
else if (result.state == 1) state1Actions(); //Do what you want
})
You also can use chrome.storage.sync
instead of chrome.storage.local
for a shared state with all user's devices.
This are to way to play with state. you have to pare what is the better for your use case. The code I have written is not tested, they are only example to illustrate my explanation.
Don't forget to check Chrome API documentation
When the extension is using a non-persistent background page aka Event page it is unloaded after ~5 seconds of inactivity. And every time it's reloaded the code runs again and all variables are re-initialized, thus losing the previous state.
The solution is to store the state in localStorage
which doesn't require any additional permissions in manifest.json:
Initialization:
var clicks = localStorage.clicks || 0; // click counter
Toggling and storing (no need for
++
andif
):var clicks = localStorage.clicks = 1 - clicks;
The value will be stringified and stored as "0" or "1" but for the above arithmetic it's not a problem.
本文标签: javascriptPersist a page action39s state in a chrome extensionStack Overflow
版权声明:本文标题:javascript - Persist a page action's state in a chrome extension - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744311468a2600049.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论