向 Greasemonkey 脚本添加菜单的最佳方式
Best way to add a menu to Greasemonkey script
我正在创建一个 Grease Monkey 脚本,目前我正在将我的设置变量存储在代码中。但我想让它们对用户来说很容易改变。最好的方法是创建一个设置菜单,但我不知道如何做以及从哪里开始(这是我的第一个浏览器扩展)。你能解释一下该怎么做吗(或者至少在哪里寻找信息)?
我想了解:
1)如何存储变量并访问它们?
2) 如何在脚本中放置设置菜单?
3) 我可以把这个设置菜单放在哪里?
伪代码:
//settings
let foo = false; // how do
let bar = true; // I change these guys using the menu?
创建一个带有输入的容器,并监听输入的变化。更改时,将变量保存在 localStorage 中。此外,在页面加载时,检查 localStorage 属性 中是否有任何内容 - 如果有,请使用保存的值填充输入:
// Retrieve the saved values, or if there aren't any, set the default values
// let vals = localStorage.vals ? JSON.parse(localStorage.vals) : ['3', 'foo', '8'];
let vals = ['3', 'foo', '8'];
const inputs = [...menu.querySelectorAll('input')];
// Populate the inputs with the values:
inputs.forEach((input, i) => input.value = vals[i]);
// Listen for changes to the inputs. On change, put all values into the "vals" variable
// and save it in localStorage:
const menu = document.querySelector('#menu');
menu.addEventListener('input', () => {
vals = inputs.map(input => input.value);
console.log(vals);
// Save it:
// localStorage.vals = JSON.stringify(vals);
});
<div id="menu">
<div>var1: <input value="3"></div>
<div>var2: <input value="foo"></div>
<div>var3: <input value="8"></div>
</div>
(不幸的是,localStorage 在沙盒 Stack Snippet iframe 中不起作用,这就是它的使用被注释掉的原因)
要保存对象而不是数组,您可以为输入命名:
// Retrieve the saved values, or if there aren't any, set the default values
// let vals = localStorage.vals ? JSON.parse(localStorage.vals) : { var1: 'foo', var2: 'bar' };
let vals = { var1: 'foo', var2: 'bar' };
const menu = document.querySelector('#menu');
const inputs = [...menu.querySelectorAll('input')];
// Populate the inputs with the values:
Object.entries(vals)
.forEach(([propName, val]) => {
menu.querySelector(`input[name="${propName}"]`).value = val;
});
// Listen for changes to the inputs. On change, put all values into the "vals" variable
// and save it in localStorage:
menu.addEventListener('input', () => {
vals = inputs.reduce((a, input) => {
a[input.name] = input.value;
return a;
}, {});
console.log(vals);
// Save it:
// localStorage.vals = JSON.stringify(vals);
});
<div id="menu">
<div>var1: <input name="var1"></div>
<div>var2: <input name="var2"></div>
</div>
我正在创建一个 Grease Monkey 脚本,目前我正在将我的设置变量存储在代码中。但我想让它们对用户来说很容易改变。最好的方法是创建一个设置菜单,但我不知道如何做以及从哪里开始(这是我的第一个浏览器扩展)。你能解释一下该怎么做吗(或者至少在哪里寻找信息)? 我想了解: 1)如何存储变量并访问它们? 2) 如何在脚本中放置设置菜单? 3) 我可以把这个设置菜单放在哪里?
伪代码:
//settings
let foo = false; // how do
let bar = true; // I change these guys using the menu?
创建一个带有输入的容器,并监听输入的变化。更改时,将变量保存在 localStorage 中。此外,在页面加载时,检查 localStorage 属性 中是否有任何内容 - 如果有,请使用保存的值填充输入:
// Retrieve the saved values, or if there aren't any, set the default values
// let vals = localStorage.vals ? JSON.parse(localStorage.vals) : ['3', 'foo', '8'];
let vals = ['3', 'foo', '8'];
const inputs = [...menu.querySelectorAll('input')];
// Populate the inputs with the values:
inputs.forEach((input, i) => input.value = vals[i]);
// Listen for changes to the inputs. On change, put all values into the "vals" variable
// and save it in localStorage:
const menu = document.querySelector('#menu');
menu.addEventListener('input', () => {
vals = inputs.map(input => input.value);
console.log(vals);
// Save it:
// localStorage.vals = JSON.stringify(vals);
});
<div id="menu">
<div>var1: <input value="3"></div>
<div>var2: <input value="foo"></div>
<div>var3: <input value="8"></div>
</div>
(不幸的是,localStorage 在沙盒 Stack Snippet iframe 中不起作用,这就是它的使用被注释掉的原因)
要保存对象而不是数组,您可以为输入命名:
// Retrieve the saved values, or if there aren't any, set the default values
// let vals = localStorage.vals ? JSON.parse(localStorage.vals) : { var1: 'foo', var2: 'bar' };
let vals = { var1: 'foo', var2: 'bar' };
const menu = document.querySelector('#menu');
const inputs = [...menu.querySelectorAll('input')];
// Populate the inputs with the values:
Object.entries(vals)
.forEach(([propName, val]) => {
menu.querySelector(`input[name="${propName}"]`).value = val;
});
// Listen for changes to the inputs. On change, put all values into the "vals" variable
// and save it in localStorage:
menu.addEventListener('input', () => {
vals = inputs.reduce((a, input) => {
a[input.name] = input.value;
return a;
}, {});
console.log(vals);
// Save it:
// localStorage.vals = JSON.stringify(vals);
});
<div id="menu">
<div>var1: <input name="var1"></div>
<div>var2: <input name="var2"></div>
</div>