어떤 DOM 요소에 초점이 있는지 어떻게 알 수 있습니까?


1309

JavaScript에서 현재 어떤 요소에 포커스가 있는지 확인하고 싶습니다. DOM을 살펴본 결과 아직 필요한 것을 찾지 못했습니다. 이것을 할 수있는 방법이 있습니까?

내가 이것을 찾고있는 이유 :

화살표와 같은 키를 만들고 enter입력 요소 테이블을 탐색 하려고합니다 . 탭은 지금 작동하지만 입력하면 화살표는 기본적으로 보이지 않습니다. 키 처리 부분이 설정되었지만 이제 이벤트 처리 기능에서 포커스를 이동하는 방법을 알아야합니다.


2
다음은 포커스가있는 요소를 console.log하는 책갈피입니다. github.com/lingtalfi/where-is-focus-bookmarklet
ling

find-focused-element패키지 를 사용할 수 있습니다 : npmjs.com/package/find-focused-element
Maxim Zhukov

답변:


1533

를 사용 document.activeElement하면 모든 주요 브라우저에서 지원됩니다.

이전에는 어떤 양식 필드에 포커스가 있는지 알아 보려고했지만 불가능했습니다. 구형 브라우저에서 감지를 에뮬레이트하려면 모든 필드에 "초점"이벤트 핸들러를 추가하고 변수에 마지막으로 초점을 맞춘 필드를 기록하십시오. "blur"핸들러를 추가하여 마지막 초점 필드의 blur 이벤트시 변수를 지우십시오.

제거해야 activeElement할 경우 흐림 효과를 사용할 수 있습니다. document.activeElement.blur(). 로 변경 activeElement됩니다 body.

관련된 링크들:


53
IE에 대해서는 확실하지 않지만 FF와 Safari는 BODY 요소를 반환합니다.
JW.

10
activeElement실제로 초점을 맞춘 요소를 반환하지 않습니다. 모든 요소에 포커스가있을 수 있습니다. 문서에 4 개의 'scrolldivs'가있는 경우 해당 div 중 0 또는 1을 화살표 키로 스크롤 할 수 있습니다. 하나를 클릭하면 해당 div에 초점이 맞춰집니다. 모두 바깥 쪽을 클릭하면 본문에 초점이 맞춰집니다. 어떤 scrolldiv가 초점을 맞추고 있는지 어떻게 알 수 있습니까? jsfiddle.net/rudiedirkx/bC5ke/show (콘솔 확인)
Rudie

18
@Rudie, @Stewart : 좀 더 정교한 놀이터를 만들기 위해 바이올린을 만들었습니다 : jsfiddle.net/mklement/72rTF . 실제로 이러한 초점을 맞출 수있는 유일한 주요 브라우저 (2012 년 말 기준) div는 Firefox 17이며 하면됩니다. 모든 주요 브라우저가 반환하는 요소 유형은 입력 관련 요소 document.activeElement로 제한됩니다 . 그러한 요소에 포커스가 없으면 모든 주요 브라우저는 요소를 반환합니다 . bodyhtml
mklement0

10
도움이되는지 확실하지 않지만 tabindex = "0"속성을 포함하여 div 수신 키보드 포커스와 같은 요소를 만들 수 있습니다.
Marco Luglio

4
어떤 상황에서는 IE9 AFAIK뿐만 아니라 예외가 발생할 수 document.activeElement있으므로에 액세스 해야합니다 try catch. bugs.jquery.com/ticket/13393bugs.jqueryui.com/ticket/8443
robocat

127

JW가 말했듯이 적어도 브라우저 독립적 인 방식으로 현재 초점을 맞춘 요소를 찾을 수 없습니다. 그러나 응용 프로그램이 IE 전용 인 경우 (일부는 ...) 다음과 같은 방법으로 찾을 수 있습니다.

document.activeElement

편집 : IE는 결국 모든 것이 잘못 된 것처럼 보이지만 HTML5 초안의 일부이며 최소한 최신 버전의 Chrome, Safari 및 Firefox에서 지원되는 것 같습니다.


5
FF3도. 이것은 실제로 "초점 관리"에 관한 HTML5 사양의 일부입니다.
Crescent Fresh

2
현재 버전의 Chrome 및 Opera (9.62)에서 작동합니다. OS X에서 사파리 3.2.3에서 작동하지만, 어제 : 사파리 출시 된 4에서 작동하지 않습니다
의 Gregers

크롬 19 : S
Sebas

1
키보드를 사용하여 요소를 탭 할 때 크롬 (20) / 사파리 (5.1.3)에서만 작동합니다. 그것을 클릭하면 jquery : focus selector 나 document.activeElement가 클릭 한 것을 반환하지 못합니다 (정의되지 않은 요소와 문서 본문 요소를 각각 반환합니다). 추신 : 나는이 스레드가 2 세라고 믿을 수 없으며 건너 뛰기 링크가 작동하지 않는 웹 킷에는 여전히 회귀 문제가 있지만 실험적인 CSS3를 추가하여 많은 작업이 수행되고 있습니다. 가족과 친구들에게 파이어 폭스를 추천하는 것으로 돌아갈 수 있다고 생각합니다.
Dawn

^^ document.activeElement를 클릭하면 텍스트 영역이나 다른 입력에 집중할 수 있습니다. 링크 인 경우 클릭 할 때 (페이지 또는 다른 방법으로) 초점을 맞추지 않습니다.
marksyzm

84

jQuery를 사용할 수 있다면 이제는 : focus를 지원하므로 1.6 이상 버전을 사용하고 있는지 확인하십시오.

이 문장은 현재 초점을 맞춘 요소를 제공합니다.

$(":focus")

보낸 사람 : jQuery를 사용하여 초점을 맞춘 요소를 선택하는 방법


4
이것은 좋지만 jQuery는 어떻게합니까? document.activeElement? return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
Harry Pehkonen

46

document.activeElementHTML5 작업 초안 사양의 일부이지만 일부 주요 / 모바일 / 이전 브라우저에서는 아직 지원되지 않을 수 있습니다. 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
);

견고성 참고 : document.body및 에서 검사하는 코드에서 document.documentElement일부 브라우저는이 중 하나를 반환하거나 null포커스가 없을 때입니다.

<body>(또는 아마도 <html>) tabIndex속성 이 있었는지 실제로 초점을 맞출 수 있는지에 대해서는 설명하지 않습니다 . 라이브러리 나 무언가를 작성하고 있고 강력하게하려면, 어떻게 든 처리해야합니다.


여기 에 집중 요소를 얻는 ( 따옴표) "한 줄짜리"버전이 있습니다. 단락에 대해 알아야하기 때문에 개념적으로 더 복잡 합니다. 읽을 수 있기를 원합니다.
나는 이것을 추천하지 않을 것이다. 그러나 당신이 1337 hax0r이라면, idk ... 거기 있습니다. 경우에 따라 신경 쓰지 않아도 부품
을 제거 할 수도 있습니다. (당신은 여전히 얻을 수 있는 경우 입니다 ) :|| nullfalsenulldocument.activeElementnull

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"'을 사용하여 포커스 가능한 요소를 설정할 수 있습니다. 없는.
Manfred

사용하지 않으려면 내 대답을보십시오 querySelector: stackoverflow.com/a/40873560/2624876
1j01

10

Joel S가 사용하는 접근 방식이 마음에 들었지만의 단순함도 좋아합니다 document.activeElement. jQuery를 사용하여 두 가지를 결합했습니다. 지원하지 않는 이전 브라우저 는 'hasFocus'값을 저장하는 데 document.activeElement사용 jQuery.data()됩니다. 최신 브라우저는를 사용 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")있습니까?
Pylinux

나는 그것이 가능하다고 생각합니다. 나는 오래 전에 이것을 썼고 5 년이 지난 지금 더 나은 솔루션을 다시 방문 할 이유가 없었습니다. 사용해보십시오! 그냥 똑같이 할 수도 있습니다. 우리 사이트의 플러그인이 적습니다! :)
Jason

10

Mootools에서 이러한 목적으로 사용한 작은 도우미 :

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 페이지에 존재해야합니다. 다음은 포커스가있는 요소에 ID를 할당했다고 가정 한 예입니다.

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

1
this.id대신 (항상?) 대신 $(this).attr('id')또는 적어도 (jQuery 객체가 이미있는 경우 ) 사용해야 합니다 $(this)[0].id. 이 레벨의 기본 Javascript는 더 빠르고 효율적입니다. 이 경우에는 눈에 띄지 않지만 시스템 전체에 차이가 있음을 알 수 있습니다.
Martijn

7

의 인스턴스 인 객체를 얻으려면을 Element사용해야 document.activeElement하지만의 인스턴스 인 객체를 얻으려면 Text을 사용해야 document.getSelection().focusNode합니다.

도움이 되길 바랍니다.


어떤면에서 더 좋습니까?
1j01

브라우저 관리자를 열고 페이지의 아무 곳이나 클릭 한 후 document.getSelection().focusNode.parentElementEnter를 탭하십시오. 그 후, 과거 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

2
문제는 현재 어떤 요소에 초점이 있는지를 묻는 것입니다. 그리고 focusNode텍스트 노드도 보장되지 않습니다.
1j01

6

document.activeElement를 사용하는 데 잠재적 인 문제가 있습니다. 치다:

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

사용자가 inner-div에 초점을 맞추더라도 document.activeElement는 여전히 외부 div를 참조합니다. 내부 div 중 어떤 것이 포커스를 가지고 있는지 확인하기 위해 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가있는 경우 document.activeElement를 지원하지 않는 브라우저가있는 경우 모든 포커스 이벤트에서 매우 간단한 것으로 채울 수 있어야합니다 (브라우저가 해당 기준을 충족하지 않는 한) ) :

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 애드온을 사용하여 화살표 키, 탭 및 입력에 대한 키보드 이벤트를 트랩하고 입력 요소를 클릭하기위한 이벤트 처리기를 만들었습니다.

그런 다음 포커스가 변경 될 때마다 activeInputArea를 조정 했으므로 해당 속성을 사용하여 내가있는 곳을 찾을 수 있습니다.

시스템에 버그가 있고 초점이 생각하는 곳에 있지 않으면 올바른 초점을 복원하기가 매우 어렵 기 때문에 이것을 망가 뜨리는 것은 쉽습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.