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

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

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

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



답변

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

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

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

관련된 링크들:


답변

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

document.activeElement

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


답변

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

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

$(":focus")

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


답변

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 테스트를 참조하십시오 .


답변

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;
});

비 이벤트 방식을 사용하여 초기 상태 가정을 수정할 수 있지만 대신 대신 사용할 수도 있습니다.


답변

document.activeElement<body>포커스 가능한 요소가없는 경우 기본적으로 요소로 설정 될 수 있습니다 . 또한 요소에 포커스가 있고 브라우저 창이 흐리게 표시 activeElement되면 계속해서 포커스가있는 요소를 유지합니다.

이 두 가지 동작 중 하나가 바람직하지 않은 경우 CSS 기반 접근 방식을 고려하십시오 document.querySelector( ':focus' ).


답변

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);