Вопрос по javascript – Есть ли способ обнаружить, если окно браузера не активно в данный момент?

522

У меня есть JavaScript, который делает деятельность периодически. Когда пользователь не смотрит на сайт (то есть окно или вкладка не имеют фокуса), было бы неплохо не запускаться.

Есть ли способ сделать это с помощью JavaScript?

Мой ориентир: чат Gmail воспроизводит звук, если окно, которое вы используете, не активно.

document.body.onblur = function (e) {console.log ("lama");} работал для несфокусированных элементов. WhyMe
80% ответов нижеare not answers to this question, Вопрос спрашивает оnot currently active но тонны ответа ниже оnot visible который не является ответом на этот вопрос. Возможно, они должны быть помечены как "не ответ" gman
Для тех, кто не удовлетворен ответами ниже, проверьтеrequestAnimationFrame API, или используйте современную функцию, что частотаsetTimeout/setInterval уменьшается, когда окно не видно (например, 1 секунда в Chrome). Rob W
Увидетьthis answer для кросс-браузерного решения, использующего API видимости страницы W3C, возвращаясь кblur/focus в браузерах, которые его не поддерживают. Mathias Bynens

Ваш Ответ

18   ответов
7

но понял, что он не обнаруживает события alt-tab в Chrome. Это потому, что он использует первый доступный источник событий, и в этом случае это API видимости страницы, который в Chrome, похоже, не отслеживает alt-tabbing.

Я решил немного изменить сценарий, чтобы отслеживатьall возможные события для изменения фокуса страницы. Вот функция, которую вы можете добавить:

function onVisibilityChange(callback) {
    var visible = true;

    if (!callback) {
        throw new Error('no callback given');
    }

    function focused() {
        if (!visible) {
            callback(visible = true);
        }
    }

    function unfocused() {
        if (visible) {
            callback(visible = false);
        }
    }

    // Standards:
    if ('hidden' in document) {
        document.addEventListener('visibilitychange',
            function() {(document.hidden ? unfocused : focused)()});
    } else if ('mozHidden' in document) {
        document.addEventListener('mozvisibilitychange',
            function() {(document.mozHidden ? unfocused : focused)()});
    } else if ('webkitHidden' in document) {
        document.addEventListener('webkitvisibilitychange',
            function() {(document.webkitHidden ? unfocused : focused)()});
    } else if ('msHidden' in document) {
        document.addEventListener('msvisibilitychange',
            function() {(document.msHidden ? unfocused : focused)()});
    } else if ('onfocusin' in document) {
        // IE 9 and lower:
        document.onfocusin = focused;
        document.onfocusout = unfocused;
    } else {
        // All others:
        window.onpageshow = window.onfocus = focused;
        window.onpagehide = window.onblur = unfocused;
    }
};

Используйте это так:

onVisibilityChange(function(visible) {
    console.log('the page is now', visible ? 'focused' : 'unfocused');
});
Chrome, например, имеет какdocument.hidden а такжеdocument.webkitHidden, Безelse вif строительство мы бы получили 2 колбэка, верно?
люблю этот ответ, отполированный и готовый к использованию (и обрабатывает alt-tab) именно то, что мне нужно
@ChristiaanWesterbeek Это хорошая мысль, я об этом не подумал! Если вы можете редактировать этот пост, продолжайте, и я приму :)
4
var visibilityChange = (function (window) {
    var inView = false;
    return function (fn) {
        window.onfocus = window.onblur = window.onpageshow = window.onpagehide = function (e) {
            if ({focus:1, pageshow:1}[e.type]) {
                if (inView) return;
                fn("visible");
                inView = true;
            } else if (inView) {
                fn("hidden");
                inView = false;
            }
        };
    };
}(this));

visibilityChange(function (state) {
    console.log(state);
});

http://jsfiddle.net/ARTsinn/JTxQY/

1

Visibility.js который предоставляет информацию о трех состояниях страницы

visible    ... page is visible
hidden     ... page is not visible
prerender  ... page is being prerendered by the browser

а также удобные обёртки для setInterval

/* Perform action every second if visible */
Visibility.every(1000, function () {
    action();
});

/* Perform action every second if visible, every 60 sec if not visible */
Visibility.every(1000, 60*1000, function () {
    action();
});

Также доступен запасной вариант для старых браузеров (IE & lt; 10; iOS & lt; 7)

0

Если вы хотите действоватьon всеbrowser blur: As I commented, if browser loose focus none of the suggested events fire. My idea is to count up in a loop and reset the counter if an event fire. If the counter reach a limit I do a location.href to an other page. This also fire if you work on dev-tools.

var iput=document.getElementById("hiddenInput");
   ,count=1
   ;
function check(){
         count++;
         if(count%2===0){
           iput.focus();
         }
         else{
           iput.blur();
         }
         iput.value=count;  
         if(count>3){
           location.href="http://Nirwana.com";
         }              
         setTimeout(function(){check()},1000);
}   
iput.onblur=function(){count=1}
iput.onfocus=function(){count=1}
check();

Это проект, успешно протестированный на FF.

3

onpageshow: Script to be run when the window becomes visible onpagehide: Script to be run when the window is hidden

Увидеть:

https://developer.mozilla.org/en-US/docs/Web/Events/pageshow https://developer.mozilla.org/en-US/docs/Web/Events/pagehide
Я думаю, что это связано с BFCache: когда пользователь нажимает кнопку «Назад» или «Вперед» - это не связано со страницей вверху рабочего стола компьютера.
3

(function () {

    var requiredResolution = 10; // ms
    var checkInterval = 1000; // ms
    var tolerance = 20; // percent


    var counter = 0;
    var expected = checkInterval / requiredResolution;
    //console.log('expected:', expected);

    window.setInterval(function () {
        counter++;
    }, requiredResolution);

    window.setInterval(function () {
        var deviation = 100 * Math.abs(1 - counter / expected);
        // console.log('is:', counter, '(off by', deviation , '%)');
        if (deviation > tolerance) {
            console.warn('Timer resolution not sufficient!');
        }
        counter = 0;
    }, checkInterval);

})();
625

recommendation статус благодаря W3C. & # x2002;API видимости страницы (наMDN) теперь позволяет нам более точно определять, когда страница скрыта для пользователя.

Текущая поддержка браузера:

Chrome 13+ Internet Explorer 10+ Firefox 10+ Opera 12.10+ [read notes]

Следующий код использует API, возвращаясь к менее надежному методу размытия / фокусировки в несовместимых браузерах.

(function() {
  var hidden = "hidden";

  // Standards:
  if (hidden in document)
    document.addEventListener("visibilitychange", onchange);
  else if ((hidden = "mozHidden") in document)
    document.addEventListener("mozvisibilitychange", onchange);
  else if ((hidden = "webkitHidden") in document)
    document.addEventListener("webkitvisibilitychange", onchange);
  else if ((hidden = "msHidden") in document)
    document.addEventListener("msvisibilitychange", onchange);
  // IE 9 and lower:
  else if ("onfocusin" in document)
    document.onfocusin = document.onfocusout = onchange;
  // All others:
  else
    window.onpageshow = window.onpagehide
    = window.onfocus = window.onblur = onchange;

  function onchange (evt) {
    var v = "visible", h = "hidden",
        evtMap = {
          focus:v, focusin:v, pageshow:v, blur:h, focusout:h, pagehide:h
        };

    evt = evt || window.event;
    if (evt.type in evtMap)
      document.body.className = evtMap[evt.type];
    else
      document.body.className = this[hidden] ? "hidden" : "visible";
  }

  // set the initial state (but only if browser supports the Page Visibility API)
  if( document[hidden] !== undefined )
    onchange({type: document[hidden] ? "blur" : "focus"});
})();

onfocusin а такжеonfocusout являютсятребуется для IE 9 и нижев то время как все остальные используютonfocus а такжеonblurкроме iOS, которая используетonpageshow а такжеonpagehide.

Вы не декларируетеhidden дважды?
@AndyE Я попробовал это решение на хроме. Он работает, если я меняю вкладки, но не меняет окна (ALT + вкладка). Должно ли это? Вот скрипка -jsfiddle.net/8a9N6/17
@ AndyE Ваше решение работает только в том случае, если пользователь меняет вкладки или сворачивает / разворачивает окно. Однако событие onchange не запускается, если пользователь оставляет активную вкладку, а максимизирует над ней другую программу с панели задач. Есть ли решение для этого сценария? Спасибо!
@Heliodor: я бы хотел пока сохранить минимальный код в ответе. Оно никогда не предназначалось для комплексного решения «вырезать и вставить», так как разработчики могут не захотеть устанавливать класс в теле и предпринимать совершенно иные действия (такие как остановка и запуск таймера).
@JulienKronegg: вот почему в моем ответе конкретно упоминается API видимости страницы, который вошел в рабочее состояние черновика после того, как я первоначально написал свой ответ. Методы фокусировки / размытия предоставляют ограниченную функциональность для старых браузеров. Привязка к другим событиям, как в вашем ответе, не охватывает намного больше, чем это, и больше подвержена риску поведенческих различий (например, IE не запускает мышку, когда окно появляется под курсором). Я хотел бы предложить более подходящее действие - отобразить сообщение или значок, указывающий пользователю, что обновления могут происходить реже из-за неактивности страницы.
44

позволяющих определить, видит ли пользователь страницу HTML, однако ни один из них не работает идеально:

The W3C Page Visibility API is supposed to do this (supported since: Firefox 10, MSIE 10, Chrome 13). However, this API only raises events when the browser tab is fully overriden (e.g. when the user changes from one tab to another one). The API does not raise events when the visibility cannot be determined with 100% accuracy (e.g. Alt+Tab to switch to another application).

Using focus/blur based methods gives you a lot of false positive. For example, if the user displays a smaller window on top of the browser window, the browser window will loose the focus (onblur raised) but the user is still able to see it (so it still need to be refreshed). See also http://javascript.info/tutorial/focus

Relying on user activity (mouse move, clicks, key typed) gives you a lot of false positive too. Think about the same case as above, or a user watching a video.

Чтобы улучшить несовершенное поведение, описанное выше, я использую комбинацию из 3 методов: W3C Visibility API, затем методы фокусировки / размытия и пользовательской активности, чтобы уменьшить вероятность ложных срабатываний. Это позволяет управлять следующими событиями:

Changing browser tab to another one (100% accuracy, thanks to the W3C Page Visibility API) Page potentially hidden by another window, e.g. due to Alt+Tab (probabilistic = not 100% accurate) User attention potentially not focused on the HTML page (probabilistic = not 100% accurate)

Вот как это работает: когда документ теряет фокус, пользовательская активность (например, перемещение мыши) в документе отслеживается, чтобы определить, является ли окно видимым или нет. Вероятность видимости страницы обратно пропорциональна времени последнего пользовательского действия на странице: если пользователь долгое время не выполняет никаких действий с документом, скорее всего, страница не видна. Приведенный ниже код имитирует API видимости страницы W3C: он ведет себя так же, но имеет небольшой процент ложных срабатываний. Он имеет преимущество быть мультибраузером (протестирован на Firefox 5, Firefox 10, MSIE 9, MSIE 7, Safari 5, Chrome 9).

    <div id="x"></div>

    <script>
    /**
    Registers the handler to the event for the given object.
    @param obj the object which will raise the event
    @param evType the event type: click, k,eypress, mouseover, ...
    @param fn the event handler function
    @param isCapturing set the event mode (true = capturing event, false = bubbling event)
    @return true if the event handler has been attached correctly
    */
    function addEvent(obj, evType, fn, isCapturing){
      if (isCapturing==null) isCapturing=false; 
      if (obj.addEventListener){
        // Firefox
        obj.addEventListener(evType, fn, isCapturing);
        return true;
      } else if (obj.attachEvent){
        // MSIE
        var r = obj.attachEvent('on'+evType, fn);
        return r;
      } else {
        return false;
      }
    }

    // register to the potential page visibility change
    addEvent(document, "potentialvisilitychange", function(event) {
      document.getElementById("x").innerHTML+="potentialVisilityChange: potentialHidden="+document.potentialHidden+", document.potentiallyHiddenSince="+document.potentiallyHiddenSince+" s<br>";
    });

    // register to the W3C Page Visibility API
    var hidden=null;
    var visibilityChange=null;
    if (typeof document.mozHidden !== "undefined") {
      hidden="mozHidden";
      visibilityChange="mozvisibilitychange";
    } else if (typeof document.msHidden !== "undefined") {
      hidden="msHidden";
      visibilityChange="msvisibilitychange";
    } else if (typeof document.webkitHidden!=="undefined") {
      hidden="webkitHidden";
      visibilityChange="webkitvisibilitychange";
    } else if (typeof document.hidden !=="hidden") {
      hidden="hidden";
      visibilityChange="visibilitychange";
    }
    if (hidden!=null && visibilityChange!=null) {
      addEvent(document, visibilityChange, function(event) {
        document.getElementById("x").innerHTML+=visibilityChange+": "+hidden+"="+document[hidden]+"<br>";
      });
    }


    var potentialPageVisibility = {
      pageVisibilityChangeThreshold:3*3600, // in seconds
      init:function() {
        function setAsNotHidden() {
          var dispatchEventRequired=document.potentialHidden;
          document.potentialHidden=false;
          document.potentiallyHiddenSince=0;
          if (dispatchEventRequired) dispatchPageVisibilityChangeEvent();
        }

        function initPotentiallyHiddenDetection() {
          if (!hasFocusLocal) {
            // the window does not has the focus => check for  user activity in the window
            lastActionDate=new Date();
            if (timeoutHandler!=null) {
              clearTimeout(timeoutHandler);
            }
            timeoutHandler = setTimeout(checkPageVisibility, potentialPageVisibility.pageVisibilityChangeThreshold*1000+100); // +100 ms to avoid rounding issues under Firefox
          }
        }

        function dispatchPageVisibilityChangeEvent() {
          unifiedVisilityChangeEventDispatchAllowed=false;
          var evt = document.createEvent("Event");
          evt.initEvent("potentialvisilitychange", true, true);
          document.dispatchEvent(evt);
        }

        function checkPageVisibility() {
          var potentialHiddenDuration=(hasFocusLocal || lastActionDate==null?0:Math.floor((new Date().getTime()-lastActionDate.getTime())/1000));
                                        document.potentiallyHiddenSince=potentialHiddenDuration;
          if (potentialHiddenDuration>=potentialPageVisibility.pageVisibilityChangeThreshold && !document.potentialHidden) {
            // page visibility change threshold raiched => raise the even
            document.potentialHidden=true;
            dispatchPageVisibilityChangeEvent();
          }
        }

        var lastActionDate=null;
        var hasFocusLocal=true;
        var hasMouseOver=true;
        document.potentialHidden=false;
        document.potentiallyHiddenSince=0;
        var timeoutHandler = null;

        addEvent(document, "pageshow", function(event) {
          document.getElementById("x").innerHTML+="pageshow/doc:<br>";
        });
        addEvent(document, "pagehide", function(event) {
          document.getElementById("x").innerHTML+="pagehide/doc:<br>";
        });
        addEvent(window, "pageshow", function(event) {
          document.getElementById("x").innerHTML+="pageshow/win:<br>"; // raised when the page first shows
        });
        addEvent(window, "pagehide", function(event) {
          document.getElementById("x").innerHTML+="pagehide/win:<br>"; // not raised
        });
        addEvent(document, "mousemove", function(event) {
          lastActionDate=new Date();
        });
        addEvent(document, "mouseover", function(event) {
          hasMouseOver=true;
          setAsNotHidden();
        });
        addEvent(document, "mouseout", function(event) {
          hasMouseOver=false;
          initPotentiallyHiddenDetection();
        });
        addEvent(window, "blur", function(event) {
          hasFocusLocal=false;
          initPotentiallyHiddenDetection();
        });
        addEvent(window, "focus", function(event) {
          hasFocusLocal=true;
          setAsNotHidden();
        });
        setAsNotHidden();
      }
    }

    potentialPageVisibility.pageVisibilityChangeThreshold=4; // 4 seconds for testing
    potentialPageVisibility.init();
    </script>

Поскольку в настоящее время не существует работающего кросс-браузерного решения без ложных срабатываний, вам следует подумать дважды об отключении периодической активности на вашем веб-сайте.

@ Джейкоб Я рад, что тебе понравилось мое решение. Не стесняйтесь продвигать его в проект GitHub самостоятельно. Я даю код с лицензией Creative Commons BYcreativecommons.org/licenses/by/4.0
@JulienKronegg Я думаю, что это пока лучшее решение. Однако приведенный выше код крайне нуждается в рефакторинге и абстракциях. Почему бы вам не загрузить его на GitHub и позволить сообществу провести его рефакторинг?
Он не работает с alt + tab
Не использовал бы оператор строгого сравнения для строки "undefined" вместо неопределенного ключевого слова вызвать ложные срабатывания в приведенном выше коде?
@kiran: На самом деле это работает с Alt + Tab. Вы не можете определить, является ли страница скрытой, когда вы нажимаете Alt + Tab, потому что вы можете переключиться на меньшее окно, чтобы вы не могли гарантировать, что ваша страница полностью скрыта. Вот почему я использую понятие «потенциально скрытый». (в этом примере порог установлен на 4 секунды, поэтому вам нужно переключиться в другое окно, используя Alt + Tab, по крайней мере, на 4 секунды). Однако ваш комментарий показывает, что ответ был не очень ясен, поэтому я перефразировал его.
0

Вопрос не ясно написан. & quot; Когда пользователь не смотрит на сайт (то есть окно или вкладка не имеют фокуса) ... & quot;

Я могу посмотреть на сайт, когда на нем нет фокуса. Большинство настольных систем могут показывать окна параллельно :)

Вот почему API видимости страницы, вероятно, является правильным ответом, поскольку он предотвращает обновление сайта, когда «пользователь не может видеть обновления». которая может сильно отличаться от "вкладка не имеет фокуса".

1

if(!document.hasFocus()) {
    // do stuff
}
11

и когда я получаю сообщение от другого пользователя, я использую:

if(new_message){
    if(!document.hasFocus()){
        audio.play();
        document.title="Have new messages";
    }
    else{
        audio.stop();
        document.title="Application Name";
    } 
}
Эффективно и в отличие от других решений дает правильную обратную связь при переключении на другую вкладку или окно браузера и даже другое приложение.
Самое чистое решение с поддержкой обратно в IE6
document.hasFocus() это самый чистый способ сделать это. Все остальные способы, использующие API видимости или события, основанные на событиях или ищущие различные уровни пользовательской активности / отсутствия активности, становятся слишком сложными и полными крайних случаев и дыр. поместите его в простой интервал и создайте пользовательское событие, когда результаты изменятся. Пример:jsfiddle.net/59utucz6/1
7

не существует решения с учетом следующих требований.

The page includes iframes that you have no control over You want to track visibility state change regardless of the change being triggered by a TAB change (ctrl+tab) or a window change (alt+tab)

Это происходит потому, что:

The page Visibility API can reliably tell you of a tab change (even with iframes), but it can't tell you when the user changes windows. Listening to window blur/focus events can detect alt+tabs and ctrl+tabs, as long as the iframe doesn't have focus.

Учитывая эти ограничения, можно реализовать решение, которое объединяет - API видимости страницы - размытие окна / фокус - document.activeElement

Это способно:

1) ctrl+tab when parent page has focus: YES 2) ctrl+tab when iframe has focus: YES 3) alt+tab when parent page has focus: YES 4) alt+tab when iframe has focus: NO <-- bummer

Когда фрейм имеет фокус, ваши события размытия / фокуса вообще не запускаются, и API видимости страницы не срабатывает на alt + tab.

Я опирался на решение @ AndyE и реализовал это (почти хорошее) решение здесь: https://dl.dropboxusercontent.com/u/2683925/estante-components/visibility_test1.html (извините, у меня были некоторые проблемы с JSFiddle).

Это также доступно на Github:https://github.com/qmagico/estante-components

Это работает на хром / хром. Он работает на firefox, за исключением того, что он не загружает содержимое iframe (есть идеи, почему?)

В любом случае, чтобы решить последнюю проблему (4), единственный способ сделать это - прослушать события размытия / фокуса в iframe. Если у вас есть некоторый контроль над фреймами, вы можете использовать для этого API postMessage.

https://dl.dropboxusercontent.com/u/2683925/estante-components/visibility_test2.html

Я до сих пор не проверил это с достаточным количеством браузеров. Если вы можете найти больше информации о том, где это не работает, пожалуйста, дайте мне знать в комментариях ниже.

Все эти ссылки 404s :(
Похоже, IPAD нужно совершенно другое решение -stackoverflow.com/questions/4940657/…
НЕ работает вообще в iPad. :-(
В моих тестах он также работал на IE9, IE10 и Chrome на Android.
124

потому что тогда все, что вам нужно сделать, это:

$(window).blur(function(){
  //your code here
});
$(window).focus(function(){
  //your code
});

Или, по крайней мере, это сработало для меня.

для меня этот звонок дважды в iframe
Это на самом деле работает?
Это больше не работает для текущих версий современных браузеров, см. Утвержденный ответ (Page Visibility API)
Работает в хроме 51.0.2704.106 м
Очень хорошо, я использовал это для управления фоновым процессом, и он работал хорошо.
2

setInterval() проверить положение мыши и сравнить с последней проверкой. Если мышь не двигалась в течение заданного промежутка времени, пользователь, вероятно, бездействует.

This has the added advantage of telling if the user is idle, instead of just checking if the window is not active.

Как отмечали многие люди, это не всегда хороший способ проверить, простаивает ли окно пользователя или браузера, так как пользователь может даже не использовать мышь или смотреть видео, или что-то подобное. Я просто предлагаю один из возможных способов проверки на безделье.

связанные: Going Commando -codinghorror.com/blog/archives/000825.html
Если только у пользователя нет мыши.
Вы можете использовать onkeypress или другие подобные события для сброса таймера и решения проблемы, не связанной с мышью. Конечно, пользователям, активно просматривающим страницу для просмотра видео, изучения изображения и т. Д., Все равно не будет работать.
Это также не воспроизводит игральные кости, если пользователь смотрит видео
@Annan: Этоcodinghorror.com/blog/2007/03/… сейчас.
23

https://github.com/serkanyersen/ifvisible.js

Пример:

// If page is visible right now
if( ifvisible.now() ){
  // Display pop-up
  openPopUp();
}

Я протестировал версию 1.0.1 на всех моих браузерах и могу подтвердить, что она работает с:

IE9, IE10 FF 26.0 Chrome 34.0

... и, вероятно, все более новые версии.

Не полностью работает с:

IE8 - always indicate that tab/window is currently active (.now() always returns true for me)
Принятый ответ вызвал проблемы в IE9. Эта библиотека прекрасно работает.
Удивительная библиотека! Спасибо! играл главную роль.
2

Это сделает задачу, например обновлять страницу каждые 30 секунд, но только если страница видна и сфокусирована.

Если видимость не может быть обнаружена, тогда будет использоваться только фокус.

Если пользователь фокусирует страницу, то она сразу обновится

Страница не будет обновляться снова в течение 30 секунд после любого вызова AJAX

var windowFocused = true;
var timeOut2 = null;

$(function(){
  $.ajaxSetup ({
    cache: false
  });
  $("#content").ajaxComplete(function(event,request, settings){
       set_refresh_page(); // ajax call has just been made, so page doesn't need updating again for 30 seconds
   });
  // check visibility and focus of window, so as not to keep updating unnecessarily
  (function() {
      var hidden, change, vis = {
              hidden: "visibilitychange",
              mozHidden: "mozvisibilitychange",
              webkitHidden: "webkitvisibilitychange",
              msHidden: "msvisibilitychange",
              oHidden: "ovisibilitychange" /* not currently supported */
          };
      for (hidden in vis) {
          if (vis.hasOwnProperty(hidden) && hidden in document) {
              change = vis[hidden];
              break;
          }
      }
      document.body.className="visible";
      if (change){     // this will check the tab visibility instead of window focus
          document.addEventListener(change, onchange,false);
      }

      if(navigator.appName == "Microsoft Internet Explorer")
         window.onfocus = document.onfocusin = document.onfocusout = onchangeFocus
      else
         window.onfocus = window.onblur = onchangeFocus;

      function onchangeFocus(evt){
        evt = evt || window.event;
        if (evt.type == "focus" || evt.type == "focusin"){
          windowFocused=true; 
        }
        else if (evt.type == "blur" || evt.type == "focusout"){
          windowFocused=false;
        }
        if (evt.type == "focus"){
          update_page();  // only update using window.onfocus, because document.onfocusin can trigger on every click
        }

      }

      function onchange () {
        document.body.className = this[hidden] ? "hidden" : "visible";
        update_page();
      }

      function update_page(){
        if(windowFocused&&(document.body.className=="visible")){
          set_refresh_page(1000);
        }
      }


  })();
  set_refresh_page();
})

function get_date_time_string(){
  var d = new Date();
  var dT = [];
  dT.push(d.getDate());
  dT.push(d.getMonth())
  dT.push(d.getFullYear());
  dT.push(d.getHours());
  dT.push(d.getMinutes());
  dT.push(d.getSeconds());
  dT.push(d.getMilliseconds());
  return dT.join('_');
}

function do_refresh_page(){

// do tasks here

// e.g. some ajax call to update part of the page.

// (date time parameter will probably force the server not to cache)

//      $.ajax({
//        type: "POST",
//        url: "someUrl.php",
//        data: "t=" + get_date_time_string()+"&task=update",
//        success: function(html){
//          $('#content').html(html);
//        }
//      });

}

function set_refresh_page(interval){
  interval = typeof interval !== 'undefined' ? interval : 30000; // default time = 30 seconds
  if(timeOut2 != null) clearTimeout(timeOut2);
  timeOut2 = setTimeout(function(){
    if((document.body.className=="visible")&&windowFocused){
      do_refresh_page();
    }
    set_refresh_page();
  }, interval);
}
Использование методов фокусировки / размытия не работает (это дает много ложных срабатываний), см. Stackoverflow.com/a/9502074/698168
1

которая позволит вашему контроллеру реагировать на изменение видимости:

myApp.directive('reactOnWindowFocus', function($parse) {
    return {
        restrict: "A",
        link: function(scope, element, attrs) {
            var hidden = "hidden";
            var currentlyVisible = true;
            var functionOrExpression = $parse(attrs.reactOnWindowFocus);

          // Standards:
          if (hidden in document)
            document.addEventListener("visibilitychange", onchange);
          else if ((hidden = "mozHidden") in document)
            document.addEventListener("mozvisibilitychange", onchange);
          else if ((hidden = "webkitHidden") in document)
            document.addEventListener("webkitvisibilitychange", onchange);
          else if ((hidden = "msHidden") in document)
            document.addEventListener("msvisibilitychange", onchange);
          else if ("onfocusin" in document) {
                // IE 9 and lower:
            document.onfocusin = onshow;
                document.onfocusout = onhide;
          } else {
                // All others:
            window.onpageshow = window.onfocus = onshow;
                window.onpagehide = window.onblur = onhide;
            }

          function onchange (evt) {
                //occurs both on leaving and on returning
                currentlyVisible = !currentlyVisible;
                doSomethingIfAppropriate();
          }

            function onshow(evt) {
                //for older browsers
                currentlyVisible = true;
                doSomethingIfAppropriate();
            }

            function onhide(evt) {
                //for older browsers
                currentlyVisible = false;
                doSomethingIfAppropriate();
            }

            function doSomethingIfAppropriate() {
                if (currentlyVisible) {
                    //trigger angular digest cycle in this scope
                    scope.$apply(function() {
                        functionOrExpression(scope);
                    });
                }
            }
        }
    };

});

Вы можете использовать это как этот пример:<div react-on-window-focus="refresh()">, гдеrefresh() является областью действия в области видимости любого Контроллера.

Благодарю. Спасло меня от необходимости писать это.
11

Using : API видимости страницы

visibilitychange' , function() {
    if (document.hidden) {
        console.log('bye');
    } else {
        console.log('well back');
    }
}, false );

Can i use ? http://caniuse.com/#feat=pagevisibility

Я думаю, что OP не говорит о функции ide
Я тоже не говорю об идеях. Я говорю о alt-tabbing / cmd-tabbing к другому приложению. Внезапно страница не активна. API видимости страницы не помогает мне узнать, не активна ли страница, а только помогает узнать, не видна ли она.
Вопрос не в видимости страницы. Это о неактивном / активном

Похожие вопросы