Javascript 代码作为Opera UserJS工作,但给出;“未定义”;Chrome和Greasemonkey用户脚本中的错误

Javascript 代码作为Opera UserJS工作,但给出;“未定义”;Chrome和Greasemonkey用户脚本中的错误,javascript,cross-browser,greasemonkey,userscripts,userjs,Javascript,Cross Browser,Greasemonkey,Userscripts,Userjs,我正在尝试编写一个跨浏览器的用户脚本,隐藏IMDb的评级,并用一个链接替换它,该链接允许用户稍后对节目/电影进行评级 在Opera中,这种方法已经奏效,但Firefox和Chrome都遇到了一个未定义的函数和/或变量。以下是我目前的代码: function hideimdbratings() { if (document.getElementsByClassName("star-box")[0]) { reenabled = document.getElementsB

我正在尝试编写一个跨浏览器的用户脚本,隐藏IMDb的评级,并用一个链接替换它,该链接允许用户稍后对节目/电影进行评级

在Opera中,这种方法已经奏效,但Firefox和Chrome都遇到了一个未定义的函数和/或变量。以下是我目前的代码:

function hideimdbratings() {

    if (document.getElementsByClassName("star-box")[0]) {

        reenabled = document.getElementsByClassName("star-box")[0].innerHTML;

        document.getElementsByClassName("star-box")[0].innerHTML = '<a href="#" id="showvote" onclick="reenableit();">Rate!</a>';

    }
}

function reenableit() {
    document.getElementsByClassName("star-box")[0].innerHTML = reenabled;
}

window.addEventListener('load', hideimdbratings, false);
结果表明,
重新启用
未定义

我尝试将代码直接放入事件侦听器:

window.addEventListener("load", function(e) {
// ...
}, false);
这种定义函数的方式(使用Firefox的unsafeWindow):

但是,无论我做什么,
reenableit()
reenabled
都没有定义。据我所知,除了Opera,函数和变量在浏览器中都不是全局的,但我似乎还没有找到解决方案


我遗漏了什么/做错了什么?

我不知道如何使变量或函数成为全局变量,尽管这里有一个解决方法,应该对您很好:

function hideimdbratings() {
    if (document.getElementsByClassName('star-box')[0]) {

        // hide the "star-box" container
        var b = document.getElementsByClassName('star-box')[0];
        b.style.display = 'none';

        // add the "Rate!" link
        var n = document.createElement('a');
        n.setAttribute('href', 'javascript:void(0);');
        n.setAttribute('onclick', 'document.getElementsByClassName("star-box")[0].style.display = "block"; this.style.display = "none";');
        n.innerHTML = 'Rate!';
        b.parentNode.insertBefore(n, b.nextSibling);
    }
}

window.addEventListener('load', hideimdbratings, false);

啊哈!找到了。试试这个:

var uw = (this.unsafeWindow) ? this.unsafeWindow : window;
var b = document.getElementsByClassName('star-box')[0];
uw.reenabled = b.innerHTML;
b.innerHTML = '<a href="javascript:void(0);" onclick="document.getElementsByClassName(\'star-box\')[0].innerHTML = reenabled;">Rate!</a>';
var uw=(这个.unsafeWindow)?this.unsafeWindow:window;
var b=document.getElementsByClassName('star-box')[0];
uw.reenabled=b.innerHTML;
b、 innerHTML='';

启发,该代码在Chrome中不起作用,因为Chrome用户脚本在沙盒()中运行,并且您不能在Chrome中设置或使用页面范围javascript对象。而且,Chrome不完全/正确地支持
unsafeWindow

该代码可以在Firefox+Greasemonkey中使用,并小心地使用
unsafeWindow
,但此处不建议使用该代码(对Chrome也没有帮助)

当需要以跨浏览器的方式与页面范围javascript交互时,经典的方法是使用。这是唯一在Chrome中运行良好的东西

然而,最明智的做法是,如果不需要的话,根本不使用页面范围JS。对于这个问题,你不需要。(提示:切勿使用
onclick
或类似属性!始终使用
addEventListener()
或等效属性。)

重构代码以避免离开沙盒范围,它将变成:

function hideImdbRatings () {
    var oldStarBoxHTML;
    var starBox = document.getElementsByClassName ("star-box");
    if (starBox.length) {
        starBox             = starBox[0];
        oldStarBoxHTML      = starBox.innerHTML;
        starBox.innerHTML   = '<a href="#" id="showVote">Rate!</a>';

        document.getElementById ("showVote").addEventListener (
            "click",
            function () {
                //-- "this" is a special javascript scope.
                this.innerHTML = oldStarBoxHTML;
            }
        );
    }
}

window.addEventListener ('load', hideImdbRatings, false);



还有一个因素可能会阻止脚本在Chrome中工作。要解决这个问题,请在脚本的文档末尾指定
@run

确实如此,谢谢!我仍然想知道我在另一种方法中做错了什么,有人知道吗?正确的方法,+1。但是不要使用
onclick
,也不要使用
innerHTML
AMAP。@BrockAdams好极了!最聪明的人:——)@BrockAdams是的,我的错。点击。@mihau,不错。只是确保你知道,因为你是新的堆栈溢出。
var uw = (this.unsafeWindow) ? this.unsafeWindow : window;
var b = document.getElementsByClassName('star-box')[0];
uw.reenabled = b.innerHTML;
b.innerHTML = '<a href="javascript:void(0);" onclick="document.getElementsByClassName(\'star-box\')[0].innerHTML = reenabled;">Rate!</a>';
function hideImdbRatings () {
    var oldStarBoxHTML;
    var starBox = document.getElementsByClassName ("star-box");
    if (starBox.length) {
        starBox             = starBox[0];
        oldStarBoxHTML      = starBox.innerHTML;
        starBox.innerHTML   = '<a href="#" id="showVote">Rate!</a>';

        document.getElementById ("showVote").addEventListener (
            "click",
            function () {
                //-- "this" is a special javascript scope.
                this.innerHTML = oldStarBoxHTML;
            }
        );
    }
}

window.addEventListener ('load', hideImdbRatings, false);
 function hideImdbRatings () {
    var starBox = document.getElementsByClassName ("star-box");
    if (starBox.length) {
        starBox                 = starBox[0];
        starBox.style.display   = 'none';
        var rateLink            = document.createElement ('a');
        rateLink.id             = 'showVote';
        rateLink.href           = '#';
        rateLink.textContent    = 'Rate!';

        starBox.parentNode.insertBefore (rateLink, starBox);

        document.getElementById ("showVote").addEventListener (
            "click",
            function () {
                //-- "this" is a special javascript scope.
                this.style.display      = 'none';
                starBox.style.display   = 'block';
            }
        );
    }
}

window.addEventListener ('load', hideImdbRatings, false);