पता लगाएँ कि क्या ब्राउज़र टैब फोकस है


149

क्या यह पता लगाने के लिए एक विश्वसनीय क्रॉस-ब्राउज़र तरीका है कि एक टैब पर ध्यान केंद्रित किया गया है।

परिदृश्य यह है कि हमारे पास एक ऐसा आवेदन है जो नियमित रूप से स्टॉक की कीमतों के लिए सर्वेक्षण करता है, और अगर पृष्ठ पर ध्यान केंद्रित नहीं होता है तो हम मतदान को रोक सकते हैं और सभी को ट्रैफ़िक के शोर से बचा सकते हैं, खासकर जब लोग विभिन्न पोर्टफोलियो के साथ कई टैब खोलने के प्रशंसक हैं।

है window.onblurऔर window.onfocusइस के लिए एक विकल्प?


जवाबों:


127

हां, window.onfocusऔर window.onblurआपके परिदृश्य के लिए काम करना चाहिए:

http://www.thefutureoftheweb.com/blog/detect-browser-window-focus


3
इस के onfocusin / onfocusout पहलू, और आपके द्वारा रोका गया उपयोगकर्ता बताने के बारे में भी नोट वास्तव में अच्छे नोट हैं। धन्यवाद।
फेंटन

7
कृपया ध्यान दें कि आप पेज लोड होने पर इस पेज के सक्रिय या निष्क्रिय होने के बीच अंतर नहीं कर सकते।
pimvdb

@SteveFenton - onfocusक्रॉसब्रोसर है, जहां आपके द्वारा बताई गई घटनाएं IE-only हैं, मैं नहीं देख सकता कि यह आपके द्वारा एक अच्छा नोट क्यों माना जाएगा ..
vsync

1
@vsync - लिंक किए गए लेख को पढ़ें, आप देखेंगे कि यह 'ऑनफोकसिन' और 'ऑनफोकस' दोनों का उपयोग करता है ।
फेंटन

क्या आप कम से कम दोनों के बीच अंतर का उल्लेख कर सकते हैं?
लेनार होयट

53

महत्वपूर्ण संपादन: यह उत्तर पुराना है। इसे लिखने के बाद से विजिबिलिटी एपीआई ( mdn , उदाहरण , युक्ति ) पेश किया गया है। यह इस समस्या को हल करने का बेहतर तरीका है।


var focused = true;

window.onfocus = function() {
    focused = true;
};
window.onblur = function() {
    focused = false;
};

AFAIK, focusऔर blurसभी ... सब कुछ पर समर्थित हैं। (देखें http://www.quirksmode.org/dom/events/index.html )


2
बस थोड़ा सा ध्यान दें, इन सभी समाधानों के साथ, आप उपयोगकर्ता के टैब को पूरी तरह से लोड होने से पहले उपयोगकर्ता के बदलने के जोखिम को चलाते हैं, इस प्रकार ध्यान केंद्रित करने के लिए गलत मान प्रदान करते हैं। सुनिश्चित नहीं है कि इसके आसपास एक अच्छा तरीका है।
JayD3e

अपडेट लिंक वही हैं जो मैं देख रहा था। उन्हें जोड़ने के लिए धन्यवाद!
webLacky3rdClass

सवाल विशेष रूप से यह पता लगाने के बारे में है कि क्या किसी पृष्ठ पर ध्यान केंद्रित किया गया है, जो यह पता लगाने से अलग है कि क्या पृष्ठ दिखाई दे रहा है। एक ही समय में (अलग-अलग विंडो में) कई पेज दिखाई दे सकते हैं, जबकि केवल एक ही फोकस हो सकता है। जो भी तकनीक आपकी आवश्यकताओं के अनुरूप है, का उपयोग करें, लेकिन अंतर को जानें।
jaredjacobs

1
यह एक खतरनाक समाधान है क्योंकि यह एक बड़े एप्लिकेशन में कुछ अन्य ईवेंट श्रोता को ओवरराइड करने का जोखिम चलाता है। आपको इसके बजाय इस उत्तर का अनुसरण करना चाहिए: stackoverflow.com/a/21935031/549503
mmmeff

51

इस समस्या के बारे में खोज करते समय, मुझे एक सिफारिश मिली कि पेज विजिबिलिटी एपीआई का उपयोग किया जाना चाहिए। अधिकांश आधुनिक ब्राउज़र कैन I यूज़: http://caniuse.com/#feat=pagevisibility के अनुसार इस एपीआई का समर्थन करते हैं ।

यहाँ एक कार्य उदाहरण ( इस स्निपेट से लिया गया है ):

$(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];
    }
  });
});

अद्यतन: ऊपर दिए गए उदाहरण में गेको और वेबकैट ब्राउज़रों के लिए उपसर्ग गुण थे, लेकिन मैंने उस कार्यान्वयन को हटा दिया क्योंकि ये ब्राउज़र अभी कुछ समय के लिए उपसर्ग के बिना पृष्ठ दृश्यता एपीआई की पेशकश कर रहे थे। IE10 के साथ संगत रहने के लिए मैंने Microsoft विशिष्ट उपसर्ग रखा।


जब विक्रेता उपसर्ग इस से जाते हैं, तो मैं शायद स्विच करूँगा!
फेंटन

केवल इसके साथ वास्तविक समस्या विक्रेता उपसर्ग नहीं है क्योंकि आधिकारिक W3C अनुशंसा है (दिनांक 29. अक्टूबर 2013)। कुछ मामलों में एक समस्या यह है कि पृष्ठ दृश्यता एपीआई IE10 और नए में समर्थित है। यदि आपको IE9 का समर्थन करने की आवश्यकता है, तो आपको एक अलग दृष्टिकोण की तलाश करनी चाहिए ...
Ilija

सभी आधुनिक ब्राउज़रों के लिए यह सही तरीका है। +1
Ajedi32

क्या आप सुनिश्चित हैं कि ये विक्रेता उपसर्ग आवश्यक हैं? MDN और CanIUse के अनुसार, वे संस्करण 32 के बाद से क्रोम पर आवश्यक नहीं हैं, या फ़ायरफ़ॉक्स पर संस्करण 17 के बाद से, और वे IE पर आवश्यक नहीं रहे हैं।
Ajedi32

@ Ajedi32 धन्यवाद। मुझे कुछ परीक्षण करने और खुदाई करने की आवश्यकता है, यह देखने के लिए कि यह अभी भी प्रासंगिक है, और अब क्या छोड़ा जा सकता है।
इलिजा

37

किसी का उल्लेख नहीं देखकर आश्चर्य हुआ document.hasFocus

if (document.hasFocus()) console.log('Tab is active')

MDN में अधिक जानकारी है।


मेरे लिए काम करता है (क्रोम और फ़ायरफ़ॉक्स पर परीक्षण किया गया)। स्वीकृत उत्तर (onfocus / onblur) ने काम नहीं किया
harmv

सही जवाब अभी तक बहुत नीचे। StackOverflow जाने का रास्ता!
अक्टूबर ग्यारह

वास्तव में, यह सही जवाब नहीं है? क्या किसी को कोई नकारात्मक पहलू दिखाई देता है?
गैस्पर

2
इसका केवल नकारात्मक पक्ष यह है कि यदि आप यह निर्धारित करने की कोशिश कर रहे हैं कि यदि टैब एक आइफ्रेम के भीतर से फोकस में है, तो यदि पेरेंट पेज अभी भी फोकस से बाहर था तो आईफ्रेम लोड होने की स्थिति में यह विफल हो जाएगा। इसे कवर करने के लिए आपको पृष्ठ दृश्यता एपीआई के साथ जाना होगा।
इवान

29

हां उन लोगों को आपके लिए काम करना चाहिए। आपने मुझे इस लिंक की याद दिलाई है जो मुझे पता चला है कि उन तकनीकों का फायदा उठाता है। दिलचस्प पढ़ा


2
+1 - यह एक बहुत ही चालाक चाल है, मैं सोच सकता हूं कि बहुत सारे लोगों को बेवकूफ बनाना।
फेंटन

2
क्या एक सरल और कुटिल हमला। दिलचस्प है कि पढ़ा, धन्यवाद।
वू

4

मैं इसे इस तरह से करूंगा (संदर्भ 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
        }

    };  

क्या आप बता सकते हैं कि यह उत्तर @ इलिजा द्वारा दिए गए उत्तर से कैसे भिन्न है - इसमें अंतर हो सकता है, लेकिन यह सूक्ष्म है - इसलिए यह क्या है और क्यों अलग होना चाहिए, इसकी व्याख्या की जाएगी।
फेंटन

2

क्रॉस ब्राउज़र jQuery समाधान! GitHub पर कच्चा उपलब्ध है

मज़ा और प्रयोग करने में आसान!

निम्न प्लगइन IE, क्रोम, फ़ायरफ़ॉक्स, सफारी, आदि के विभिन्न संस्करणों के लिए आपके मानक परीक्षण के माध्यम से जाएगा .. और तदनुसार अपने घोषित तरीकों को स्थापित करें। यह इस तरह के मुद्दों से संबंधित है:

  • onblur | .blur / onfocus | .focus " डुप्लिकेट " कॉल
  • वैकल्पिक शब्द के चयन के माध्यम से विंडो खो जाना, जैसे शब्द
    • यह केवल इसलिए अवांछनीय हो जाता है, क्योंकि यदि आपके पास एक बैंक पेज खुला है, और यह ऑनब्लूर ईवेंट पृष्ठ को मास्क करने के लिए कहता है, तो यदि आप कैलकुलेटर खोलते हैं, तो आप अब पेज नहीं देख सकते हैं!
  • पृष्ठ लोड पर ट्रिगर नहीं है

उपयोग उतना ही सरल है: ' रन स्निपेट ' के लिए नीचे स्क्रॉल करें

$.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>


आपको प्लगइन के लिए कोड को अन-मिनिमाइज़ करना चाहिए।
पैट्रिक डेसजार्डिन्स 16

@PatrickDesjardins हाँ। इस सप्ताह के अंत में अन्य चीजों के साथ करने की योजना बनाएं। मैं? मेरे पास सामान के एक समूह के लिए एक जिस्ट बनाओ। गदबब पर जदमकसतन। पुराने उत्तरों के लिंक इस तरह जोड़ेंगे जैसे मैं उन्हें पाने के लिए जोड़ देता हूँ
SpYk3HH

क्या होगा यदि मैं चाहता हूं कि पेज फोकस खो जाए, जब मैं "वर्ड" या "कैलकुलेटर" जैसे किसी अन्य ऐप पर स्विच करूं?
बनारस

@ बेंस गलत हो सकता है, लेकिन मेरा मानना ​​है कि यह बहुत ही बुनियादी आधार की कार्यक्षमता है jQuery(window).blur/focus, जो कि कई लोगों द्वारा अवांछित था, इस प्रकार मैंने इस प्लगइन को बनाया है। प्लगइन यह
बताने में
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.