That code won't work in Chrome because Chrome userscripts operate in a sandbox ("isolated world"), and you cannot set or use page-scope javascript objects in Chrome. And, Chrome does not fully/properly support unsafeWindow
.
The code would work in Firefox+Greasemonkey with careful use of unsafeWindow
, but that is not recommended here (and won't help with Chrome).
The classic approach, when one needs to interact with page-scope javascript in a cross-browser way is to use Script Injection. This is the only thing that works well in Chrome.
However, the smartest thing to do is not use page-scope JS at all if you don't have to. And, for what's in this question, you don't need to. (Hint: never use onclick
or similar attributes! Always use addEventListener()
, or equivalent.)
Refactoring the code to avoid leaving the sandbox scope, it becomes:
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);
However 2, you'll notice that all of the code so far, busts the interaction of IMDB's rating widget. This is because it's overwriting innerHTML
, which trashes the widget's event handlers. Don't use innerHTML
like that.
The smartest-er thing to do is to hide the block, similar to Geo's answer, like so:
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);
There is an additional factor that may stop the script from working in Chrome. By default, Chrome userscripts may run after the load
event. To work around that, specify @run-at document-end
in the metadata block of your script.