使用userscript定义数组内的值时更改它

时间:2017-04-13 19:04:16

标签: javascript greasemonkey userscripts

我在本地地址menu.html的文件http://127.0.0.1/menu.html中有一个类似于此的数组:

<script language='javascript'>
<!-- hide
var options = new Array('blue',
                           'a',
                           'm',
                           '1',
                           '1',
                           '0',
                           '1'
                          );

   // change value of blue to green before execution of the function below.

   createMenu(options);

// done hiding -->
    </script>

我想在使用执行blue之前将green的值更改为createMenu(options)

我尝试创建包含http://127.0.0.1/*

的新用户脚本

内容

// ==UserScript==
// @name        scriptname
// @namespace   namespace
// @description makes password blue
// @include     http://127.0.0.1/*
// @version     1
// @grant       none
// ==/UserScript==

unsafeWindow.options = new Array('green',
                               'a',
                               'm',
                               '1',
                               '1',
                               '0',
                               '1'
                              );

但是这段代码没有按预期工作。

是否有人知道如何将数据options中的值从blue更改为green

我使用的是unsafeWindow,因为我并不关心此用户脚本的安全性。

2 个答案:

答案 0 :(得分:1)

首先,有几点。你可以免于隐藏你的JavaScript - 多年前因为他们需要而编码的人。如今浏览器通常会识别JavaScript,因此隐藏它是不必要的。其次,如果您希望在GreaseMonkey脚本中包含JavaScript文件,则需要将JavaScript放在自己的.js文件中;包括HTML文件无法实现您的目标。因此,这里有一种方法可以将一个JavaScript文件包含在GreaseMonkey脚本中,并在执行 CreateMenuOptions()之前将选项蓝色更改为绿色

test_gm.js:

var options = new Array('blue',
                           'a',
                           'm',
                           '1',
                           '1',
                           '0',
                           '1'
                          );

function CreateMenuOptions(opts) {
  document.getElementsByTagName("body")[0].style.background = opts[0];
}

(GreaseMonkey)blue2green.user.js:

// ==UserScript==
// @name        Blue2Green
// @namespace   http://localhost/hayageek.com
// @include     *
// @version     1
// @grant       none
// @require     http://localhost/exp/test_gm.js
// ==/UserScript==

options[0] = "green";
CreateMenuOptions(options);

请注意,.js文件包含在使用@require的GreaseMonkey脚本中。 @include用于指定.user.js文件可以通过使.user.js文件本身执行并影响当前网页来扩充一个或多个网页的位置。

最后,还要注意这个策略不需要使用“unsafeWindow”,这应该是GreaseMonkey手册的最后手段:API

答案 1 :(得分:0)

tl;dr JSFiddle

您有三种选择。我会根据它们的黑客程度对它们进行排序,首先是最简单的解决方案:

1。覆盖createMenu()

这个很简单。

// Save old version of the function
var old_createMenu = window.createMenu;
window.createMenu = function(options) {
    // Change first value of the array
    options[0] = "green";
    // call the original function
    old_createMenu(options);
}

2。覆盖new Array()构造函数

仅在使用new Array()时有效,不适用于[]数组文字!除非必要,否则我不建议这样做:

var oldArray = Array;
Array = function() {
    if(arguments.length>0 && arguments[0]=="blue") {
        arguments[0] = "green";
        // Put back old constructor
        Array = oldArray;
    }
    // create array of arguments which must be prepended with null
    var args = [];
    args.push.apply(args, arguments);
    args.unshift(null);
    return new (Function.prototype.bind.apply(oldArray, args));
}

3。在window.options

上设置setter

仅在使用window.options时才有效,不适用于var options

这里的想法是保护window.options,每当有人试图设置一个新数组时,修改它:

var options_secret = [];
Object.defineProperty(window, "options", {
    get: function() {return options_secret;},
    set: function(new_value) {
        if(new_value.length>0 && new_value[0]=="blue")
            new_value[0] = "green";
        options_secret = new_value;
    }
})