Javascript 代码作为Opera UserJS工作,但给出;“未定义”;Chrome和Greasemonkey用户脚本中的错误
我正在尝试编写一个跨浏览器的用户脚本,隐藏IMDb的评级,并用一个链接替换它,该链接允许用户稍后对节目/电影进行评级 在Opera中,这种方法已经奏效,但Firefox和Chrome都遇到了一个未定义的函数和/或变量。以下是我目前的代码: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
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);