Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/79.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用ALT+;切换程序/窗口时不会触发visibilitychange事件;选项卡或在任务栏中单击_Javascript_Html_Events_Event Handling_Dom Events - Fatal编程技术网

Javascript 使用ALT+;切换程序/窗口时不会触发visibilitychange事件;选项卡或在任务栏中单击

Javascript 使用ALT+;切换程序/窗口时不会触发visibilitychange事件;选项卡或在任务栏中单击,javascript,html,events,event-handling,dom-events,Javascript,Html,Events,Event Handling,Dom Events,问题在于事件“visibilitychange”的行为 它被触发: -当我切换到浏览器窗口内的其他选项卡时 单击浏览器窗口的最小化/还原按钮时 (这没关系) 它未被触发: -当我使用ALT+TAB切换到其他窗口/程序时 当我切换到其他窗口/程序时,单击任务栏 (这应该会触发,因为与最小化时一样,窗口的可见性可能会更改) W3页面可见性API文档: 规范表中没有关于ALT+TAB/程序切换的“页面可见性”定义。我猜这与操作系统和浏览器之间的关系有关 测试 浏览器: Chrome 40

问题在于事件“visibilitychange”的行为

它被触发: -当我切换到浏览器窗口内的其他选项卡时

  • 单击浏览器窗口的最小化/还原按钮时
(这没关系)

它未被触发: -当我使用ALT+TAB切换到其他窗口/程序时

  • 当我切换到其他窗口/程序时,单击任务栏
(这应该会触发,因为与最小化时一样,窗口的可见性可能会更改)


W3页面可见性API文档

规范表中没有关于ALT+TAB/程序切换的“页面可见性”定义。我猜这与操作系统和浏览器之间的关系有关


测试
  • 浏览器: Chrome 40.0.2214.115 m/Firefox 36.0.1/Internet Explorer 11.0.9600.17107
  • 操作系统:Windows 8.1

是否有解决此问题的方法?实现相当简单,我使用jQuery侦听“visibilitychange”事件,然后在其回调中检查“document.visibilityState”的值,但问题是该事件没有按预期触发

$(document).on('visibilitychange', function() {

    if(document.visibilityState == 'hidden') {
        // page is hidden
    } else {
        // page is visible
    }
});
这也可以在没有jQuery的情况下完成,但仍然缺少ALT+选项卡和任务栏开关隐藏/显示预期行为:

if(document.addEventListener){
    document.addEventListener("visibilitychange", function() {
        // check for page visibility
    });
}
我还尝试了ifvisible.js模块(),但行为是相同的

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

ifvisible.on('focus', function() {
    // page is visible
});
我还没有在其他浏览器上测试过,因为如果我不能在Windows上的Chrome上运行,我真的不在乎其他浏览器

有什么帮助或建议吗


更新 我尝试使用不同的供应商前缀作为事件名称(visibilitychange、webkitvisibilitychange、mozvisibilitychange、msvisibilitychange),但当我切换到任务栏或ALT+选项卡中的其他程序时,或者即使我用windows键打开windows中的“开始”菜单,事件仍不会触发,它覆盖了整个屏幕

我可以在Chrome、Firefox和Internet Explorer中重现完全相同的问题

更新#2 我为这个问题写了一篇综述文章,并用纯Javascript解决了遇到的问题

更新#3 编辑以包含源博客文章的副本。(请参阅接受的答案)

我为本期撰写的一篇综述文章,以及用纯JavaScript解决遇到的问题的一种变通方法

编辑以包含源博客帖子的副本:


在我们开发的任何类型的javascript应用程序中,都可能存在 功能或应用程序中根据 当前用户可见性状态,这可能是暂停播放视频 当用户按ALT+键切换到另一个窗口时,跟踪有关如何操作的统计信息 用户与我们的应用程序交互,他多久切换一次 另一张账单,他需要多长时间才能回来,还有很多 可以从这种API中受益的性能改进

页面可见性API为我们提供了两个顶级属性: document.hidden(布尔值)和document.visibilityState(可以是 这些字符串中的任意一个:“隐藏”、“可见”、“预渲染”、“卸载”)。 如果没有我们可以聆听的活动,这是不够好的 不过,这就是为什么API还提供了有用的可视性更改 事件

所以,这里有一个基本的例子,说明我们如何对可见性采取行动 更改:

我们还可以检查document.visibilityState值

处理供应商问题John Smibert的George Berkeley

某些浏览器上的某些实现仍然需要 属性,甚至事件名称都有供应商前缀,这意味着我们 可能需要侦听msvisibilitychange事件或检查 document.webkitHidden或document.mozHidden属性。整齐 为此,我们应该检查是否设置了任何供应商前缀属性,以及 一旦我们知道当前浏览器中使用的是哪一个(仅当 需要前缀),我们可以命名事件和属性 对

下面是一个关于如何处理这些前缀的示例方法:

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('visible');
  }
}

document.addEventListener(getVisibilityEvent(browserPrefix), handleVisibilityChange, false);
var-browserPrefixes=['moz','ms','o','webkit'];
//获取正确的属性名称
函数getHiddenPropertyName(前缀){
返回(前缀?前缀+‘隐藏’:‘隐藏’);
}
//获取正确的事件名称
函数getVisibilityEvent(前缀){
返回(前缀?前缀:“”)+“visibilitychange”;
}
//获取当前浏览器供应商前缀
函数getBrowserPrefix(){
对于(变量i=0;i
其他问题围绕“页面可见性”存在一个具有挑战性的问题 定义:如何确定应用程序是否可见,如果 另一个窗口的窗口焦点丢失,但实际窗口焦点丢失 屏幕上的可见性?不同类型的可见性如何 丢失,如ALT+TAB、WIN/MAC键(开始菜单/破折号)、任务栏/停靠 操作、WIN+L(锁定屏幕)、窗口最小化、窗口关闭、选项卡 切换。移动设备上的行为如何

我们可能会以很多方式失去或获得可见性,还有很多 浏览器和操作系统之间可能的交互,因此 不要认为有一个适当的和完整的“可见页面”的定义 W3
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('visible');
  }
}

document.addEventListener(getVisibilityEvent(browserPrefix), handleVisibilityChange, false);
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);
 document.addEventListener('visibilitychange', function () {
  // code goes here
}, false)
 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);