检测页面上是否显示了警告框或确认框

30

是否有一种使用JavaScript或jQuery来检测确认框或提示框是否正在显示的方法?


1
“被显示”具体是什么意思?你是指代码中是否有对该命令的引用吗? - Pekka
使用Web Workers,您可以... - Šime Vidas
@Raynos 我假设警报不会阻塞工作线程。 - Šime Vidas
1
@SimeVidas,这并不是检测警报的方法。假设您想进行一些自动化测试,并断言警报是否正常工作,而无需人为干预。您会怎么做? - Raynos
1
@Raynos,事实证明警报弹出窗口不会完全阻止窗口。这个演示-http://vidasp.net/tinydemos/worker/main.html-显示了即使打开警报弹出窗口,工作线程到窗口和窗口到工作线程的通信仍然可以正常进行。 - Šime Vidas
显示剩余3条评论
6个回答

28

如果你想在alert()触发时运行一些代码,你可以尝试像这样:

我只在Chrome中进行了测试,所以不确定浏览器的支持情况。

示例:http://jsfiddle.net/Q785x/1/

(function() {
    var _old_alert = window.alert;
    window.alert = function() {
                     // run some code when the alert pops up
        document.body.innerHTML += "<br>alerting";
        _old_alert.apply(window,arguments);
                     // run some code after the alert
        document.body.innerHTML += "<br>done alerting<br>";
    };
})();

alert('hey');
alert('you');
alert('there');
当然,这只能让您在警告框弹出前后运行代码。正如@kander所指出的那样,在显示警告时JavaScript执行被暂停。

你无法保证警报会被触发。你假设 window.alert 被正确实现了! - Raynos
@Raynos:如果你在谈论浏览器支持,是的,我是这样假设的。我在我的回答中指出,我只在Chrome中进行了测试,并且我对此之外的情况不确定。或者我误解了你的评论? - user113716
哦,我实际上是指检测您的标准警报对话框是否在浏览器中物理显示。无法以编程方式保证它被显示。 - Raynos

8

没有这样的方法。您可以检查confirm命令的返回值是否为truefalse,但无法检查其是否显示出来。

这些属于浏览器而非DOM的一部分。我确定有一种针对IE的肮脏黑客方法可以实现,因为它是Windows操作系统的一个杂交儿。


7
+1 是因为你的第二段话几乎肯定是真的。 - Moses
@Moses 我挑战你找到一个链接,该链接可以让你实际检查警报是否在IE中显示。 - Raynos
有许多方法可以检查这一点。 我知道两种方法 - 1)在alertconfirm之前注入自己的处理程序(请参见下面的答案),或2)设置一个函数间隔(setInterval)来了解UI线程上次解锁的时间(虽然长时间的滞后不一定只是由于alert()confirm(),但可能足够说明问题)。 - Dan Beam
@DanBeam 我理解这个问题是如何确保在客户端上按预期显示警报。这只是断言您的代码调用了 window.alert 函数,而它不在 DOM 中,超出了您的控制范围。 - Raynos

7

如果你想这样做,你可以...

(function () {

    // remember the normal alert
    var oldAlert = (function(){ return this.alert; }()),
        oldConfirm = (function(){ return this.confirm; }());

    // inject ourself into the window.alert and window.confirm globals
    alert = function (msg) {
        oldAlert.call(document, msg);
        document.onAlert(msg);
    };
    confirm = function (msg) {
        var result = oldConfirm.call(document, msg);
        document.onConfirm(msg, result);
        return result;
    };

    // these just chill and listen for events
    document.onAlert = function (msg) {
        window.console && console.log('someone alerted: ' + msg);
    };
    document.onConfirm = function (msg) {
        window.console && console.log('someone was asked: ' + msg);
        window.console && console.log('and they answered: ' + (msg ? 'yes' : 'no'));
    };

}());

这样做的缺点是:

4
确认和警告框会阻塞事件 - 在这些框显示时,Javascript代码执行会停止。因此,据我所知,您无法检测当前是否正在显示这些框。

1
这是真的,它们会阻塞UI线程,但这并不意味着你可以嗅探它。 - Dan Beam

3

除了@user113716的回答,你还可以借助时间来判断。我认为如果确认对话框的响应时间小于200毫秒,那么它就被浏览器阻塞了。下面的代码是基于TypeScript编写的,默认返回false,如果确认对话框被阻塞则返回true。

    let oldConfirm = window.confirm;
    window.confirm = (msg) => {
        let time = new Date().getTime();
        let conf = oldConfirm(msg);

        return new Date().getTime() - time > 200 ? conf : true;
    }

3
如果您想检测这些是否被阻止。您将需要使用自己的消息来处理,但覆盖本地的警告/确认。
window.nativeAlert = window.alert;
window.alert = function (message) {
var timeBefore = new Date();
var confirmBool = nativeAlert(message);
var timeAfter = new Date();
if ((timeAfter - timeBefore) < 350) {
    MySpecialDialog("You have alerts turned off, turn them back on or die!!!");
  }
}

window.nativeConfirm = window.confirm;
window.confirm = function (message) {
var timeBefore = new Date();
var confirmBool = nativeConfirm(message);
var timeAfter = new Date();
if ((timeAfter - timeBefore) < 350) {
    MySpecialDialog("You have alerts turned off, turn them back on or die!!!");
}
 return confirmBool;
}

很明显我将时间设置为3.5毫秒。但是经过一些测试,我们只能在大约5毫秒左右点击或关闭对话框。


在 confirm() 中,如果时间太短,您也可以返回 null;这既可以被调用者检测到,也可以看起来像大多数正常用途的“false”。 - J Bryan Price
在时间过短的情况下覆盖返回到null(或false)也可以帮助防止当某人提交表单后按住Enter键太久时意外自动确认。 - J Bryan Price
这不是一个坏主意,但我担心覆盖用户的决定,可能他们知道会有确认。虽然我确实看到这样做的优势,因为这是在做这件事情时唯一的漏洞。可以按住回车键的人将触发特殊对话框。但它将99.9%的时间工作。 - DeadlyChambers
1
这是正确的;是否强制用户阅读确认消息可能取决于用例。 - J Bryan Price

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接