javascript - 作为 javascript 工作,但不作为 Greasemonkey 脚本工作?

标签 javascript greasemonkey

我正在制作 Greasemonkey 脚本以在 cnn.com 上的视频旁边添加下载链接。

我使用了 HTML 页面的保存版本来测试我的脚本,并且能够让它完美地工作。然后当我将 javascript 放入 Greasemonkey 并在实际站点上尝试时,它没有工作。

这不是完整的脚本,而是有问题的脚本部分。它只是应该在每个 div 的底部添加一个带有“sec_video_box”类的链接(如图所示)。

// ==UserScript==
// @name           CNN Download
// @namespace      Cool
// @description    CNN Download
// @include        http://*cnn.com/video/*
// ==/UserScript==

var getClass = function(clssName, rootNode /*optional*/){

    var root = rootNode || document,
    clssEls = [],
    elems,
    clssReg = new RegExp("\\b"+clssName+"\\b");

    // use the built in getElementsByClassName if available
    if (document.getElementsByClassName){
        return root.getElementsByClassName(clssName);
    }

    // otherwise loop through all(*) nodes and add matches to clssEls
    elems = root.getElementsByTagName('*');
    for (var i = 0, len = elems.length; i < len; i+=1){
        if (clssReg.test(elems[i].className)) clssEls.push(elems[i])
    }

    return clssEls;

};

function insertlinks() { 
    var boxes = getClass("sec_video_box");

    for (i=0; i<boxes.length; i++) { 
            var theboxid = boxes[i].getAttribute("id");
            document.getElementById(theboxid).innerHTML = document.getElementById(theboxid).innerHTML + '<a href="'+ theboxid +'">link</a>';
    } 
}

window.onload = insertlinks ();


Pic: JS works; GM doesn't.

有人可以告诉我我做错了什么吗?

最佳答案

该脚本的 3 个最大问题是:

  1. 你不能那样使用window.onload;见GM Pitfall #2: Event Handlers .始终使用 addEventListener() 或 jQuery。
  2. 无论如何,这些视频对象是在文档加载后通过 AJAX 输入的。
  3. 这些视频对象可以通过 AJAX 改变;所以您需要监视新对象。

有一些小问题,但首先请注意整个现有脚本可以使用 jQuery 简化为:

// ==UserScript==
// @name            CNN Download
// @namespace       Cool
// @description     CNN Download
// @include         http://*cnn.com/video/*
// @require         http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js
// ==/UserScript==

function insertlinks () {
    var boxes = $(".sec_video_box");

    boxes.each ( function () {
        var theboxid    = this.id;
        $(this).append ('<a href="'+ theboxid +'">link</a>');
    } );
}

$(window).load (insertlinks);

(重要提示:此示例代码仍然无法运行。)




处理 AJAX 问题,它变成:

// ==UserScript==
// @name            CNN Download
// @namespace       Cool
// @description     CNN Download
// @include         http://*cnn.com/video/*
// @require         http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js
// ==/UserScript==

function insertlink (jNode) {
    var theboxid    = jNode.attr ('id');
    jNode.append ('<a href="' + theboxid + '">link</a>');
}

waitForKeyElements (".sec_video_box", insertlink, false);

function waitForKeyElements (
    selectorTxt,    /* Required: The jQuery selector string that
                        specifies the desired element(s).
                    */
    actionFunction, /* Required: The code to run when elements are
                        found. It is passed a jNode to the matched
                        element.
                    */
    bWaitOnce,      /* Optional: If false, will continue to scan for
                        new elements even after the first match is
                        found.
                    */
    iframeSelector  /* Optional: If set, identifies the iframe to
                        search.
                    */
)
{
    var targetNodes, btargetsFound;

    if (typeof iframeSelector == "undefined")
        targetNodes     = $(selectorTxt);
    else
        targetNodes     = $(iframeSelector).contents ()
                                           .find (selectorTxt);

    if (targetNodes  &&  targetNodes.length > 0) {
        /*--- Found target node(s).  Go through each and act if they
            are new.
        */
        targetNodes.each ( function () {
            var jThis        = $(this);
            var alreadyFound = jThis.data ('alreadyFound')  ||  false;

            if (!alreadyFound) {
                //--- Call the payload function.
                actionFunction (jThis);
                jThis.data ('alreadyFound', true);
            }
        } );
        btargetsFound   = true;
    }
    else {
        btargetsFound   = false;
    }

    //--- Get the timer-control variable for this selector.
    var controlObj      = waitForKeyElements.controlObj  ||  {};
    var controlKey      = selectorTxt.replace (/[^\w]/g, "_");
    var timeControl     = controlObj [controlKey];

    //--- Now set or clear the timer as appropriate.
    if (btargetsFound  &&  bWaitOnce  &&  timeControl) {
        //--- The only condition where we need to clear the timer.
        clearInterval (timeControl);
        delete controlObj [controlKey]
    }
    else {
        //--- Set a timer, if needed.
        if ( ! timeControl) {
            timeControl = setInterval ( function () {
                    waitForKeyElements (    selectorTxt,
                                            actionFunction,
                                            bWaitOnce,
                                            iframeSelector
                                        );
                },
                500
            );
            controlObj [controlKey] = timeControl;
        }
    }
    waitForKeyElements.controlObj   = controlObj;
}

(哪个有效。)

关于javascript - 作为 javascript 工作,但不作为 Greasemonkey 脚本工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7539088/

相关文章:

javascript - 使用 JavaScript 一次更改具有相同类名的多个元素的样式?

javascript - UI 路由器 $stateParams 是只读的

javascript - 如何使用 jQuery 从 SPAN 元素中提取名称属性?

javascript - 在 "material-components-web"代码中使用 "react-boilerplate"

javascript - react : How do I update my components state from an external function?

javascript - 嵌套 Backbone 集合的 URL

javascript - Greasemonkey 能否在新页面或重新加载时保持脚本数据和连接处于事件状态?

javascript - 如何让 Greasemonkey 单击具有指定文本的链接?

Greasemonkey 脚本未更新