向 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>