代码之家  ›  专栏  ›  技术社区  ›  psycho brm

jQuery.no用户脚本中的冲突奇怪行为,仅在Firefox中

  •  2
  • psycho brm  · 技术社区  · 11 年前

    我有一个包含以下内容的用户脚本:

    // userscript header
    (function() {
        // here is jquery source code
        var $ = $.noConflict();
    })();
    

    我正在使用的网站正在使用mootools,所以该网站的代码取决于 $ 这个 noConflict 由于一些奇怪的原因,在Firefox(23.0.1)中没有帮助。该网站仍然以$获得jQuery,这破坏了网站原有的功能。

    但是,当我将其更改为: var$=jQuery.noConflict();

    它有效。为什么?

    我不能把userscript放在jsfiddle上,所以这里有一张包含所有代码的gif图(左边是HTML,右边是userscript),显示了问题:

    jQuery.noConflict weird behavior

    版本:一切都是最新的,Firefox 23.0.1,Greasemonkey 1.11,jQuery v1.10.2,Mootools 1.4.5-nc

    “Bug”不会出现在:Chrome 29.0.1547.66米,Opera 12.16米

    2 回复  |  直到 11 年前
        1
  •  2
  •   nmaier    11 年前

    让我们看看如何 noConflict() 实际实现。。。

    if ( window.$ === jQuery ) {
      window.$ = _$; // where $_ is window.$ before jquery reassigns it.
    }
    

    现在我们需要记住 window 操作的用户脚本实际上与 网站看到了。它是一个沙盒包装(至少在Greasemonkey和Scriptish中是这样)。该包装器实际上隐藏了所有“expando”,即原始对象上添加或覆盖的财产。

    因此,在您的用户脚本中 window.$ === undefined 而在实际页面中,它被定义为那个mootools助手。 unsafewindow.$ 也是mootools助手,因为 unsafeWindow 是展开的页面 .

    现在,当您的用户脚本包含jQuery时, $ 将在包装上设置 .原始页面 window.$ 从网站的角度来看,仍有争议。

    接下来,呼叫 .noConflict() ,如上所述,将恢复 窗口$ 返回,但在沙盒包装器上。因此 窗口$ 在用户脚本沙箱中 undefined 再说一遍,当页面 窗口$ (又名。 unsafeWindow.$ 在用户脚本沙盒中)仍然是moo助手(实际上从未更改)。

    使现代化 :Greasemonkey在的“无授权”分支中主动显式禁用这些包装器 createSandox() 通过设置 wantXRays = false 我认为这是 a bug .

    现在,这就是你需要的原因 .noConflict()(无冲突) 在第一位 GM .

    var $ = $.noConflict() 无法工作,因为这是一个错误。这个 var $ 将被吊起,因此它立即未被定义。jQuery实际上不会设置它(它只是设置 窗口$ ,不是本地范围 $ ),因此 $.noConflict() 呼叫变为 undefined.noConflict() .

        2
  •  0
  •   Steve    11 年前

    我对jQuery的不太熟悉 noConflict() 方法,但我认为它必须在全局范围内使用。

    您正在匿名函数的范围内使用它,因此 无冲突() 方法不会对 $ 声明在此范围之外。

    移动 $.noConflict() 进入全局范围,您应该没事:

    $.noConflict();
    (function() {
        ...
    })();