Programing

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

lottogame 2020. 5. 29. 07:53
반응형

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


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

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

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

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

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

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

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

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


흠 ... 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은 클릭 한 버튼 (탭 대 탭) 에 초점을 맞추지 않는다는 경고가 있습니다.


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 ) 까지 지원하지 않습니다 .


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

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

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


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

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

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

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


또한 특정 요소를 클릭하고 작동하는 솔루션이있는 경우 자동 완성 기능이 흐려짐을 무시하도록 노력하고 있지만 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 문제를 해결할 수 없다면 해결책을 따를 것입니다.


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

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

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

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

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


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

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>

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


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

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

  • document.activeElement는 상위 노드 일 수 있습니다 (예 : 대상에서 다른 대상으로 임시 단계 전환 중이므로 본문 노드). 따라서 범위에 사용할 수 없습니다
  • ev.explicitOriginalTarget is not always valued

So the best way is to use onclick on body event for understanding indirectly your node(event.target) is on blur


Edit: A hacky way to do it would be to create a variable that keeps track of focus for every element you care about. So, if you care that 'myInput' lost focus, set a variable to it on focus.

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

Original Answer: You can pass 'this' to the function.

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

I suggest using global variables blurfrom and blurto. Then, configure all elements you care about to assign their position in the DOM to the variable blurfrom when they lose focus. Additionally, configure them so that gaining focus sets the variable blurto to their position in the DOM. Then, you could use another function altogether to analyze the blurfrom and blurto data.


keep in mind, that the solution with explicitOriginalTarget does not work for text-input-to-text-input jumps.

try to replace buttons with the following text-inputs and you will see the difference:

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

I've been playing with this same feature and found out that FF, IE, Chrome and Opera have the ability to provide the source element of an event. I haven't tested Safari but my guess is it might have something similar.

$('#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;
    }
    //...
});

I do not like using timeout when coding javascript so I would do it the opposite way of Michiel Borkent. (Did not try the code behind but you should get the idea).

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

In the head something like that

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

You can fix IE with :

 event.currentTarget.firstChild.ownerDocument.activeElement

It looks like "explicitOriginalTarget" for FF.

Antoine And J


I wrote an alternative solution how to make any element focusable and "blurable".

It's based on making an element as contentEditable and hiding visually it and disabling edit mode itself:

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

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

DEMO

Note: Tested in Chrome, Firefox, and Safari (OS X). Not sure about IE.


Related: I was searching for a solution for VueJs, so for those who interested/curious how to implement such functionality using Vue Focusable directive, please take a look.


Works in Google Chrome v66.x, Mozilla v59.x and Microsoft Edge... Solution with jQuery.

I test in Internet Explorer 9 and not supported.

$("#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
     }
});

Comment your test in others internet explorer versions.


I see only hacks in the answers, but there's actually a builtin solution very easy to use : Basically you can capture the focus element like this:

const focusedElement = document.activeElement

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


This way:

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

Or if you attach the listener via JavaScript (jQuery in this example):

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

Edit: sorry. I misread the question.



I think its easily possible via jquery by passing the reference of the field causing the onblur event in "this".
For e.g.

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

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

Thanks
Monika


You could make it like this:

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

참고URL : https://stackoverflow.com/questions/121499/when-a-blur-event-occurs-how-can-i-find-out-which-element-focus-went-to

반응형