代码之家  ›  专栏  ›  技术社区  ›  ManIkWeet

在googlechrome的页面中注入JS和userscript中的变量?

  •  2
  • ManIkWeet  · 技术社区  · 15 年前

    我的代码是:

    // ==UserScript==
    // @name   Test
    // @description  Test
    // @include   http://www.google*
    // ==/UserScript==
    
    var toAlert = "This is what I want to alert...";
    alert("Before implementation...");
    contentEval( function(){ alert(toAlert);});
    alert("And after...");
    function contentEval(source) {
      // Check for function input.
      if ('function' == typeof source) {
        // Execute this function with no arguments, by adding parentheses.
        // One set around the function, required for valid syntax, and a
        // second empty set calls the surrounded function.
        source = '(' + source + ')();'
      }
    
      // Create a script node holding this  source code.
      var script = document.createElement('script');
      script.setAttribute("type", "application/javascript");
      script.textContent = source;
    
      // Insert the script node into the page, so it will run, and immediately
      // remove it to clean up.
      document.body.appendChild(script);
      document.body.removeChild(script);
    }
    

    但它不起作用。。。 我做错什么了?

    1 回复  |  直到 15 年前
        1
  •  4
  •   Brock Adams    15 年前

    toAlert 碰巧是在页面的全局范围中定义的。


    这就是为什么不能直接将该函数从扩展范围注入到页面范围,而必须从源字符串重新创建它。

    这意味着,如果在页作用域中创建函数,则函数所需的任何变量或函数必须:

    1. 已经在源页面中全局存在。
      或者

    例如,像这样修改代码。。。

    //-- Must recreate the variable that the function requires.
    scriptStr  = 'var toAlert="' + toAlert +'";';
    
    //-- Now the function.
    scriptStr += '(' + source.toString() + ')();'
    
    var script = document.createElement('script');
    script.textContent = scriptStr;
    

    ... 工作,但这种方法显然变得混乱。


    (A) 将所有JavaScript保存在扩展中;不要与页面的JavaScript交互。

    或者(B)如果您必须与页面的JS交互,或者加载jQuery之类的库,那么 全部的

    像这样:

    function localMain ()
    {
        /*--- Put EVERYTHING inside this wrapper, functions and variables.
            Call or use nothing else that's defined in the GM script here.
            Can use objects in the source page's scope, though.
        */
    }
    
    //--- Now create the function in the page's scope and run it.
    var scriptNode          = document.createElement ("script");
    scriptNode.textContent  = localMain.toString() + "\n localMain ();";
    document.head.appendChild (scriptNode);
    

    请注意,如果还要将库加载到页面的作用域中,则可能需要延迟运行 localMain()