मुझे कैसे पता चलेगा कि किस डोम तत्व पर ध्यान केंद्रित किया गया है?


1309

मैं यह पता लगाना चाहूंगा कि जावास्क्रिप्ट में, वर्तमान में किस तत्व पर ध्यान केंद्रित किया गया है। मैं डोम के माध्यम से देख रहा हूँ और मुझे जो अभी तक चाहिए, वह नहीं मिला। क्या ऐसा करने का कोई तरीका है, और कैसे?

इसका कारण मैं देख रहा था:

मैं तीर की तरह चाबी बनाने की कोशिश कर रहा हूं और enterइनपुट तत्वों की एक तालिका के माध्यम से नेविगेट कर रहा हूं । टैब अब काम करता है, लेकिन दर्ज करें, और तीर डिफ़ॉल्ट रूप से ऐसा नहीं लगता है। मुझे कुंजी हैंडलिंग भाग सेट अप मिल गया है, लेकिन अब मुझे यह पता लगाने की आवश्यकता है कि इवेंट हैंडलिंग फ़ंक्शन में फ़ोकस को कैसे स्थानांतरित किया जाए।


2
: यहाँ एक बुकमार्कलेट कि ध्यान देने के साथ तत्व console.log है github.com/lingtalfi/where-is-focus-bookmarklet
लिंग

आप find-focused-elementपैकेज का उपयोग कर सकते हैं : npmjs.com/package/find-focused-element
मैक्सिम

जवाबों:


1533

उपयोग document.activeElement, यह सभी प्रमुख ब्राउज़रों में समर्थित है।

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

यदि आपको हटाने की आवश्यकता है तो activeElementआप धब्बा का उपयोग कर सकते हैं; document.activeElement.blur()। यह activeElementकरने के लिए बदल जाएगा body

सम्बंधित लिंक्स:


53
IE के बारे में निश्चित नहीं है, लेकिन FF और Safari दोनों ही BODY तत्व लौटाते हैं।
जेडब्ल्यू।

10
activeElementवास्तव में केंद्रित तत्व वापस नहीं करता है। किसी भी तत्व पर ध्यान केंद्रित किया जा सकता है। यदि किसी डॉक्यूमेंट में 4 'स्क्रोलडिव्स' हैं, तो उनमें से 0 या 1 एरो कीज़ द्वारा स्क्रॉल किए जा सकते हैं। यदि आप एक क्लिक करते हैं, तो वह div केंद्रित है। यदि आप सभी के बाहर क्लिक करते हैं, तो शरीर केंद्रित है। आप यह कैसे पता लगा सकते हैं कि कौन सा स्क्रोलडिव केंद्रित है? jsfiddle.net/rudiedirkx/bC5ke/show (चेक कंसोल)
रुडी

18
@Rudie, @Stewart: मैंने एक अधिक विस्तृत खेल का मैदान बनाने के लिए आपकी फिडेल पर बनाया है: jsfiddle.net/mklement/72rTF । आप पाएंगे कि एकमात्र प्रमुख ब्राउज़र (2012 के अंत तक) जो वास्तव में इस तरह के divफ़ायरफ़ॉक्स 17 पर ध्यान केंद्रित कर सकता है, और केवल इसे टैब करके । तत्वों के प्रकार जो सभी प्रमुख ब्राउज़रों के माध्यम से वापस आते document.activeElementहैं, वे इनपुट- संबंधित तत्वों तक ही सीमित हैं। यदि इस तरह के किसी तत्व पर ध्यान नहीं दिया जाता है, तो सभी प्रमुख ब्राउज़र bodyतत्व को वापस कर देते हैं - IE 9 को छोड़कर, जो htmlतत्व को वापस करता है।
mklement0

10
यकीन नहीं है कि अगर यह मदद करता है, लेकिन आप एक तत्व बना सकते हैं जैसे कि div एक कीबोर्ड प्राप्त करता है जिसमें विशेषता टैबइंडेक्स = "0" शामिल है
Marco Luglio

4
किसी भी परिस्थिति में इसे किसी अपवाद के रूप document.activeElementमें लपेटा जा सकता try catchहै (केवल IE9 AFAIK नहीं)। देखें Bugs.jquery.com/ticket/13393 और bugs.jqueryui.com/ticket/8443
लूट

127

जैसा कि JW द्वारा कहा गया है, आप कम से कम ब्राउज़र-स्वतंत्र तरीके से वर्तमान केंद्रित तत्व नहीं खोज सकते। लेकिन अगर आपका ऐप केवल IE है (कुछ हैं ...), तो आप इसे निम्न तरीके से पा सकते हैं:

document.activeElement

संपादित करें: ऐसा लगता है कि IE में सब कुछ गलत नहीं था, यह HTML5 ड्राफ्ट का हिस्सा है और कम से कम क्रोम, सफारी और फ़ायरफ़ॉक्स के नवीनतम संस्करण द्वारा समर्थित प्रतीत होता है।


5
FF3 भी। यह वास्तव में "फोकस प्रबंधन" के आसपास HTML5 कल्पना का हिस्सा है।
क्रिसेंट फ्रेश

2
यह क्रोम और ओपेरा (9.62) के वर्तमान संस्करण में काम करता है। ओएस एक्स पर सफारी 3.2.3 में काम नहीं करता है, लेकिन यह सफारी 4 में काम करता है जो कल जारी किया गया था :)
ग्रिगर्स

अभी भी क्रोम 19 के लिए समान है: एस
सेबास

1
यह केवल क्रोम (20) / सफारी (5.1.3) में काम करता है जब आप तत्व पर टैब करने के लिए कीबोर्ड का उपयोग करते हैं। यदि आप उस पर क्लिक करते हैं, तो न तो jquery: चयनकर्ता पर ध्यान केंद्रित करें और न ही document.activeElement उस पर लौटने में सफल होता है, जिस पर आपने क्लिक किया था (क्रमशः अपरिभाषित और दस्तावेज़ निकाय तत्व वापस लौटाता है)। PS मुझे विश्वास नहीं हो रहा है कि यह धागा 2 साल पुराना है और अभी भी वेबकिट पर रिग्रेशन की समस्याएँ हैं, साथ ही जहाँ स्किप लिंक काम नहीं करते हैं, लेकिन प्रायोगिक css3 को जोड़ने के साथ इतना काम किया जा रहा है। मुझे लगता है कि मैं अपने परिवार और दोस्तों को फ़ायरफ़ॉक्स की सिफारिश करने के लिए वापस जा सकता हूं।
डॉन

^ ^ document.activeElement ठीक है जब आप एक पाठ क्षेत्र या अन्य इनपुट पर ध्यान केंद्रित करने के लिए क्लिक करते हैं। यदि यह एक लिंक है तो यह उस पर ध्यान केंद्रित नहीं करेगा जब (पृष्ठ में या स्पष्ट रूप से अन्यथा) पर क्लिक किया जाता है।
13:13

84

यदि आप jQuery का उपयोग कर सकते हैं, तो यह अब समर्थन करता है: ध्यान दें, बस यह सुनिश्चित करें कि आप संस्करण 1.6+ का उपयोग कर रहे हैं।

यह कथन आपको वर्तमान में केंद्रित तत्व मिलेगा।

$(":focus")

से: jQuery के साथ उस पर ध्यान केंद्रित करने वाले तत्व का चयन कैसे करें


4
यह अच्छा है, लेकिन jQuery कैसे करता है? document.activeElement? मैंने इसे पाया: return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
हैरी पेहोनेन

46

document.activeElementअब HTML5 वर्किंग ड्राफ्ट विनिर्देश का हिस्सा है , लेकिन यह अभी तक कुछ गैर-प्रमुख / मोबाइल / पुराने ब्राउज़रों में समर्थित नहीं हो सकता है। आप वापस गिर सकते हैं querySelector(यदि वह समर्थित है)। यह भी ध्यान देने योग्य है कि document.activeElementवापस आ जाएगीdocument.body यदि कोई तत्व केंद्रित नहीं है तो - भले ही ब्राउज़र विंडो में फोकस न हो।

निम्नलिखित कोड इस मुद्दे के आसपास काम करेगा और querySelectorथोड़ा बेहतर समर्थन देने के लिए वापस आ जाएगा ।

var focused = document.activeElement;
if (!focused || focused == document.body)
    focused = null;
else if (document.querySelector)
    focused = document.querySelector(":focus");

ध्यान देने वाली एक अतिरिक्त बात यह है कि इन दो तरीकों के बीच प्रदर्शन अंतर है। activeElementसंपत्ति का उपयोग करने की तुलना में चयनकर्ताओं के साथ दस्तावेज़ को छोड़ना हमेशा बहुत धीमा होगा । इस jsperf.com परीक्षण को देखें ।


21

अपने आप से, document.activeElementअभी भी एक तत्व वापस कर सकते हैं यदि दस्तावेज़ केंद्रित नहीं है (और इस प्रकार दस्तावेज़ में कुछ भी ध्यान केंद्रित नहीं है!)

आप उस व्यवहार को चाह सकते हैं, या यह बात नहीं हो सकती है (उदाहरण के लिए एक keydownघटना के भीतर ), लेकिन अगर आपको कुछ जानने की जरूरत है तो आप वास्तव में ध्यान केंद्रित कर सकते हैं document.hasFocus()

निम्नलिखित आपको केंद्रित तत्व देगा यदि कोई है, या कोई और है null

var focused_element = null;
if (
    document.hasFocus() &&
    document.activeElement !== document.body &&
    document.activeElement !== document.documentElement
) {
    focused_element = document.activeElement;
}

यह जाँचने के लिए कि क्या किसी विशिष्ट तत्व पर ध्यान केंद्रित है, यह सरल है:

var input_focused = document.activeElement === input && document.hasFocus();

यह जांचने के लिए कि क्या कुछ भी केंद्रित है, यह फिर से अधिक जटिल है:

var anything_is_focused = (
    document.hasFocus() &&
    document.activeElement !== null &&
    document.activeElement !== document.body &&
    document.activeElement !== document.documentElement
);

Robustness Note : उस कोड में जहां यह खिलाफ चेक करता है document.bodyऔर document.documentElement, यह इसलिए है क्योंकि कुछ ब्राउज़र इनमें से किसी एक को लौटाते हैं या nullजब कुछ भी फोकस नहीं होता है।

अगर <body>(या हो सकता है <html>) के पास इसकी tabIndexविशेषता नहीं है और इस तरह वास्तव में ध्यान केंद्रित किया जा सकता है । यदि आप एक पुस्तकालय या कुछ लिख रहे हैं और इसे मजबूत बनाना चाहते हैं, तो आपको शायद किसी भी तरह से संभालना चाहिए।


यहां ध्यान केंद्रित तत्व प्राप्त करने के लिए ( भारी - भरकम वायुरोधी) "वन-लाइनर" संस्करण है, जो वैचारिक रूप से अधिक जटिल है क्योंकि आपको शॉर्ट-सर्कुलेटिंग के बारे में जानना होगा, और y'know, यह स्पष्ट रूप से एक लाइन पर फिट नहीं होता है, आपको मानते हुए यह पठनीय होना चाहते हैं।
मैं यह एक की सिफारिश नहीं करने जा रहा हूँ। लेकिन अगर आप 1337 hax0r हैं, तो idk ... यह वहाँ है। यदि आप कुछ मामलों में मन नहीं लगाते हैं तो आप
उस || nullहिस्से को भी हटा सकते हैं false। (आप अभी भी मिल सकता है nullअगर document.activeElementहै null):

var focused_element = (
    document.hasFocus() &&
    document.activeElement !== document.body &&
    document.activeElement !== document.documentElement &&
    document.activeElement
) || null;

यह जांचने के लिए कि क्या कोई विशिष्ट तत्व केंद्रित है, वैकल्पिक रूप से आप घटनाओं का उपयोग कर सकते हैं, लेकिन इस तरीके के लिए सेटअप (और संभावित रूप से फाड़) की आवश्यकता होती है, और महत्वपूर्ण रूप से, एक प्रारंभिक स्थिति मानता है :

var input_focused = false;
input.addEventListener("focus", function() {
    input_focused = true;
});
input.addEventListener("blur", function() {
    input_focused = false;
});

आप गैर-घटना वाले तरीके का उपयोग करके प्रारंभिक स्थिति को ठीक कर सकते हैं, लेकिन फिर आप इसके बजाय इसका उपयोग कर सकते हैं।


15

document.activeElement<body>यदि कोई फ़ोकस करने योग्य तत्व फ़ोकस में हैं, तो तत्व के लिए डिफ़ॉल्ट हो सकता है । इसके अतिरिक्त, यदि कोई तत्व केंद्रित है और ब्राउज़र विंडो धुंधली है,activeElement तो केंद्रित तत्व को पकड़ना जारी रखेगा।

यदि इन दोनों में से कोई भी व्यवहार वांछनीय नहीं है, तो CSS- आधारित दृष्टिकोण पर विचार करें document.querySelector( ':focus' ):।


कूल, हां मेरे मामले में आपके दृष्टिकोण ने पूरी तरह से समझ में आया। मैं अपने ध्यान देने योग्य तत्वों को 'tabindex = "- 1"' के साथ सेट कर सकता हूं, अगर उनमें से किसी का भी ध्यान केंद्रित नहीं है (चलो कहते हैं, कुछ पाठ या चित्र, जो मुझे परवाह नहीं है) दस्तावेज़। प्रश्नरीटर ('फोकस') रिटर्न शून्य।
मैनफ्रेड

उपयोग करने से बचने के लिए मेरा उत्तर देखें querySelector: stackoverflow.com/a/40873560/2624876
1j01

10

मुझे जोएल एस द्वारा इस्तेमाल किया गया दृष्टिकोण पसंद आया, लेकिन मुझे सादगी पसंद है document.activeElement। मैंने jQuery का उपयोग किया और दोनों को संयोजित किया। पुराने ब्राउज़र जो समर्थन नहीं करते हैं document.activeElementवे jQuery.data()'hasFocus' के मान को संग्रहीत करने के लिए उपयोग करेंगे । नए ब्राउज़र उपयोग करेंगे document.activeElement। मुझे लगता है कि document.activeElementबेहतर प्रदर्शन होगा।

(function($) {
var settings;
$.fn.focusTracker = function(options) {
    settings = $.extend({}, $.focusTracker.defaults, options);

    if (!document.activeElement) {
        this.each(function() {
            var $this = $(this).data('hasFocus', false);

            $this.focus(function(event) {
                $this.data('hasFocus', true);
            });
            $this.blur(function(event) {
                $this.data('hasFocus', false);
            });
        });
    }
    return this;
};

$.fn.hasFocus = function() {
    if (this.length === 0) { return false; }
    if (document.activeElement) {
        return this.get(0) === document.activeElement;
    }
    return this.data('hasFocus');
};

$.focusTracker = {
    defaults: {
        context: 'body'
    },
    focusedElement: function(context) {
        var focused;
        if (!context) { context = settings.context; }
        if (document.activeElement) {
            if ($(document.activeElement).closest(context).length > 0) {
                focused = document.activeElement;
            }
        } else {
            $(':visible:enabled', context).each(function() {
                if ($(this).data('hasFocus')) {
                    focused = this;
                    return false;
                }
            });
        }
        return $(focused);
    }
};
})(jQuery);

3
क्या इसे बदल कर @William Denniss किया जा सकता है $("*:focus")?
पाइलिनक्स

मुझे लगता है कि यह कर सकता था। मैंने यह एक लंबे समय से पहले लिखा था और एक बेहतर समाधान को फिर से करने का एक कारण नहीं था कि अब यह 5 साल बाद है। कोशिश करके देखो! मैं बस यही कर सकता हूं। मैं हमारी साइट पर कम प्लगइन! :)
जेसन

10

एक छोटा सहायक जो मैंने मूटूल में इन उद्देश्यों के लिए उपयोग किया है:

FocusTracker = {
    startFocusTracking: function() {
       this.store('hasFocus', false);
       this.addEvent('focus', function() { this.store('hasFocus', true); });
       this.addEvent('blur', function() { this.store('hasFocus', false); });
    },

    hasFocus: function() {
       return this.retrieve('hasFocus');
    }
}

Element.implement(FocusTracker);

इस तरह से आप जाँच कर सकते हैं कि क्या तत्व के साथ फोकस है el.hasFocus()बशर्ते कि startFocusTracking()दिए गए तत्व पर कॉल किया गया हो।


7

JQuery :focusवर्तमान के रूप में छद्म वर्ग का समर्थन करता है । यदि आप इसे JQuery के दस्तावेज़ में ढूंढ रहे हैं, तो "चयनकर्ता" के तहत जाँच करें जहाँ यह आपको W3C CSS डॉक्स की ओर इंगित करता है । मैंने Chrome, FF और IE 7+ के साथ परीक्षण किया है। ध्यान दें कि IE में काम करने के लिए, <!DOCTYPE...html पेज पर मौजूद होना चाहिए। यहाँ एक उदाहरण दिया गया है कि आपने उस तत्व को एक आईडी निर्दिष्ट किया है जिसमें ध्यान केंद्रित किया गया है:

$(":focus").each(function() {
  alert($(this).attr("id") + " has focus!");
});

1
आपको (हमेशा?) के this.idबजाय का उपयोग करना चाहिए $(this).attr('id'), या कम से कम (जब आप पहले से ही अपने jQuery वस्तु है) $(this)[0].id। इस स्तर पर देशी जावास्क्रिप्ट तेजी से और अधिक कुशल है। इस मामले में ध्यान देने योग्य नहीं हो सकता है, लेकिन सिस्टमवाइड आपको एक अंतर दिखाई देगा।
मार्टिज़न

7

यदि आप एक ऐसी वस्तु प्राप्त करना चाहते हैं जिसका उदाहरण है Element, तो आपको अवश्य उपयोग करना चाहिए document.activeElement, लेकिन यदि आप उस वस्तु को प्राप्त करना चाहते हैं जो कि उदाहरण के लिए है Text, तो आपको उसका उपयोग करना होगाdocument.getSelection().focusNode

मुझे उम्मीद है कि मदद मिलेगी।


किस तरीके से बेहतर है?
जे 01

अपने ब्राउज़र का इंस्पेक्टर खोलें, पृष्ठ के किसी भी स्थान पर क्लिक करें, इसे पिछले करें document.getSelection().focusNode.parentElementऔर Enter पर टैप करें। उसके बाद, अतीत document.activeElementऔर यह नमूना करना। ;)
rplaurindo

इस टिप्पणी बॉक्स ध्यान केंद्रित, document.activeElementदेता है <textarea>, जबकि document.getSelection().focusNodeदेता है <td>कि होता है <textarea>(और document.getSelection().focusNode.parentElementदेता <tr>युक्त <td>)
1j01

क्षमा करें, मेरी क्षमायाचना। मैंने इसे अच्छी तरह से नहीं समझाया। यदि आप एक ऐसी वस्तु प्राप्त करना चाहते हैं जो कि उदाहरण के लिए है Element, तो आपको इसका उपयोग करना होगा document.activeElement, लेकिन यदि आप एक ऐसी वस्तु प्राप्त करना चाहते हैं जिसका उदाहरण है Text, तो आपको उपयोग करना होगा document.getSelection().focusNode। कृपया, इसे फिर से परखें। मुझे उम्मीद है कि मैंने मदद की।
rplaurindo 3

2
प्रश्न यह पूछ रहा है कि वर्तमान में किस तत्व पर ध्यान केंद्रित किया गया है। और focusNodeएक पाठ नोड होने की गारंटी नहीं है।
ज .01

6

Document.activeElement का उपयोग करने के साथ संभावित समस्याएं हैं। विचार करें:

<div contentEditable="true">
  <div>Some text</div>
  <div>Some text</div>
  <div>Some text</div>
</div>

यदि उपयोगकर्ता इनर-डिव पर ध्यान केंद्रित करता है, तो document.activeElement अभी भी बाहरी डिव का संदर्भ देता है। आंतरिक डिव का कौन सा फोकस है, यह निर्धारित करने के लिए आप document.activeElement का उपयोग नहीं कर सकते।

निम्न फ़ंक्शन इसके चारों ओर हो जाता है, और केंद्रित नोड लौटाता है:

function active_node(){
  return window.getSelection().anchorNode;
}

यदि आप केंद्रित तत्व प्राप्त करेंगे, तो उपयोग करें:

function active_element(){
  var anchor = window.getSelection().anchorNode;
  if(anchor.nodeType == 3){
        return anchor.parentNode;
  }else if(anchor.nodeType == 1){
        return anchor;
  }
}

3
यह वास्तव में एक समस्या नहीं है document.activeElement: आंतरिक <div>तत्व वास्तव में ध्यान केंद्रित नहीं कर सकते हैं, जैसा कि आप :focusछद्म वर्ग को दृश्यमान रूप से सेट करके देख सकते हैं (उदाहरण: jsfiddle.net/4gasa1t2/1 )। आप जिस बारे में बात कर रहे <div>हैं, उसमें से कौन सा आंतरिक चयन या कैरेट है, जो एक अलग मुद्दा है।
टिम डाउन

6

मैंने निम्नलिखित स्निपेट को उपयोगी पाया है जब यह निर्धारित करने की कोशिश की जा रही है कि वर्तमान में किस तत्व पर ध्यान केंद्रित किया गया है। निम्नलिखित को अपने ब्राउज़र के कंसोल में कॉपी करें, और प्रत्येक सेकंड में उस वर्तमान तत्व का विवरण प्रिंट होगा जिसमें फोकस है।

setInterval(function() { console.log(document.querySelector(":focus")); }, 1000);

console.logयदि आप संपूर्ण तत्व को प्रिंट करने में मदद नहीं करते हैं, तो सटीक तत्व को इंगित करने में मदद करने के लिए कुछ अलग से लॉग आउट करने के लिए स्वतंत्र महसूस करें ।


5

अन्य उत्तरों को पढ़ना, और स्वयं की कोशिश करना, ऐसा लगता है document.activeElementकि आपको अधिकांश ब्राउज़रों में आपकी आवश्यकता का तत्व देगा।

यदि आपके पास एक ब्राउज़र है जो दस्तावेज़ का समर्थन नहीं करता है। सक्रियण अगर आपके पास jQuery है, तो आपको इसे सभी फोकस घटनाओं पर इस तरह से बहुत सरल तरीके से पॉप्युलेट करना चाहिए (अप्रकाशित क्योंकि मेरे पास ब्राउज़र नहीं है जो उन मानदंडों को पूरा करने के लिए है ):

if (typeof document.activeElement === 'undefined') { // Check browser doesn't do it anyway
  $('*').live('focus', function () { // Attach to all focus events using .live()
    document.activeElement = this; // Set activeElement to the element that has been focussed
  });
}

5

यदि आप jQuery का उपयोग कर रहे हैं, तो आप यह पता लगाने के लिए इसका उपयोग कर सकते हैं कि क्या कोई तत्व सक्रिय है:

$("input#id").is(":active");


3

इस समाधान को देने के लिए मैं इसे यहाँ रख रहा हूँ।

मैंने document.activeInputArea नामक एक संपत्ति बनाई है, और jQuery के HotKeys का उपयोग तीर कुंजी, टैब के लिए कीबोर्ड घटनाओं को फंसाने और दर्ज करने के लिए किया, और मैंने इनपुट तत्वों में क्लिक करने के लिए एक इवेंट हैंडलर बनाया।

फिर मैंने हर बार फ़ोकस में सक्रियInputArea को समायोजित किया, इसलिए मैं उस संपत्ति का उपयोग यह जानने के लिए कर सकता था कि मैं कहाँ था।

हालांकि, इसे पेंच करना आसान है, क्योंकि अगर आपके पास सिस्टम में बग है और फोकस नहीं है कि आप यह कहां सोचते हैं, तो सही फोकस को बहाल करना बहुत कठिन है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.