2

我正在尝试使用 Greasemonkey 脚本中的 jQuery Waypoints 插件,但似乎无法进行基本测试。有谁知道 Waypoints 不能从用户脚本中工作的原因?

@require 行:

// @require     http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js
// @require     http://cdn.jsdelivr.net/jquery.waypoints/2.0.2/waypoints.min.js

脚本:

$('div.container').waypoint(function(){
    alert('you hit bottom');
},{ offset: 'bottom-in-view' });

有趣的是,如果这个带有“容器”类的 div 存在,脚本就会中断,并且该语句之外的代码将不会运行。如果我更改选择器以查找一些不存在的元素,则脚本的其余部分运行良好。

有谁知道这里发生了什么?我正用头撞墙。谢谢!

PS。我还尝试将 Waypoints 插件代码直接粘贴到脚本中(而不是使用 CDN),我得到了相同的结果。

4

1 回答 1

2

不幸的是,该扩展不如许多其他 jQuery 扩展编写得好。它使用this, 和jQuery,比方说,“不幸”的方式。这意味着它会从用户脚本范围内崩溃,即使@grant none已设置。

对于像这样的库,您的选择是:

  • 寻找更好的图书馆(推荐)。

  • 自己找一个更好的方法来编码,如果它不是太复杂的话。

  • 如果页面不使用 jQuery,或者使用兼容版本的 jQuery,那么您可以通过Script Injection使用此类扩展。见下文。

  • 如果页面使用不兼容的 jQuery 版本,那么您可能无法在不破坏页面的情况下做任何事情。 有时可以使用解决方法,但这是另一个问题。


页面已经使用兼容版本的 jQuery 的情况:

你只需要注入 Waypoints 和任何使用 Waypoints 的代码。不要使用@require.
像这样:

// ==UserScript==
// @name        _YOUR_SCRIPT_NAME
// @include     http://YOUR_SERVER.COM/YOUR_PATH/*
// @grant       GM_addStyle
// ==/UserScript==
/*- The @grant directive is needed to work around a design change
    introduced in GM 1.0.   It restores the sandbox.
*/

function GM_main () {
    $('div.container').waypoint(function(){
        alert('you hit bottom');
    },{ offset: 'bottom-in-view' });
}

addJS_Node (
    null,
    "http://cdn.jsdelivr.net/jquery.waypoints/2.0.2/waypoints.min.js",
    null,
    function () {addJS_Node (null, null, GM_main); }
);

//-- This is a standard-ish utility function.
function addJS_Node (text, s_URL, funcToRun, runOnLoad) {
    var D                                   = document;
    var scriptNode                          = D.createElement ('script');
    if (runOnLoad) {
        scriptNode.addEventListener ("load", runOnLoad, false);
    }
    scriptNode.type                         = "text/javascript";
    if (text)       scriptNode.textContent  = text;
    if (s_URL)      scriptNode.src          = s_URL;
    if (funcToRun)  scriptNode.textContent  = '(' + funcToRun.toString() + ')()';

    var targ = D.getElementsByTagName ('head')[0] || D.body || D.documentElement;
    targ.appendChild (scriptNode);
}

页面根本不使用 jQuery 的情况:

您需要注入 jQuery,然后将 Waypoints 的注入和任何使用 Waypoints 的代码链接起来。不要使用@require.
像这样:

// ==UserScript==
// @name        _YOUR_SCRIPT_NAME
// @include     http://YOUR_SERVER.COM/YOUR_PATH/*
// @grant       GM_addStyle
// ==/UserScript==
/*- The @grant directive is needed to work around a design change
    introduced in GM 1.0.   It restores the sandbox.
*/

function GM_main () {
    $('div.container').waypoint(function(){
        alert('you hit bottom');
    },{ offset: 'bottom-in-view' });
}

//-- Add jQuery.
addJS_Node (
    null,
    "http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js",
    null,
    addWaypointsAndFireMain
);

function addWaypointsAndFireMain () {
    addJS_Node (
        null,
        "http://cdn.jsdelivr.net/jquery.waypoints/2.0.2/waypoints.min.js",
        null,
        function () {addJS_Node (null, null, GM_main); }
    );
}

//-- This is a standard-ish utility function.
function addJS_Node (text, s_URL, funcToRun, runOnLoad) {
    var D                                   = document;
    var scriptNode                          = D.createElement ('script');
    if (runOnLoad) {
        scriptNode.addEventListener ("load", runOnLoad, false);
    }
    scriptNode.type                         = "text/javascript";
    if (text)       scriptNode.textContent  = text;
    if (s_URL)      scriptNode.src          = s_URL;
    if (funcToRun)  scriptNode.textContent  = '(' + funcToRun.toString() + ')()';

    var targ = D.getElementsByTagName ('head')[0] || D.body || D.documentElement;
    targ.appendChild (scriptNode);
}


GM_不幸的是,当您必须注入脚本代码时,使用函数变得更加混乱。如果这适用于您,请参阅:“如何从必须在目标页面范围内运行的代码调用 Greasemonkey 的 GM_ 函数?”

于 2013-04-20T08:05:15.600 回答