似乎无法适应window.focus和window.onblur到我的情况

时间:2013-08-02 17:15:25

标签: javascript

所以我想做的是:如果我的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
); 
}

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

建议?

2 个答案:

答案 0 :(得分:2)

您当前的流程如下:

  1. ajax请求成功。
  2. 15秒后,setTimeout会创建两个事件处理程序来监听window.focus(应该是 window.onfocus )和window.onblur
  3. 在同一setTimeout来电中,isActive的值会被选中,而undefined则为setTimeout。由于脚本没有时间监听焦点或模糊事件 - 因为它们是在同一isActive语句中创建的 - 这意味着isActive没有给出值。
  4. 您的变量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

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

    修改

    还有另一个问题。如果用户听到通知,关注窗口进行阅读,然后再次模糊窗口,该怎么办?当15秒过去时,即使已经看到通知,由于窗口未对焦,仍会发出警报。

    所以,让我们通过将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);
    

    然后,用这个替换第二个片段:

    {{1}}

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

答案 1 :(得分: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);
    }
});