Now and then, when I’m in a big hurry, I use JavaScript’s alert()
function to do some quick and dirty debugging. The problem is when one of those happens to be inside a loop that goes through so many iterations that the alerts take control, and you can’t even close the browser window. This script (with the help of Greasemonkey) adds a Cancel button that allows you to temporarily block alerts and get out of that vicious cycle.
Instant Gratification
If you don’t want to read the detailed explanation of the code, you can just install the script: alert.user.js
Step by Step
Anyone remember that other JavaScript function, confirm()
? It issues a dialog box that looks just like an alert window, but offers the user two buttons: OK or Cancel. When a button is clicked, the function returns true
or false
, respectively.
So if we redefine alert()
to re-route its message through confirm()
, then every alert we issue can automagically offer us the option of suppressing subsequent alerts.
Let’s start with the essence of what we’re doing:
function alert(message) {
alert.block = !confirm(message);
}
We’re defining a new function named alert()
, to replace the built-in one in the current window. We’re also adding a property to it, called block
, which will indicate whether alerts are currently being blocked. If the OK button is clicked, confirm()
returns true
, and alert.block
gets set to false
. If Cancel is clicked, alert.block
gets set to true
.
The next step is to actually block alerts, according to the value of that property:
function alert(message) {
if (!alert.block) {
alert.block = !confirm(message);
}
}
Now, if someone clicks Cancel, no more alerts will get past that condition, and our alert()
function will just return without doing anything. But that’s not quite what we want. We want to stop the alerts, but not necessarily for the life of the page view; just long enough to wrest back control of the browser. So, we introduce a timeout that sets alert.block
back to false
after five seconds:
function alert(message) {
if (!alert.block) {
alert.block = !confirm(message);
if (alert.block) {
setTimeout("alert.block = false;", 5000);
}
}
}
Now we’re getting there, and in fact, the code above does everything it really needs to. However, let’s make it a little more user-friendly by explaining what the Cancel and OK buttons do. And as a finishing touch, we’ll move that magic number 5000
into a variable named delay
, to make the code more readable.
function alert(message) {
var delay = 5000; // 5 seconds
if (!alert.block) {
message += "\n\n* Click 'OK' to dismiss this alert." +
"\n* Click 'Cancel' to quell runaway alerts for " +
(delay / 1000) + " seconds.";
alert.block = !confirm(message);
if (alert.block) {
setTimeout("alert.block = false;", delay);
}
}
}
Greasemonkey
Now that we’ve got a working script, we need to make it work with Greasemonkey. For security reasons, any functions defined in a Greasemonkey script won’t be available on the page. There’s a way around that though. Use the special Greasemonkey variable unsafeWindow
:
unsafeWindow.alert = function alert(message) {
var delay = 5000; // 5 seconds
if (!alert.block) {
message += "\n\n* Click 'OK' to dismiss this alert." +
"\n* Click 'Cancel' to quell runaway alerts for " +
(delay / 1000) + " seconds.";
alert.block = !confirm(message);
if (alert.block) {
setTimeout("alert.block = false;", delay);
}
}
};
See Mark Pilgrim’s “Avoid Common Pitfalls in Greasemonkey” for more info on the security issues that make this necessary.
Example
The button below issues ten alerts in a row. Here’s how it’s set up:
<script type="text/javascript">
//<![CDATA[
function lotsOfAlerts() {
for (var i = 1; i <= 10; i++) {
alert('number ' + i);
}
}
//]]>
</script>
<button onclick="lotsOfAlerts();">I GOTTA SEE THIS</button>
Install the Greasemonkey script, reload this page, then click: