Как я могу сделать кнопку действия браузера, которая выглядит и действует как переключатель
1113 просмотра
1 ответ
Цель - получить WebExtension для Firefox, который пользователь может активировать / деактивировать на панели инструментов, например, включить / выключить переключатель.
Я использую background.js с этим кодом:
browser.browserAction.onClicked.addListener(function (tab) {
switch (button) {
case 'turn-on':
enable();
break;
case 'turn-off':
disable();
break;
}
});
function enable() {
browser.browserAction.setIcon({ path: '/ui/is-on.png', });
browser.browserAction.setPopup({ popup: '/ui/turn-off.js', });
browser.webNavigation.onCommitted.addListener(onTabLoad);
}
function disable() {
browser.browserAction.setIcon({ path: '/ui/is-off.png', });
browser.browserAction.setPopup({ popup: '/ui/turn-on.js', });
browser.webNavigation.onCommitted.removeListener(onTabLoad);
}
function onTabLoad(details) {
browser.tabs.executeScript(details.tabId, {
file: '/gc.js',
allFrames true,
});
}
enable(); // enable or disable by default
Очевидно, я делаю что-то не так. Я добрый новичок в коде. Это личный проект, который я пытаюсь закончить.
Автор: rafael1138 Источник Размещён: 12.11.2019 09:03Ответы (1)
3 плюса
Ваш код
Добавляя switch
оператор для включения button
, вы никогда не определяли button
и не меняли его состояние. У вас также не было случая по умолчанию, на случай, если button
переменная не была одним из значений, для которых вы проверяли свои case
утверждения.
Вы не должны использовать, browserAction.setPopup()
чтобы установить всплывающее окно. Установка всплывающего окна приведет к тому, что всплывающее окно откроется, а фоновая страница не получит click
событие. Кроме того, всплывающее окно должно быть страницей HTML, а не JavaScript.
Смотрите ниже раздел об ошибке в Firefox, которую вам нужно обойти onTabLoad()
.
Прослушивания webNavigation.onCommitted
недостаточно, чтобы охватить все случаи, когда ваш сценарий нужно будет ввести. Другими словами, webNavigation.onCommitted
не срабатывает каждый раз при загрузке страницы. Чтобы полностью охватить каждую ситуацию, в которой ваш сценарий должен быть введен, вам нужно задать другой вопрос.
var nextButtonState;
browser.browserAction.onClicked.addListener(function (tab) {
switch (nextButtonState) {
case 'turn-on':
enable();
break;
case 'turn-off':
default:
disable();
break;
}
});
function enable() {
browser.browserAction.setIcon({ path: '/ui/is-on.png', });
//browser.browserAction.setPopup({ popup: '/ui/turn-off.js', });
browser.webNavigation.onCommitted.addListener(onTabLoad);
nextButtonState = 'turn-off';
}
function disable() {
browser.browserAction.setIcon({ path: '/ui/is-off.png', });
//browser.browserAction.setPopup({ popup: '/ui/turn-on.js', });
browser.webNavigation.onCommitted.removeListener(onTabLoad);
nextButtonState = 'turn-on';
}
function onTabLoad(details) {
//Add a setTimout to avoid a Firefox bug that Firefox is not quite ready to
// have tabs.executeScript() inject a script when the onCommitted event fires.
setTimeout(function(){
chrome.tabs.executeScript(details.tabId, {
file: '/gc.js',
allFrames true,
});
},0);
}
enable(); // enable or disable by default
Обходной путь для webNavigation.onCommitted
ошибки Firefox
В вашем onTabLoad()
коде есть изменения, необходимые для использования webNavigation.onCommitted
слушателя для вставки сценариев, используемых tabs.executeScript()
в Firefox (в Chrome это не требуется). Это связано с ошибкой в Firefox, которая приводит tabs.executeScript()
к сбою, если выполняется немедленно из webNavigation.onCommitted
слушателя. Обходной путь, который я использую, состоит в том, чтобы ввести скрипт после setTimeout(function,0)
задержки. Это позволяет Firefox выполнять код, необходимый для настройки среды, необходимой для executeScript()
работы.
function onTabLoad(details) {
//Add a setTimout to avoid a Firefox bug that Firefox is not quite ready to
// have tabs.executeScript() inject a script when the onCommitted event fires.
setTimeout(function(){
chrome.tabs.executeScript(details.tabId, {
file: '/gc.js',
allFrames true,
});
},0);
}
Обобщенное решение для кнопок с несколькими состояниями (например, кнопка переключения)
Код, который я использую для того, чтобы кнопка «Действие браузера» работала как переключатель, приведена ниже. Я изменил browserButtonStates
объект, который описывает и то , что кнопки делают и как они выглядят, чтобы добавить и удалить webNavigation.onCommitted
слушатель, onTabLoad()
. Смотрите выше для вопросов с onTabLoad()
.
Код ниже является более сложным, чем вам нужно. Я написал его, намереваясь иметь возможность перемещать его из проекта в проект, для чего нужно только изменить содержимое browserButtonStates
объекта. Затем, просто изменив этот объект, можно изменить значок, текст, текст значка, цвет значка и действие, которое выполняется в каждом состоянии (например, вкл / выкл).
background.js
//The browserButtonStates Object describes the states the button can be in and the
// 'action' function to be called when the button is clicked when in that state.
// In this case, we have two states 'on' and 'off'.
// You could expand this to as many states as you desire.
//icon is a string, or details Object for browserAction.setIcon()
//title must be unique for each state. It is used to track the state.
// It indicates to the user what will happen when the button is clicked.
// In other words, it reflects what the _next_ state is, from the user's
// perspective.
//action is the function to call when the button is clicked in this state.
var browserButtonStates = {
defaultState: 'off',
on: {
icon : '/ui/is-on.png'
//badgeText : 'On',
//badgeColor : 'green',
title : 'Turn Off',
action : function(tab) {
chrome.webNavigation.onCommitted.removeListener(onTabLoad);
},
nextState : 'off'
},
off: {
icon : '/ui/is-off.png'
//badgeText : 'Off',
//badgeColor : 'red',
title : 'Turn On',
action : function(tab) {
chrome.webNavigation.onCommitted.addListener(onTabLoad);
},
nextState : 'on'
}
}
//This moves the Browser Action button between states and executes the action
// when the button is clicked. With two states, this toggles between them.
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.browserAction.getTitle({tabId:tab.id},function(title){
//After checking for errors, the title is used to determine
// if this is going to turn On, or Off.
if(chrome.runtime.lastError){
console.log('browserAction:getTitle: Encountered an error: '
+ chrome.runtime.lastError);
return;
}
//Check to see if the current button title matches a button state
let newState = browserButtonStates.defaultState;
Object.keys(browserButtonStates).some(key=> {
if(key === 'defaultState') {
return false;
}
let state = browserButtonStates[key];
if(title === state.title) {
newState = state.nextState;
setBrowserActionButton(browserButtonStates[newState]);
if(typeof state.action === 'function') {
//Do the action of the matching state
state.action(tab);
}
//Stop looking
return true;
}
});
setBrowserActionButton(browserButtonStates[newState]);
});
});
function setBrowserActionButton(tabId,details){
if(typeof tabId === 'object' && tabId !== null){
//If the tabId parameter is an object, then no tabId was passed.
details = tabId;
tabId = null;
}
let icon = details.icon;
let title = details.title;
let text = details.badgeText;
let color = details.badgeColor;
//Supplying a tabId is optional. If not provided, changes are to all tabs.
let tabIdObject = {};
if(tabId !== null && typeof tabId !== 'undefined'){
tabIdObject.tabId = tabId;
}
if(typeof icon === 'string'){
//Assume a string is the path to a file
// If not a string, then it needs to be a full Object as is to be passed to
// setIcon().
icon = {path:icon};
}
if(icon) {
Object.assign(icon,tabIdObject);
chrome.browserAction.setIcon(icon);
}
if(title) {
let detailsObject = {title};
Object.assign(detailsObject,tabIdObject);
chrome.browserAction.setTitle(detailsObject);
}
if(text) {
let detailsObject = {text};
Object.assign(detailsObject,tabIdObject);
chrome.browserAction.setBadgeText(detailsObject);
}
if(color) {
let detailsObject = {color};
Object.assign(detailsObject,tabIdObject);
chrome.browserAction.setBadgeBackgroundColor(detailsObject);
}
}
//Set the starting button state to the default state
setBrowserActionButton(browserButtonStates[browserButtonStates.defaultState]);
manifest.json :
{
"description": "Demo Button toggle",
"manifest_version": 2,
"name": "Demo Button toggle",
"version": "0.1",
"background": {
"scripts": [
"background.js"
]
},
"browser_action": {
"default_icon": {
"32": "myIcon.png"
},
"default_title": "Turn On",
"browser_style": true
}
}
Автор: Makyen
Размещён: 15.11.2016 07:35
Вопросы из категории :
- javascript Как определить, какой из указанных шрифтов был использован на веб-странице?
- javascript Валидация клиентской стороны ASP.Net
- javascript Длина объекта JavaScript
- javascript Получение текста из выпадающего списка
- javascript Скрипт входа со скрытыми кнопками
- firefox Как подавить заполнение поля пароля Firefox?
- firefox Написание плагина Firefox для анализа пользовательского языка на стороне клиента
- firefox Как удалить пунктирный контур Firefox на КНОПКАХ, а также на ссылках?
- firefox Как определить, виден ли элемент DOM в текущем окне просмотра?
- firefox Why does the checkbox stay checked when reloading the page?
- firefox-addon Размер страницы: добавить Firefox
- firefox-addon получить URL вкладок Firefox из расширения Firefox
- firefox-addon Расширение Firefox, чтобы узнать, какое событие Javascript связано с проверяемым элементом?
- firefox-addon Можно ли просмотреть данные почтового запроса в Firefox или Chrome?
- firefox-addon Изменение HTTP-ответов в расширении Firefox
- firefox-webextensions Как увидеть или отладить скрипт содержимого Chrome в Firefox ночью (webextensions)
- firefox-webextensions How to inspect a Firefox WebExtension popup?
- firefox-webextensions Firefox WebExtensions против SDK надстройки
- firefox-webextensions Как я могу загрузить файл в Firefox Webextension без использования chrome.downloads.download?
- firefox-webextensions API WebExtensions Firefox : Chrome is undefined