'블러'이벤트가 발생하면 어떤 요소 포커스가 *로 * 이동했는지 어떻게 알 수 있습니까?


187

다음 blur과 같이 HTML 입력 상자에 함수를 연결한다고 가정 하십시오.

<input id="myInput" onblur="function() { ... }"></input>

blur함수 내에서 이벤트를 발생시킨 요소 (클릭 한 요소) 의 ID를 얻는 방법이 있습니까? 어떻게?

예를 들어 다음과 같은 범위가 있다고 가정하십시오.

<span id="mySpan">Hello World</span>

입력 요소에 포커스가있는 직후 범위를 클릭하면 입력 요소의 포커스가 사라집니다. 함수 mySpan는 클릭 된 것을 어떻게 알 수 있습니까?

추신 : 입력 요소의 onblur 이벤트 전에 span의 onclick 이벤트가 발생하면 특정 요소가 클릭되었음을 나타내는 일부 상태 값을 설정할 수 있기 때문에 문제가 해결됩니다.

PPS :이 문제의 배경은 blur입력 요소 의 이벤트로 인해 제안이 즉시 사라지지 않고 AJAX 자동 완성 컨트롤을 외부에서 (클릭 가능한 요소에서) 트리거하여 제안을 표시하려고한다는 것 입니다. 따라서 blur하나의 특정 요소를 클릭했는지 기능 을 확인 하고, 그렇다면 블러 이벤트를 무시하십시오.


이것은 추론을 뒷받침하고 싶은 흥미로운 질문입니다. 즉, 왜이 일을하고 있습니까? 문맥은 무엇입니까?
Rahul

Rahul과 roosteronacid, 나는 당신의 의견 (PPS)에 대한 반응으로 질문을 업데이트했습니다.
Michiel Borkent

1
이 정보가 약간 오래
Jonathan M

답변:


86

흠 ... Firefox에서는 explicitOriginalTarget클릭 한 요소를 끌어 오는 데 사용할 수 있습니다 . toElementIE에서도 똑같이 할 것으로 예상 했지만 작동하지 않는 것 같습니다 ...하지만 문서에서 새로 초점을 맞춘 요소를 가져올 수 있습니다.

function showBlur(ev)
{
   var target = ev.explicitOriginalTarget||document.activeElement;
   document.getElementById("focused").value = 
      target ? target.id||target.tagName||target : '';
}

...

<button id="btn1" onblur="showBlur(event)">Button 1</button>
<button id="btn2" onblur="showBlur(event)">Button 2</button>
<button id="btn3" onblur="showBlur(event)">Button 3</button>
<input id="focused" type="text" disabled="disabled" />

주의해야 할 점은 : 이 기술은 않습니다 하지 초점을위한 작업으로 인한 변경됩니다 탭 이동 키보드를 사용하여 필드를 통해, 그리고 크롬이나 사파리에서 전혀 일을하지 않습니다. 사용하는 데 큰 문제 activeElement(IE를 제외하고는)가 지속적으로 될 때까지 갱신되지 않는다는 blur 이벤트가 처리되고, 처리 기간 동안 전혀 유효한 값을 갖지 않을 수! 이것은 Michiel이 다음을 사용하여 끝내는 기술 의 변형으로 완화 될 수 있습니다 .

function showBlur(ev)
{
  // Use timeout to delay examination of activeElement until after blur/focus 
  // events have been processed.
  setTimeout(function()
  {
    var target = document.activeElement;
    document.getElementById("focused").value = 
      target ? target.id||target.tagName||target : '';
  }, 1);
}

이것은 대부분의 최신 브라우저 (Chrome, IE 및 Firefox에서 테스트 됨)에서 작동하며 Chrome은 클릭 한 버튼 (탭 대 탭) 에 초점을 맞추지 않는다는 경고가 있습니다.


1
나는 explicitOriginalTarget과 같은 것을 오랫동안 찾고 있습니다. 어떻게 알게 되었습니까?
Kev

3
FireBug에서 이벤트 객체를 검사했습니다. FWIW이 있으며,이 건물은 모질라 별, 그리고 MDC에 문서화 : developer.mozilla.org/en/DOM/event.explicitOriginalTarget
Shog9

2
Firefox 3.6에서는 작동하지 않거나 작동이 중지 되었습니까? Windows에서는 Safari 4.0.3입니다.
Chetan S

1
@Jonathan : 속성을 사용할 수 있지만 blur이벤트가 발생할 때 업데이트되지 않습니다 . 자세한 내용으로 답변을 업데이트했습니다. Chrome 또는 Firefox에서 activeElement를 사용해 보셨습니까? 그것은 당신에게 요소를 흐리게합니다 ...
Shog9

1
실제로 FF 31에서는 작동하지 않습니다. explicitOriginalTarget은 현재 흐림 대상을 표시하고, document.activeElement는 흐림 이벤트에서 null입니다.
Adrian Maire

75

2015 답변 : UI Events 에 따르면 이벤트relatedTarget속성을 사용할 수 있습니다 .

EventTarget이벤트 유형에 따라 포커스 이벤트와 관련된 보조를 식별하는 데 사용됩니다 .

대한 blur이벤트

relatedTarget: 이벤트 대상 수신 초점.

예:

function blurListener(event) {
  event.target.className = 'blurred';
  if(event.relatedTarget)
    event.relatedTarget.className = 'focused';
}
[].forEach.call(document.querySelectorAll('input'), function(el) {
  el.addEventListener('blur', blurListener, false);
});
.blurred { background: orange }
.focused { background: lime }
<p>Blurred elements will become orange.</p>
<p>Focused elements should become lime.</p>
<input /><input /><input />

참고 Firefox는 relatedTarget버전 48 ( 버그 962251 , MDN ) 까지 지원하지 않습니다 .


Firefox는 지원하지 않지만 티켓이 있습니다 : bugzilla.mozilla.org/show_bug.cgi?id=687787
sandstrom

3
지금이 있습니다. 여기를 참조 하십시오 .
rplaurindo

이제 모든 것이 많이 ^ _ ^ 쉽게, 웹 커뮤니티를 사랑
am05mhz가

6
훌륭한 솔루션. 불행히도, 대상 수신 포커스가 입력 요소가 아닌 경우 relatedTarget반환 null합니다.
Pedro Hoehl Carvalho

5
포커스 요소 수신이 입력 요소가 아닌 경우 tabIndex="0"속성을 추가 하면 작동합니다.
Dany

19

나는 결국 onblur 이벤트 시간 초과로 해결했습니다 (StackOverflow가 아닌 ​​친구의 조언 덕분에).

<input id="myInput" onblur="setTimeout(function() {alert(clickSrc);},200);"></input>
<span onclick="clickSrc='mySpan';" id="mySpan">Hello World</span>

FF와 IE에서 모두 작동합니다.


9
이것이 자바 스크립트 세계에서 나쁜 습관으로 간주됩니까?
Michiel Borkent

1
오래된 게시물이지만 같은 질문이 있습니다. 상관없이, 브라우저 간 작업을 수행하는 유일한 방법입니다.
joshs

이 답변은 다른 문제를 해결함으로써 내 TON을 도왔습니다 ... 감사합니다 마이클!
Alex

@ MichielBorkent 이벤트 중심이 아니기 때문에 나쁜 구현입니다. 당신은 주어진 시간 동안 기다렸다가 충분히 길기를 바랍니다. 더 오래 기다릴수록 더 안전 해지지 만 오래 기다릴 필요가 없으면 더 많은 시간을 낭비하게됩니다. 어쩌면 누군가 오래되었거나 느린 장치에 있고이 시간이 충분하지 않을 수 있습니다. 불행히도 나는 이벤트가 FireFox에서 iframe을 클릭했는지 여부를 결정하는 데 필요한 것을 제공하지 않기 때문에 여기에 있지만 다른 모든 브라우저에서도 작동합니다. 비록 나쁜 습관이긴하지만 지금이 방법을 사용하고 싶습니다.
CTS_AE

1
이 질문은 꽤 오래되어 2008 년으로 거슬러 올라갑니다. 한편 더 나은 접근 방식이있을 수 있습니다. 2015 년 답변을 시도해 볼 수 있습니까?
Michiel Borkent

16

흐림 대신 문서의 mousedown 이벤트를 사용할 수 있습니다.

$(document).mousedown(function(){
  if ($(event.target).attr("id") == "mySpan") {
    // some process
  }
});

8

유형 FocusEvent인스턴스에는 relatedTargetFF의 버전 47까지 속성이 있습니다. 특히이 속성은 이미 작동하는 48 개에서 null을 리턴합니다.

더 자세한 내용은 여기 를 참조 하십시오 .


2

또한 특정 요소를 클릭하고 작동하는 솔루션이있는 경우 자동 완성 기능이 흐려짐을 무시하도록 노력하고 있지만 explicitOriginalTarget으로 인해 Firefox에서만

Autocompleter.Base.prototype.onBlur = Autocompleter.Base.prototype.onBlur.wrap( 
        function(origfunc, ev) {
            if ($(this.options.ignoreBlurEventElement)) {
                var newTargetElement = (ev.explicitOriginalTarget.nodeType == 3 ? ev.explicitOriginalTarget.parentNode : ev.explicitOriginalTarget);
                if (!newTargetElement.descendantOf($(this.options.ignoreBlurEventElement))) {
                    return origfunc(ev);
                }
            }
        }
    );

이 코드는 Autocompleter의 기본 onBlur 메소드를 래핑하고 ignoreBlurEventElement 매개 변수가 설정되어 있는지 확인합니다. 설정된 경우 클릭 한 요소가 ignoreBlurEventElement인지 여부를 확인합니다. 이 경우 Autocompleter는 onBlur를 계산하지 않고 onBlur를 호출합니다. explicitOriginalTarget 속성이 Mozilla 전용이기 때문에 Firefox에서만 작동한다는 점이 유일한 문제입니다. 이제 explicitOriginalTarget을 사용하는 것과 다른 방법을 찾으려고합니다. 언급 한 솔루션을 사용하려면 클릭 동작을 요소에 수동으로 추가해야합니다. explicitOriginalTarget 문제를 해결할 수 없다면 해결책을 따를 것입니다.


2

확인중인 내용과 시간을 되돌릴 수 있습니까? 마지막으로 흐려진 부분을 기억하는 경우입니다.

<input id="myInput" onblur="lastBlurred=this;"></input>

그런 다음 span의 onClick에서 두 객체로 function ()을 호출하십시오.

<span id="mySpan" onClick="function(lastBlurred, this);">Hello World</span>

그러면 함수가 Ajax.AutoCompleter 컨트롤을 트리거할지 여부를 결정할 수 있습니다. 이 함수에는 클릭 한 오브젝트 흐릿한 오브젝트가 있습니다. onBlur가 이미 발생 했으므로 제안이 사라지지 않습니다.


1

다음과 같이 사용하십시오 :

var myVar = null;

그런 다음 함수 내부에서 :

myVar = fldID;

그리고:

setTimeout(setFocus,1000)

그리고:

function setFocus(){ document.getElementById(fldID).focus(); }

최종 코드 :

<html>
<head>
    <script type="text/javascript">
        function somefunction(){
            var myVar = null;

            myVar = document.getElementById('myInput');

            if(myVar.value=='')
                setTimeout(setFocusOnJobTitle,1000);
            else
                myVar.value='Success';
        }
        function setFocusOnJobTitle(){
            document.getElementById('myInput').focus();
        }
    </script>
</head>
<body>
<label id="jobTitleId" for="myInput">Job Title</label>
<input id="myInput" onblur="somefunction();"></input>
</body>
</html>

1

IE에서는 사용할 수 window.event.toElement없지만 가능하지는 않지만 파이어 폭스에서는 작동 하지 않습니다 !


Chrome 또는 Safari에서는 작동하지 않습니다. 표준과 호환되는 새로운 버전의 IE에서는 작동하지 않을 수 있습니다.
robocat

1

이 답변 에서 언급했듯이 의 값을 확인할 수 있습니다 document.activeElement. document는 전역 변수이므로 onBlur 핸들러에서 사용하기 위해 마법을 사용할 필요가 없습니다.

function myOnBlur(e) {
  if(document.activeElement ===
       document.getElementById('elementToCheckForFocus')) {
    // Focus went where we expected!
    // ...
  }
}

1
  • document.activeElement는 상위 노드 일 수 있습니다 (예 : 대상에서 다른 대상으로 임시 단계 전환 중이므로 본문 노드). 따라서 범위에 사용할 수 없습니다
  • ev.explicitOriginalTarget이 항상 가치있는 것은 아닙니다

따라서 가장 좋은 방법은 onclick on body 이벤트를 사용하여 간접적으로 노드 (event.target)가 흐릿하다는 것을 이해하는 것입니다


1

jQuery가 포함 된 Chrome v66.x, Mozilla v59.x 및 Microsoft Edge ... 솔루션에서 작동합니다.

Internet Explorer 9에서 테스트했지만 지원되지 않습니다.

$("#YourElement").blur(function(e){
     var InputTarget =  $(e.relatedTarget).attr("id"); // GET ID Element
     console.log(InputTarget);
     if(target == "YourId") { // If you want validate or make a action to specfic element
          ... // your code
     }
});

다른 인터넷 익스플로러 버전에서 테스트에 주석을 답니다.


0

편집 : 해킹하는 방법은 관심있는 모든 요소에 대한 초점을 추적하는 변수를 만드는 것입니다. 따라서 'myInput'이 포커스를 잃어 버렸다고 생각하면 포커스에 변수를 설정하십시오.

<script type="text/javascript">
   var lastFocusedElement;
</script>
<input id="myInput" onFocus="lastFocusedElement=this;" />

원래 답변 : 'this'를 함수에 전달할 수 있습니다.

<input id="myInput" onblur="function(this){
   var theId = this.id; // will be 'myInput'
}" />

이것은 질문에 대한 답이 아니기 때문에 추가 예제를 통해 더 명확하게 설명했으면합니다.
Michiel Borkent

0

전역 변수 blurfrom 및 blurto를 사용하는 것이 좋습니다. 그런 다음 초점을 잃을 때 DOM에서 해당 위치를 변수 blurfrom에 할당하도록 관심있는 모든 요소를 ​​구성하십시오. 또한, 구성 그들을 그렇게 초점을 얻는 것은에 변수 blurto 설정한다는 그들의 는 DOM에 위치. 그런 다음 다른 기능을 사용하여 흐림 및 흐림 데이터를 분석 할 수 있습니다.


그것은 거의 해결책이지만 onblur 이벤트 핸들러에서는 이미 어떤 항목이 클릭되었는지 알고 있어야했기 때문에 onblur의 시간 초과가 나를 위해했습니다.
Michiel Borkent

0

explicitOriginalTarget을 사용하는 솔루션은 텍스트 입력에서 텍스트 입력으로 점프 할 수 없습니다.

버튼을 다음과 같은 텍스트 입력으로 바꾸면 차이가 나타납니다.

<input id="btn1" onblur="showBlur(event)" value="text1">
<input id="btn2" onblur="showBlur(event)" value="text2">
<input id="btn3" onblur="showBlur(event)" value="text3">

0

나는이 동일한 기능을 가지고 놀고 FF, IE, Chrome 및 Opera가 이벤트의 소스 요소를 제공 할 수 있음을 발견했습니다. Safari를 테스트하지는 않았지만 비슷한 것이있을 수 있습니다.

$('#Form').keyup(function (e) {
    var ctrl = null;
    if (e.originalEvent.explicitOriginalTarget) { // FF
        ctrl = e.originalEvent.explicitOriginalTarget;
    }
    else if (e.originalEvent.srcElement) { // IE, Chrome and Opera
        ctrl = e.originalEvent.srcElement;
    }
    //...
});

이 다운 보팅이 왜 잘 작동합니까? originalEvent를 제거하십시오!
fekiri malek

0

나는 자바 스크립트를 코딩 할 때 타임 아웃을 사용하는 것을 좋아하지 않기 때문에 Michiel Borkent의 반대 방식으로 할 것입니다. (코드를 숨기지 않았지만 아이디어를 얻어야합니다).

<input id="myInput" onblur="blured = this.id;"></input>
<span onfocus = "sortOfCallback(this.id)" id="mySpan">Hello World</span>

머리에 그런 것

<head>
    <script type="text/javascript">
        function sortOfCallback(id){
            bluredElement = document.getElementById(blured);
            // Do whatever you want on the blured element with the id of the focus element


        }

    </script>
</head>

0

다음과 같이 IE를 수정할 수 있습니다.

 event.currentTarget.firstChild.ownerDocument.activeElement

FF의 경우 "explicitOriginalTarget"처럼 보입니다.

앙투안과 제이


0

대체 솔루션을 작성했습니다 어떤 요소에 초점을 맞추고 "흐리게"만드는 방법을 .

요소를 contentEditable시각적으로 숨기고 편집 모드 자체를 비활성화 하는 것을 기반 으로합니다.

el.addEventListener("keydown", function(e) {
  e.preventDefault();
  e.stopPropagation();
});

el.addEventListener("blur", cbBlur);
el.contentEditable = true;

데모

참고 : Chrome, Firefox 및 Safari (OS X)에서 테스트되었습니다. IE에 대해 잘 모르겠습니다.


관련 : VueJs에 대한 솔루션을 찾고 있었으므로 Vue Focusable 지시문을 사용하여 이러한 기능을 구현하는 방법에 관심이 있거나 궁금한 사람들 은 살펴보십시오 .


-2

이 방법:

<script type="text/javascript">
    function yourFunction(element) {
        alert(element);
    }
</script>
<input id="myinput" onblur="yourFunction(this)">

또는 JavaScript를 통해 리스너를 연결하는 경우 (이 예제에서는 jQuery) :

var input = $('#myinput').blur(function() {
    alert(this);
});

편집 : 죄송합니다. 질문을 잘못 읽었습니다.


3
이 질문에 대한 답변이 아니라는 것을 알고 잘못 읽은 경우 그에 따라 업데이트하거나 삭제하십시오.
TJ

-2


"this"에서 onblur 이벤트를 발생시키는 필드 참조를 전달하여 jquery를 통해 쉽게 가능하다고 생각합니다.
예를 들어

<input type="text" id="text1" onblur="showMessageOnOnblur(this)">

function showMessageOnOnblur(field){
    alert($(field).attr("id"));
}

감사합니다
Monika


-2

다음과 같이 만들 수 있습니다.

<script type="text/javascript">
function myFunction(thisElement) 
{
    document.getElementByName(thisElement)[0];
}
</script>
<input type="text" name="txtInput1" onBlur="myFunction(this.name)"/>

-2

답변에는 해킹 만 표시되지만 실제로 사용하기 매우 쉬운 내장 솔루션이 있습니다. 기본적으로 다음과 같이 초점 요소를 캡처 할 수 있습니다.

const focusedElement = document.activeElement

https://developer.mozilla.org/en-US/docs/Web/API/DocumentOrShadowRoot/activeElement


적어도 내 경우에는 activeElement가 본문이므로 작동하지 않습니다. 다음 렌더링 / 틱에서이를 확인하면 올바르게 설정됩니다. 그러나 진드기가 제대로 해킹 되었기 때문에 shog9의 솔루션이 유일한 적절한 솔루션 인 것 같습니다.
Mathijs Segers
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.