ventanas ventana una teclas tab que puedo para funciona entre con como combinaciĆ³n cambiar activar abiertas javascript html5 events javascript-events event-handling

javascript - una - El evento de visibilidad de cambio no se activa al cambiar de programa/ventana con ALT+TAB o al hacer clic en la barra de tareas



no puedo cambiar de ventana con alt tab (4)

Básicamente, el problema está en el comportamiento del evento "visiblechange".

Se activa: - Cuando cambio a una pestaña diferente dentro de la ventana del navegador.

  • Cuando hago clic en los botones minimizar / restaurar para la ventana del navegador.

(esto esta bien)

No se activa: - Cuando cambio a una ventana / programa diferente usando ALT + TAB.

  • Cuando cambio a una ventana / programa diferente, haga clic en la barra de tareas.

(esto DEBE activarse, ya que, al igual que al minimizar, la visibilidad de la ventana puede cambiar)

Documentación de la API de visibilidad de la página W3 : http://www.w3.org/TR/page-visibility/

No hay una definición de "visibilidad de la página" con respecto a ALT + TAB / cambio de programa en la hoja de especificaciones. Supongo que tiene algo que hacer entre el sistema operativo y el navegador.

Probado en

  • Navegadores : Chrome 40.0.2214.115 m / Firefox 36.0.1 / Internet Explorer 11.0.9600.17107
  • SO : Windows 8.1

¿Hay una solución para solucionar este comportamiento? La implementación es bastante simple, escucho el evento "visiblechange" con jQuery y luego, en su devolución de llamada, verifico el valor de "document.visibilityState", pero el problema es que el evento no se dispara cuando se espera.

$(document).on(''visibilitychange'', function() { if(document.visibilityState == ''hidden'') { // page is hidden } else { // page is visible } });

Esto también se puede hacer sin jQuery, pero aún falta el comportamiento esperado / ALT + TAB y el interruptor de la barra de tareas:

if(document.addEventListener){ document.addEventListener("visibilitychange", function() { // check for page visibility }); }

También probé el módulo ifvisible.js ( https://github.com/serkanyersen/ifvisible.js ) pero el comportamiento es el mismo.

ifvisible.on(''blur'', function() { // page is hidden }); ifvisible.on(''focus'', function() { // page is visible });

No lo he probado en otros navegadores porque, si no puedo hacerlo funcionar en Chrome en Windows, todavía no me importan los otros navegadores.

Cualquier ayuda o sugerencia es agradecida de antemano.

ACTUALIZAR

Intenté usar diferentes prefijos de proveedores para el nombre del evento (visibilidadcambiar, webkitvisibilitychange, mozvisibilitychange, msvisibilitychange) pero aún así el evento no se activa cuando cambio a un programa diferente en la barra de tareas o ALT + TAB, o incluso si abro el menú de inicio Cosa en Windows con la tecla Windows, que cubre toda la pantalla.

Puedo reproducir exactamente el mismo problema en Chrome, Firefox e Internet Explorer.

ACTUALIZACIÓN # 2

Here''s una publicación de resumen que escribí para este problema y una solución en javascript puro para resolver los problemas encontrados.

ACTUALIZACIÓN # 3

Editado para incluir una copia de la publicación del blog. (ver respuesta aceptada)


Hay una solución muy simple para esto que he encontrado.

Solo debe pasar falso a useCapture al adjuntar un detector de eventos al documento. ¡Funciona de maravilla!

document.addEventListener(''visibilitychange'', function () { // code goes here }, false)


Podemos hacer lo siguiente al cambiar entre pestañas y cambiar entre aplicaciones.

var pageVisible = true; function handleVisibilityChange() { if (document.hidden) { pageVisible = false; } else { pageVisible = true; } console.log("handleVisibilityChange") console.log("pageVisible", pageVisible) // some function call } document.addEventListener("visibilitychange", handleVisibilityChange, false); window.addEventListener(''focus'', function() { pageVisible = true; // some function call }, false); window.addEventListener(''blur'', function() { pageVisible = false; // some function call }, false);


Se propone una solución de trabajo que se describe aquí: https://.com/a/9502074/698168 . Utiliza una combinación de la API de visibilidad de página W3C, desenfoque / enfoque y movimientos del mouse. Las páginas HTML ocultas relacionadas con Alt + Tab se identifican de manera probabilística (es decir, no puede determinar si su página está oculta con el 100% de precisión).


Here''s una publicación de resumen que escribí para este problema y una solución en javascript puro para resolver los problemas encontrados.

Editado para incluir una copia de la publicación del blog de origen:

En cualquier tipo de aplicación javascript que desarrollemos puede haber una característica o cualquier cambio en la aplicación que reaccione de acuerdo con el estado actual de visibilidad del usuario, esto podría ser pausar un video en reproducción cuando el usuario ALT + TABs se encuentra en una ventana diferente, estadísticas de seguimiento. acerca de cómo los usuarios interactúan con nuestra aplicación, con qué frecuencia cambia a una pestaña diferente, cuánto tiempo le lleva regresar y muchas mejoras de rendimiento que pueden beneficiarse de este tipo de API.

La API de visibilidad de la página nos proporciona dos atributos de nivel superior: document.hidden (boolean) y document.visibilityState (que podría ser cualquiera de estas cadenas: "oculto", "visible", "prerender", "descargado"). Sin embargo, esto no sería lo suficientemente bueno sin un evento que pudiéramos escuchar, por eso la API también proporciona un evento de visibilidad útil.

Por lo tanto, aquí hay un ejemplo básico sobre cómo podríamos actuar en un cambio de visibilidad:

function handleVisibilityChange() { if(document.hidden) { // the page is hidden } else { // the page is visible } } document.addEventListener("visibilitychange", handleVisibilityChange, false);

También podríamos comprobar el valor de document.visibilityState.

Tratar con los problemas de los proveedores George Berkeley por John Smibert

Algunas de las implementaciones en algunos navegadores todavía necesitan que los atributos o incluso el nombre del evento tengan el prefijo del proveedor, esto significa que es posible que debamos escuchar el evento msvisibilitychange o verificar los atributos document.webkitHidden o document.mozHidden. Para hacerlo, deberíamos verificar si algún atributo con prefijo de proveedor está establecido, y una vez que sepamos cuál es el que se usa en el navegador actual (solo si es necesario un prefijo), podemos nombrar el evento y los atributos correctamente.

Aquí hay un enfoque de ejemplo sobre cómo manejar estos prefijos:

var browserPrefixes = [''moz'', ''ms'', ''o'', ''webkit'']; // get the correct attribute name function getHiddenPropertyName(prefix) { return (prefix ? prefix + ''Hidden'' : ''hidden''); } // get the correct event name function getVisibilityEvent(prefix) { return (prefix ? prefix : '''') + ''visibilitychange''; } // get current browser vendor prefix function getBrowserPrefix() { for (var i = 0; i < browserPrefixes.length; i++) { if(getHiddenPropertyName(browserPrefixes[i]) in document) { // return vendor prefix return browserPrefixes[i]; } } // no vendor prefix needed return null; } // bind and handle events var browserPrefix = getBrowserPrefix(); function handleVisibilityChange() { if(document[getHiddenPropertyName(browserPrefix )]) { // the page is hidden console.log(''hidden } else { // the page is visible console.log(''hidden } } document.addEventListener(getVisibilityEvent(browserPrefix), handleVisibilityChange, false);

Otros problemas Existe un problema desafiante en torno a la definición de "Visibilidad de la página": ¿cómo determinar si la aplicación es visible o no si el foco de la ventana se pierde en otra ventana, pero no la visibilidad real en la pantalla? ¿qué pasa con los diferentes tipos de visibilidad perdidos, como ALT + TAB, tecla WIN / MAC (menú de inicio / guión), acciones de la barra de tareas / acoplamiento, WIN + L (pantalla de bloqueo), minimizar ventana, cerrar ventana, cambiar de pestaña? ¿Qué pasa con el comportamiento en dispositivos móviles?

Hay muchas maneras en las que podemos perder o ganar visibilidad y muchas interacciones posibles entre el navegador y el sistema operativo, por lo tanto, no creo que haya una definición adecuada y completa de "página visible" en la especificación W3C. Esta es la definición que obtenemos para el atributo document.hidden:

ATRIBUTO OCULTO Al obtener, el atributo oculto DEBE retornar verdadero si el Documento contenido por el contexto de navegación de nivel superior (ventana raíz en la ventana gráfica del navegador) [HTML5] no es visible en absoluto. El atributo DEBE devolver falso si el Documento contenido por el contexto de navegación de nivel superior es al menos parcialmente visible en al menos una pantalla.

Si la vista predeterminada del documento es nula, al obtenerlo, el atributo oculto DEBE devolver el valor verdadero.

Para adaptarse a las herramientas de accesibilidad que suelen ser de pantalla completa pero que aún muestran una vista de la página, cuando corresponda, este atributo PUEDE devolver falso cuando el Agente de usuario no está minimizado pero otras aplicaciones lo ocultan por completo.

He encontrado varias incoherencias sobre cuándo se activa realmente el evento, por ejemplo (Chrome 41.0.2272.101 m, en Windows 8.1) el evento no se activa cuando I ALT + TAB en una ventana / programa diferente ni cuando I ALT + TAB de nuevo para volver, pero se dispara si presiona CTRL + TAB y luego CTRL + MAYÚS + TAB para cambiar entre las pestañas del navegador. También se activa cuando hago clic en el botón de minimizar, pero no se activa si la ventana no está maximizada y hago clic en la ventana de mi editor, que se encuentra detrás de la ventana del navegador. Por lo tanto, el comportamiento de esta API y sus diferentes implementaciones aún son poco claros.

Una solución para esto, es compensar aprovechando los eventos de enfoque y desenfoque mejor implementados, y haciendo un enfoque personalizado a todo el problema de "Visibilidad de la página" utilizando un indicador interno para evitar múltiples ejecuciones, esto es lo que he encontrado. :

var browserPrefixes = [''moz'', ''ms'', ''o'', ''webkit''], isVisible = true; // internal flag, defaults to true // get the correct attribute name function getHiddenPropertyName(prefix) { return (prefix ? prefix + ''Hidden'' : ''hidden''); } // get the correct event name function getVisibilityEvent(prefix) { return (prefix ? prefix : '''') + ''visibilitychange''; } // get current browser vendor prefix function getBrowserPrefix() { for (var i = 0; i < browserPrefixes.length; i++) { if(getHiddenPropertyName(browserPrefixes[i]) in document) { // return vendor prefix return browserPrefixes[i]; } } // no vendor prefix needed return null; } // bind and handle events var browserPrefix = getBrowserPrefix(), hiddenPropertyName = getHiddenPropertyName(browserPrefix), visibilityEventName = getVisibilityEvent(browserPrefix); function onVisible() { // prevent double execution if(isVisible) { return; } // change flag value isVisible = true; console.log(''visible} function onHidden() { // prevent double execution if(!isVisible) { return; } // change flag value isVisible = false; console.log(''hidden} function handleVisibilityChange(forcedFlag) { // forcedFlag is a boolean when this event handler is triggered by a // focus or blur eventotherwise it''s an Event object if(typeof forcedFlag === "boolean") { if(forcedFlag) { return onVisible(); } return onHidden(); } if(document[hiddenPropertyName]) { return onHidden(); } return onVisible(); } document.addEventListener(visibilityEventName, handleVisibilityChange, false); // extra event listeners for better behaviour document.addEventListener(''focus'', function() { handleVisibilityChange(true); }, false); document.addEventListener(''blur'', function() { handleVisibilityChange(false); }, false); window.addEventListener(''focus'', function() { handleVisibilityChange(true); }, false); window.addEventListener(''blur'', function() { handleVisibilityChange(false); }, false);

Doy la bienvenida a cualquier comentario sobre esta solución. Algunas otras grandes fuentes de ideas sobre este tema:

Uso de la API de visibilidad de la página Uso del hardware de la PC de manera más eficiente en HTML5: Nuevas API de rendimiento web, Parte 2 Introducción a la API de la visibilidad de la página Conclusión Las tecnologías de la web están evolucionando continuamente, todavía estamos recuperando de un pasado oscuro donde las tablas donde el marcado Rey, donde la semántica no importaba, y no eran estándares en cuanto a cómo un navegador debería mostrar una página.

Es importante que impulsemos estos nuevos estándares hacia adelante, pero a veces nuestros requisitos de desarrollo nos obligan a adaptarnos a este tipo de transiciones, manejando los prefijos de los proveedores, probando en diferentes navegadores y diferentes sistemas operativos o dependemos de herramientas de terceros para identificar correctamente estas diferencias. .

Solo podemos esperar un futuro donde las especificaciones de W3C sean revisadas estrictamente, implementadas estrictamente por los equipos de desarrolladores de navegadores, y tal vez algún día tengamos un estándar común con el que todos podamos trabajar.

En cuanto a la API de Visibilidad de la Página, solo citemos a George Berkeley y digamos que:

"Ser visible" se está percibiendo.