0

所以我想做的是:如果我的 ajax 请求返回一些东西,我想播放声音。如果用户在 15 秒内到达选项卡,那么什么都不会发生。但如果他花费超过 15 秒,就会触发警报。我似乎无法让这种行为起作用....

 $.getJSON('/orders/'+restaurant+'/.json', function(data) { 

 $.each(data, function(key, val) {
     //does some processing on the data
 });
 if (data.length > 0){
  $('#play_sound').html('<iframe width="1" height="1" src="http://www.youtube.com/embed/3puTnBV8DbQ?autoplay=1" frameborder="0" ></iframe>');


  setTimeout
  (
    function()
     {
       var isActive;

       window.focus = function (){
         isActive = true;
       }
       window.onblur = function() {
         isActive = false;
       };

       if ((!isActive)){
         alert('ajax request returned info');
        }
      }
  , 15000
); 
}

现在我有点知道我可能需要一个额外的变量,就像一个计数器......我不知道......

建议?

4

2 回答 2

2

您当前的流程如下所示:

  1. ajax 请求成功。
  2. 15 秒后,setTimeout创建两个事件处理程序来监听window.focus(应该是window.onfocus)和window.onblur.
  3. 在同一个setTimeout调用中,isActive检查 的值,它是undefined. 由于脚本没有时间监听焦点或模糊事件——因为它们是在同一个setTimeout语句中创建的——这意味着isActive没有被赋予一个值。

您的变量isActive和函数应该单独和全局声明:

var isActive = true;
window.onfocus = function () {
    isActive = true;
};
window.onblur = function() {
    isActive = false;
};

然后,像这样使用你的超时:

// Ajax request succeeds above

setTimeout(function() {
    if (!isActive) {
        alert("ajax request returned info");
    }
}, 15000);

这样,isActive是一个全局可用的变量,它将始终知道窗口是否处于活动状态。

编辑

还有一个问题。如果用户听到通知,将注意力集中在窗口上阅读它,然后再次模糊窗口怎么办?15 秒过后,即使已经看到通知,由于窗口不在焦点上,仍会发出警报。

所以,让我们通过将你设置setTimeout为一个提醒变量来解决这个问题,一旦窗口聚焦,我们就可以取消它。

var isActive = true;
var reminder = false;
window.onfocus = function () {
    isActive = true;
    if (reminder !== false) {
        clearTimeout(reminder);
        reminder = false;
    }
};
window.onblur = function() {
    isActive = false;
};

然后,将第二个片段替换为:

// Ajax request succeeds above

reminder = setTimeout(function() {
    if (!isActive) {
        alert("ajax request returned info");
    }
}, 15000);

因此,如果用户在警报响起之前看到通知,则警报将被取消。

于 2013-08-02T17:31:31.977 回答
1

您的代码有两个问题。

第一个是您正在覆盖窗口对象的focus方法,而不是通过onfocus.

第二个问题是您需要在超时和成功回调之外分配处理程序,以便在执行超时时数据可用:

dvar isActive = true; //the window is focused when the code is executed first

//all this will happen independently of the AJAX call so that state is available when the timeout executes

window.onfocus = function () {
     isActive = true; //window gains focus while waiting for the AJAX call to finish
};
window.onblur = function () {
       isActive = false; //window loses focus focus while waiting for the AJAX call to finish  
};

$.getJSON('/orders/' + restaurant + '/.json', function (data) {

    $.each(data, function (key, val) {
        //does some processing on the data
    });
    if (data.length > 0) {
        $('#play_sound').html('<iframe width="1" height="1" src="http://www.youtube.com/embed/3puTnBV8DbQ?autoplay=1" frameborder="0" ></iframe>');

        setTimeout(function () {
            if ((!isActive)) {
                alert('ajax request returned info');
            }
        }, 15000);
    }
});
于 2013-08-02T17:34:11.843 回答