jQuery를 사용하여 입력에 초점이 있는지 테스트


561

내가 만들고있는 사이트의 첫 페이지에서 여러 사람들 <div>이 CSS :hover유사 클래스를 사용 하여 마우스가 위에있을 때 테두리를 추가합니다. 의 하나 <div>s는 포함되어 <form>그 안에 입력 포커스가있는 경우 국경을 유지할 jQuery를 사용하는. IE6가 s :hover이외 <a>의 요소를 지원하지 않는 것을 제외하고는 완벽하게 작동합니다 . 따라서이 브라우저에서만 jQuery를 :hover사용하여 $(#element).hover()메소드를 사용하여 CSS를 모방 합니다 . 유일한 문제는 이제 jQuery가 양식 focus() hover() 입력 포커스가 다음에 사용자가 아웃 마우스를 이동 경계는 사라진다.

나는 우리가 이런 행동을 막기 위해 어떤 조건을 사용할 수 있다고 생각했습니다. 예를 들어, 입력 중 하나에 포커스가 있으면 마우스 출력을 테스트 한 경우 테두리가 사라지는 것을 막을 수 있습니다. AFAIK, :focusjQuery 에는 선택기가 없으므로이 방법을 잘 모르겠습니다. 어떤 아이디어?


1
필요한 내용과 내가 무슨 일이 일어나고 있는지 몇 문장으로 정리해 볼 수 있습니까?
mkoryak 2016 년

포커스 및 블러 이벤트 캡처 ( docs.jquery.com/Events/focusdocs.jquery.com/Events/blur ) 를 조사해야한다고 생각합니다.
Wolfr

관련 질문에 대한 답변을 게시했습니다. "JavaScript (또는 jQuery)에 '초점이 있습니까?' . 나는 [gnarf에 의해 인용 된 클레프 접근법] (# 2684561)을 향상시켰다.
luiggitama

답변:


928

jQuery 1.6 이상

jQuery는 :focus선택기를 추가하여 더 이상 직접 선택할 필요가 없습니다. 그냥 사용$("..").is(":focus")

jQuery 1.5 이하

편집 : 시간 이 지남에 따라 초점을 테스트하는 더 좋은 방법을 찾았습니다 .Ben Alman의 요점다음과 같습니다.

jQuery.expr[':'].focus = function( elem ) {
  return elem === document.activeElement && ( elem.type || elem.href );
};

Mathias Bynens 에서 인용 : 여기

점을 유의 (elem.type || elem.href)테스트가 몸과 같은 잘못된 반응에서 필터에 추가되었습니다. 이런 식으로 양식 컨트롤과 하이퍼 링크를 제외한 모든 요소를 ​​필터링해야합니다.

새로운 선택기를 정의하고 있습니다. 플러그인 / 작성을 참조하십시오 . 그럼 당신은 할 수 있습니다 :

if ($("...").is(":focus")) {
  ...
}

또는:

$("input:focus").doStuff();

모든 jQuery

어떤 요소에 초점이 있는지 파악하고 싶다면

$(document.activeElement)

버전이 1.6 이하인지 확실하지 않은 경우 :focus선택기가없는 경우 선택기를 추가 할 수 있습니다 .

(function ( $ ) {
    var filters = $.expr[":"];
    if ( !filters.focus ) { 
        filters.focus = function( elem ) {
           return elem === document.activeElement && ( elem.type || elem.href );
        };
    }
})( jQuery );

4
이로 인해 오 탐지가 발생할 수 있습니다. 자세한 내용은 stackoverflow.com/questions/967096/… 을 참조하십시오 (Ben Alman 및 Diego Perini 덕분에).
Mathias Bynens

@Mathias Bynens-업데이트 주셔서 감사합니다 (이 커뮤니티 위키 답변 btw를 편집하는 것을 환영합니다!)
gnarf

1.5와 1.6에서 모두 작동하기 위해 필요한 경우는 어떻습니까? jQuery 자체 포커스 선택기를 재정의하고 싶지 않습니다. 같은 것 if (!jQuery.expr[':'].focus) { /* gist from Ben Alman */ }?
Betamos

@betamos-정확히 맞습니다 ... 그것을 반영하기 위해 답변에 무언가를 추가 할 것입니다.
gnarf

2
@ 알렉스는 - 때문에 지금까지 내가 말할 수있는 바와 같이, jsFiddle 문제를 보여주는 감소 된 테스트 케이스를 제공하십시오,이 이유가없는 "동적"요소에 대한 작업. 나는 shenanigans라고 부른다.
gnarf

46

CSS :

.focus {
    border-color:red;
}

jQuery :

  $(document).ready(function() {

    $('input').blur(function() {
        $('input').removeClass("focus");
      })
      .focus(function() {
        $(this).addClass("focus")
      });
  });

22

현재 받아 들여지는 것보다 더 강력한 답변이 있습니다.

jQuery.expr[':'].focus = function(elem) {
  return elem === document.activeElement && (elem.type || elem.href);
};

다음 (elem.type || elem.href)과 같은 오 탐지를 필터링하기 위해 테스트가 추가되었습니다.body . 이런 식으로 양식 컨트롤과 하이퍼 링크를 제외한 모든 요소를 ​​필터링해야합니다.

(에서 촬영 이 요점 에 의해 벤 독일어 .)


13

2015 년 4 월 업데이트

이 질문은 오래 전부터 있었으며 몇 가지 새로운 규칙이 적용되었으므로 .live 적용되었으므로 방법이 감가 상각되었다고 .

그 자리에서 .on 방법이 도입되었습니다.

그들의 문서 는 그것이 어떻게 작동하는지 설명하는데 매우 유용합니다;

.on () 메소드는 이벤트 핸들러를 jQuery 객체에서 현재 선택된 요소 세트에 연결합니다. jQuery 1.7부터 .on () 메소드는 이벤트 핸들러를 첨부하는 데 필요한 모든 기능을 제공합니다. 이전 jQuery 이벤트 메소드에서 변환하는 데 도움이 필요하면 .bind (), .delegate () 및 .live ()를 참조하십시오.

따라서 '입력 중심'이벤트를 대상으로하기 위해이를 스크립트에서 사용할 수 있습니다. 다음과 같은 것 :

$('input').on("focus", function(){
   //do some stuff
});

이것은 매우 강력하며 TAB 키도 사용할 수 있습니다.


2

나는 당신이 무엇을하고 있는지 확실하지 않지만 입력 요소 (또는 div?)의 상태를 변수로 저장하여 얻을 수있는 것처럼 들립니다.

$('div').each(function(){

    var childInputHasFocus = false;

    $(this).hover(function(){
        if (childInputHasFocus) {
            // do something
        } else { }
    }, function() {
        if (childInputHasFocus) {
            // do something
        } else { }
    });

    $('input', this)
        .focus(function(){
            childInputHasFocus = true;
        })
        .blur(function(){
            childInputHasFocus = false;
        });
});

이것이 내가 한 일이지만 글로벌 자바 스크립트 변수가 아닌 임의의 CSS 클래스를 사용했습니다.
bloudermilk

나는 이것의 변형을 사용했다. 새로운 jQuery 플러그인이 필요하지 않습니다. 그로 인해 나는 행복한 캠프가됩니다!
Dennis Day

1

클래스를 사용하여 요소의 상태를 표시하는 대안은 내부 데이터 저장소 기능 입니다.

추신 : 부울과 data()함수를 사용하여 원하는 것을 저장할 수 있습니다. 그것은 단지 문자열에 관한 것이 아닙니다 :)

$("...").mouseover(function ()
{
    // store state on element
}).mouseout(function ()
{
    // remove stored state on element
});

그리고 그것은 요소의 상태에 접근하는 문제입니다.



1

이것을 시뮬레이션하기 위해 mouseOvermouseOut 사용에 대해 생각해 보셨습니까? mouseEntermouseLeave 도 살펴보십시오


그것이 본질적으로 jQuery의 호버로하는 일입니다. 마우스 입력과 마우스 출력을위한 두 가지 기능을 제공합니다.
bloudermilk 2016 년

0

두 상태 (마우스 오버, 포커스)를 true / false 플래그로 추적하고 하나가 변경 될 때마다 둘 다 false 인 경우 테두리를 제거하는 기능을 실행하고 그렇지 않으면 테두리를 표시합니다.

따라서 onfocus는 포커스가 설정되어 있고 true이면 onblur가 포커스가 설정되어 있습니다. onmouseover 세트가 가리키면 = true, onmouseout 세트가 가리키고 = false. 이러한 각 이벤트 후에 테두리를 추가 / 제거하는 기능을 실행하십시오.


0

내가 아는 한 화면의 입력에 포커스가 있는지 브라우저에 요청할 수 없으므로 일종의 포커스 추적을 설정해야합니다.

나는 보통 "noFocus"라는 변수를 가지고 있으며 true로 설정합니다. 그런 다음 noFocus를 false로 만드는 모든 입력에 포커스 이벤트를 추가합니다. 그런 다음 noFocus를 다시 true로 설정하는 모든 입력에 흐림 이벤트를 추가합니다.

나는 이것을 매우 쉽게 처리하는 MooTools 클래스를 가지고 있으며, 동일한 작업을 수행하기 위해 jquery 플러그인을 만들 수 있다고 확신합니다.

일단 생성되면 경계 스와핑을 수행하기 전에 noFocus를 확인할 수 있습니다.



0

요소가 집중되어 있는지 확인하는 플러그인이 있습니다 : http://plugins.jquery.com/project/focused

$('input').each(function(){
   if ($(this) == $.focused()) {
      $(this).addClass('focused');
   }
})

1
핵심 jquery를 사용할 수 있는데 왜 플러그인을 사용합니까?
Marcy Sutton

1
네 말이 맞아 그러나 나는 2 년 전이 문제에 대한 해결책을 몰랐습니다.
Murat Çorlu

0

텍스트 입력 내용을 select () (강조 표시)로 설정된 .live ( "focus") 이벤트가 있으므로 사용자가 새 값을 입력하기 전에 선택할 필요가 없습니다.

$ (formObj) .select ();

서로 다른 브라우저 사이의 단점으로 인해 선택으로 인해 클릭이 발생하여 대체 될 수 있으며 텍스트 필드 내에 커서를 놓는 즉시 콘텐츠를 선택 취소합니다 (FF에서는 대부분 작동했지만 IE에서는 실패했습니다)

나는 선택에 약간의 지연을 두어 이것을 해결할 수 있다고 생각했다 ...

setTimeout (function () {$ (formObj) .select ();}, 200);

이것은 잘 작동하고 선택은 지속되지만 재미있는 문제가 발생했습니다. 한 필드에서 다음 필드로 탭한 경우 선택이 발생하기 전에 초점이 다음 필드로 전환됩니다. select가 포커스를 훔치기 때문에 포커스는 되돌아 가서 새로운 "포커스"이벤트를 트리거합니다. 이것은 일련의 입력 선택이 화면 전체에서 춤을 추게되었습니다.

실행 가능한 솔루션은 select ()를 실행하기 전에 필드에 여전히 초점이 있는지 확인하는 것이지만 언급 한 바와 같이 간단한 확인 방법은 없습니다. 서브 루틴으로 가득 찬 거대한 함수에 대한 단일 jQuery select () 호출 ...


0

내가 한 일은 jQuery focus () 함수 내에서 추가되고 제거되는 .elementhasfocus라는 임의의 클래스를 만드는 것입니다. 마우스 오버시 hover () 함수가 실행될 때 .element의 포커스가 있는지 확인합니다.

if(!$("#quotebox").is(".boxhasfocus")) $(this).removeClass("box_border");

따라서 해당 클래스가없는 경우 (읽기 : div 내에 요소가 포커스가 없음) 테두리가 제거됩니다. 그렇지 않으면 아무 일도 일어나지 않습니다.


-2

단순한

 <input type="text" /> 



 <script>
     $("input").focusin(function() {

    alert("I am in Focus");

     });
 </script>

현재 어떤 요소가 현재 초점을 맞추고 있는지 알려주지 않습니다. 새로운 요소가 포커스를 얻었을 때 호출됩니다. 따라서 요소에 이미 초점이 있고 'this'가 하나인지 여부를 알고 싶다면이 코드는 쓸모가 없습니다.
Alexis Wilke
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.