Existe-t-il un moyen fiable, multi-navigateur, de détecter qu'un onglet est actif?.
Le scénario est que nous avons une application qui interroge régulièrement les cours des actions et si la page n’est pas ciblée, nous pouvons arrêter le sondage et épargner le bruit de la circulation pour tout le monde, d’autant plus que les utilisateurs sont fans d’ouvrir plusieurs onglets avec différents portefeuilles.
Est window.onblur
et window.onfocus
une option pour cela?
Oui, window.onfocus
et window.onblur
devrait fonctionner pour votre scénario:
http://www.thefutureoftheweb.com/blog/detect-browser-window-focus
Important Modifier: Cette réponse est obsolète. Depuis son écriture, l'API de visibilité ( mdn , exemple , spec ) a été introduit. C'est le meilleur moyen de résoudre ce problème.
var focused = true;
window.onfocus = function() {
focused = true;
};
window.onblur = function() {
focused = false;
};
Autant que je sache, focus
et blur
sont tous pris en charge sur ... tout. (voir http://www.quirksmode.org/dom/events/index.html )
En cherchant sur ce problème, j'ai trouvé une recommandation selon laquelle API de visibilité de la page devrait être utilisé. La plupart des navigateurs modernes prennent en charge cette API conformément à Puis-je utiliser: http://caniuse.com/#feat=pagevisibility .
Voici un exemple de travail (dérivé de cet extrait ):
$(document).ready(function() {
var hidden, visibilityState, visibilityChange;
if (typeof document.hidden !== "undefined") {
hidden = "hidden", visibilityChange = "visibilitychange", visibilityState = "visibilityState";
} else if (typeof document.msHidden !== "undefined") {
hidden = "msHidden", visibilityChange = "msvisibilitychange", visibilityState = "msVisibilityState";
}
var document_hidden = document[hidden];
document.addEventListener(visibilityChange, function() {
if(document_hidden != document[hidden]) {
if(document[hidden]) {
// Document hidden
} else {
// Document shown
}
document_hidden = document[hidden];
}
});
});
Mise à jour: L'exemple ci-dessus avait des propriétés préfixées pour les navigateurs Gecko et WebKit, mais j'ai supprimé cette implémentation, car ces navigateurs offraient une API de visibilité des pages sans préfixe depuis un moment maintenant. J'ai gardé le préfixe spécifique à Microsoft afin de rester compatible avec IE10.
Oui, ceux-ci devraient fonctionner pour vous. Vous venez de me rappeler de ce lien que j'ai découvert qui exploite ces techniques. lecture intéressante
Surprenant de ne voir personne mentionné document.hasFocus
if (document.hasFocus()) console.log('Tab is active')
Je le ferais de cette façon (référence http://www.w3.org/TR/page-visibility/ ):
window.onload = function() {
// check the visiblility of the page
var hidden, visibilityState, visibilityChange;
if (typeof document.hidden !== "undefined") {
hidden = "hidden", visibilityChange = "visibilitychange", visibilityState = "visibilityState";
}
else if (typeof document.mozHidden !== "undefined") {
hidden = "mozHidden", visibilityChange = "mozvisibilitychange", visibilityState = "mozVisibilityState";
}
else if (typeof document.msHidden !== "undefined") {
hidden = "msHidden", visibilityChange = "msvisibilitychange", visibilityState = "msVisibilityState";
}
else if (typeof document.webkitHidden !== "undefined") {
hidden = "webkitHidden", visibilityChange = "webkitvisibilitychange", visibilityState = "webkitVisibilityState";
}
if (typeof document.addEventListener === "undefined" || typeof hidden === "undefined") {
// not supported
}
else {
document.addEventListener(visibilityChange, function() {
console.log("hidden: " + document[hidden]);
console.log(document[visibilityState]);
switch (document[visibilityState]) {
case "visible":
// visible
break;
case "hidden":
// hidden
break;
}
}, false);
}
if (document[visibilityState] === "visible") {
// visible
}
};
Solution jQuery croisée sur le navigateur! Raw disponible sur GitHub
Le plug-in suivant passera par votre test standard pour différentes versions d'IE, Chrome, Firefox, Safari, etc. et établira vos méthodes déclarées en conséquence. Il traite également de questions telles que:
L'utilisation est aussi simple que: Faites défiler vers le bas pour ' Exécuter l'extrait'
$.winFocus(function(event, isVisible) {
console.log("Combo\t\t", event, isVisible);
});
// OR Pass False boolean, and it will not trigger on load,
// Instead, it will first trigger on first blur of current tab_window
$.winFocus(function(event, isVisible) {
console.log("Combo\t\t", event, isVisible);
}, false);
// OR Establish an object having methods "blur" & "focus", and/or "blurFocus"
// (yes, you can set all 3, tho blurFocus is the only one with an 'isVisible' param)
$.winFocus({
blur: function(event) {
console.log("Blur\t\t", event);
},
focus: function(event) {
console.log("Focus\t\t", event);
}
});
// OR First method becoms a "blur", second method becoms "focus"!
$.winFocus(function(event) {
console.log("Blur\t\t", event);
},
function(event) {
console.log("Focus\t\t", event);
});
/* Begin Plugin */
;;(function($){$.winFocus||($.extend({winFocus:function(){var a=!0,b=[];$(document).data("winFocus")||$(document).data("winFocus",$.winFocus.init());for(x in arguments)"object"==typeof arguments[x]?(arguments[x].blur&&$.winFocus.methods.blur.Push(arguments[x].blur),arguments[x].focus&&$.winFocus.methods.focus.Push(arguments[x].focus),arguments[x].blurFocus&&$.winFocus.methods.blurFocus.Push(arguments[x].blurFocus),arguments[x].initRun&&(a=arguments[x].initRun)):"function"==typeof arguments[x]?b.Push(arguments[x]):
"boolean"==typeof arguments[x]&&(a=arguments[x]);b&&(1==b.length?$.winFocus.methods.blurFocus.Push(b[0]):($.winFocus.methods.blur.Push(b[0]),$.winFocus.methods.focus.Push(b[1])));if(a)$.winFocus.methods.onChange()}}),$.winFocus.init=function(){$.winFocus.props.hidden in document?document.addEventListener("visibilitychange",$.winFocus.methods.onChange):($.winFocus.props.hidden="mozHidden")in document?document.addEventListener("mozvisibilitychange",$.winFocus.methods.onChange):($.winFocus.props.hidden=
"webkitHidden")in document?document.addEventListener("webkitvisibilitychange",$.winFocus.methods.onChange):($.winFocus.props.hidden="msHidden")in document?document.addEventListener("msvisibilitychange",$.winFocus.methods.onChange):($.winFocus.props.hidden="onfocusin")in document?document.onfocusin=document.onfocusout=$.winFocus.methods.onChange:window.onpageshow=window.onpagehide=window.onfocus=window.onblur=$.winFocus.methods.onChange;return $.winFocus},$.winFocus.methods={blurFocus:[],blur:[],focus:[],
exeCB:function(a){$.winFocus.methods.blurFocus&&$.each($.winFocus.methods.blurFocus,function(b,c){this.apply($.winFocus,[a,!a.hidden])});a.hidden&&$.winFocus.methods.blur&&$.each($.winFocus.methods.blur,function(b,c){this.apply($.winFocus,[a])});!a.hidden&&$.winFocus.methods.focus&&$.each($.winFocus.methods.focus,function(b,c){this.apply($.winFocus,[a])})},onChange:function(a){var b={focus:!1,focusin:!1,pageshow:!1,blur:!0,focusout:!0,pagehide:!0};if(a=a||window.event)a.hidden=a.type in b?b[a.type]:
document[$.winFocus.props.hidden],$(window).data("visible",!a.hidden),$.winFocus.methods.exeCB(a);else try{$.winFocus.methods.onChange.call(document,new Event("visibilitychange"))}catch(c){}}},$.winFocus.props={hidden:"hidden"})})(jQuery);
/* End Plugin */
// Simple example
$(function() {
$.winFocus(function(event, isVisible) {
$('td tbody').empty();
$.each(event, function(i) {
$('td tbody').append(
$('<tr />').append(
$('<th />', { text: i }),
$('<td />', { text: this.toString() })
)
)
});
if (isVisible)
$("#isVisible").stop().delay(100).fadeOut('fast', function(e) {
$('body').addClass('visible');
$(this).stop().text('TRUE').fadeIn('slow');
});
else {
$('body').removeClass('visible');
$("#isVisible").text('FALSE');
}
});
})
body { background: #AAF; }
table { width: 100%; }
table table { border-collapse: collapse; margin: 0 auto; width: auto; }
tbody > tr > th { text-align: right; }
td { width: 50%; }
th, td { padding: .1em .5em; }
td th, td td { border: 1px solid; }
.visible { background: #FFA; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h3>See Console for Event Object Returned</h3>
<table>
<tr>
<th><p>Is Visible?</p></th>
<td><p id="isVisible">TRUE</p></td>
</tr>
<tr>
<td colspan="2">
<table>
<thead>
<tr>
<th colspan="2">Event Data <span style="font-size: .8em;">{ See Console for More Details }</span></th>
</tr>
</thead>
<tbody></tbody>
</table>
</td>
</tr>
</table>