【问题标题】:Detect if an alert or confirm is displayed on a page检测页面上是否显示警报或确认
【发布时间】:2011-06-19 12:20:36
【问题描述】:

有没有办法使用 JavaScript 或 jQuery 来检测是否正在显示确认或警告框?

【问题讨论】:

  • “被展示”到底是什么意思?你的意思是代码中是否有对该命令的引用?
  • 有了 Web Workers,你可以...
  • @Raynos 我假设警报不会阻止工作人员。
  • @SimeVidas 未检测到警报。假设您想做一些自动化测试并断言警报在没有人工干预的情况下有效。你会怎么做?
  • @Raynos 事实证明,弹出警报不会完全阻止窗口。这个演示 - vidasp.net/tinydemos/worker/main.html - 表明即使在警报弹出窗口打开的情况下,worker-to-window 和 window-to-worker 通信也可以正常进行。

标签: javascript jquery alert


【解决方案1】:

如果您想在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:如果您在谈论浏览器支持,是的,我假设。我在回答中指出,我只在 Chrome 中进行了测试,除此之外我不确定。还是我误解了你的评论?
  • 哦,我的意思是检测您的标准警报对话框是否实际显示在浏览器中。没有办法以编程方式保证它是。
【解决方案2】:

不,没有。您可以检查confirm 命令的返回值是否确实是truefalse,但您无法直观地检查那里是否存在。

这些东西是浏览器的一部分,而不是 DOM 的一部分。我确信有一个适用于 IE 的肮脏 hack,因为它是 windows 操作系统的私生子。

【讨论】:

  • +1 表示您的第二段几乎绝对正确。
  • @Moses 我挑战你找到一个指向 Windows 操作系统的链接,它允许你实际检查警报是否物理显示在 IE 中
  • 有很多方法可以检查这一点。你可以做两件我知道的事情——1)在alertconfirm之前注入你自己的处理程序(见下面的答案),或者2)间隔设置一个函数(setInterval)来找出最后一次的时间解锁 UI 线程的时间(虽然很长的延迟不一定来自 alert()confirm(),它可能已经足够说明问题了)。
  • @DanBeam 我将问题解释为如何确保在客户端上按预期显示警报。这只是断言您的代码调用了window.alert 函数。它不在 DOM 中,不在你的控制范围内。
【解决方案3】:

如果你愿意,你可以这样做......

(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 代码执行会停止。所以不 - 据我所知,您无法检测到当前是否正在显示。

    【讨论】:

    • 他们确实阻塞了 UI 线程,但这并不意味着你可以嗅探到这个。
    【解决方案5】:

    如果您想检测这些是否被阻止。您将不得不对将要显示的消息做自己的事情,但会覆盖本机警报/确认。

    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;这既可以被调用者检测到,也可以在大多数正常使用中看起来像“假”。
    • 这不是一个坏主意,但我担心会覆盖用户的决定,可能是他们知道会有确认。尽管我确实看到了这样做的好处,因为这是这样做的一个漏洞。可以按住 enter 的人将触发特殊对话框。但它会在 99.9% 的时间内有效。
    • 确实如此;是否强制用户阅读确认消息可能是特定于用例的。
    【解决方案6】:

    要添加到@user113716 的答案,您可以依靠时间。我假设如果确认对话框花费的时间少于 200 毫秒,它会被浏览器阻止。如果确认对话框被阻止,下面我返回 true(默认返回 false,代码在 TypeScript 中)。

        let oldConfirm = window.confirm;
        window.confirm = (msg) => {
            let time = new Date().getTime();
            let conf = oldConfirm(msg);
    
            return new Date().getTime() - time > 200 ? conf : true;
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多