Kiedy wystąpi zdarzenie "rozmycie", Jak mogę dowiedzieć się, do którego elementu focus poszedł *?

Załóżmy, że dołączam funkcję blur do pola wejściowego HTML, takiego jak:

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

Czy istnieje sposób na uzyskanie identyfikatora elementu, który spowodował wywołanie zdarzenia blur (elementu, który został kliknięty) wewnątrz funkcji? Jak?

Na przykład, załóżmy, że mam taką rozpiętość:

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

Jeśli kliknę span zaraz po tym, jak element wejściowy zostanie ustawiony ostrość, element wejściowy straci swoją ostrość. Skąd funkcja wie, że to {[4] } było kliknąłeś?

PS: Jeśli zdarzenie onclick span wystąpiłoby przed zdarzeniem onblur elementu wejściowego, mój problem byłby rozwiązany, ponieważ mogłem ustawić jakąś wartość statusu wskazującą, że dany element został kliknięty.

PPS: tłem tego problemu jest to, że chcę uruchomić autouzupełnianie AJAX zewnętrznie (z klikalnego elementu), aby pokazać swoje sugestie, bez sugestii znikających natychmiast z powodu zdarzenia blur na elemencie wejściowym. Więc Ja chcesz sprawdzić w funkcji blur, czy jeden konkretny element został kliknięty, a jeśli tak, zignoruj Zdarzenie rozmycie.

Author: mikemaccana, 2008-09-23

23 answers

Hmm... W Firefoksie możesz użyć explicitOriginalTarget, aby wyciągnąć element, który został kliknięty. Spodziewałem się toElement zrobić to samo dla IE, ale to nie wydaje się działać... Można jednak wyciągnąć nowo skupiony element z dokumentu:

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

Zastrzeżenie: ta technika nie działa dla zmian ostrości spowodowanych przez tabulowanie przez pola za pomocą klawiatury, i nie działa w ogóle w Chrome lub Safari. Dużym problemem z używaniem activeElement (poza IE) jest to, że nie jest stale aktualizowana, dopóki po Zdarzenie blur nie zostało przetworzone i może nie mieć żadnej wartości podczas przetwarzania! Można to złagodzić wariacją na temat techniki, którą Michiel wykorzystał :

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

Powinno to działać w większości nowoczesnych przeglądarek (testowanych w Chrome, IE i Firefox), z zastrzeżeniem, że Chrome nie ustawia ostrości na przyciskach, które są kliknięte (vs.tabbed to).

 91
Author: Shog9,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:33:26

2015 odpowiedź : zgodnie z Ui Events, możesz użyć relatedTarget właściwość zdarzenia:

Używane do identyfikacji wtórnego EventTarget związane z fokusem Zdarzenie, w zależności od rodzaju zdarzenia.

Dla blur wydarzenia,

relatedTarget: cel zdarzenia otrzymujący fokus.

Przykład:

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

Uwaga Firefox nie obsługuje relatedTarget do wersji 48 (bug 962251, MDN ).

 84
Author: Oriol,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-23 11:20:55

Rozwiązałem to ostatecznie z timeoutem na wydarzeniu onblur (dzięki radom znajomego, który nie jest StackOverflow):

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

Działa zarówno w FF jak i IE.

 19
Author: Michiel Borkent,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-24 17:17:36

Możliwe jest użycie zdarzenia mousedown dokumentu zamiast rozmycia:

$(document).mousedown(function(){
  if ($(event.target).attr("id") == "mySpan") {
    // some process
  }
});
 16
Author: Evgeny Shmanev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-03 19:49:13

Instancje type FocusEvent mają atrybut relatedTarget, jednak do wersji 47 FF, W szczególności ten atrybut zwraca null, z 48 już działa.

Możesz zobaczyć więcej tutaj .

 8
Author: rplaurindo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-07 20:19:36

Staram się również, aby Autocompleter ignorował rozmycie, jeśli dany element kliknie i ma działające rozwiązanie, ale tylko dla Firefoksa ze względu na explicitOriginalTarget

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

Ten kod zawija domyślną metodę Onblur Autocompleter i sprawdza, czy parametry ignoreBlurEventElement są ustawione. jeśli jest ustawiony, sprawdza za każdym razem, czy kliknięty element jest ignoreBlurEventElement, czy nie. Jeśli tak, Autocompleter nie wywołuje onBlur, w przeciwnym razie wywołuje onBlur. Jedynym problemem jest to, że działa tylko w Firefoksie, ponieważ właściwość explicitOriginalTarget jest specyficzna dla Mozilli . Teraz staram się znaleźć inny sposób niż za pomocą explicitOriginalTarget. Rozwiązanie, o którym wspomniałeś, wymaga ręcznego dodania zachowania onclick do elementu. Jeśli nie uda mi się rozwiązać problemu explicitOriginalTarget, myślę, że podążę za twoim rozwiązaniem.

 2
Author: matte,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-07 10:56:06

Możesz cofnąć to, co sprawdzasz i kiedy? To jest, jeśli pamiętasz, co było ostatnio zamazane:

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

A następnie w onClick for your span wywołanie funkcji () z obu obiektów:

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

Twoja funkcja może wtedy zdecydować, czy uruchomić Ajax.Sterowanie autouzupełniaczem. Funkcja posiada obiekt kliknięty i obiekt rozmyty. OnBlur już się pojawił, więc nie sprawi, że sugestie znikną.

 2
Author: bmb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-17 17:05:55

Działa w Google Chrome v66.X, Mozilla v59.X i Microsoft Edge... Rozwiązanie z jQuery.

Testuję w Internet Explorer 9 i nie jest obsługiwany.

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

Skomentuj swój test w innych wersjach internet Explorera.

 2
Author: LuisEduardox,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-15 00:16:51

Użyj czegoś takiego:

var myVar = null;

A następnie wewnątrz funkcji:

myVar = fldID;

A następnie:

setTimeout(setFocus,1000)

A następnie:

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

Kod końcowy:

<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
Author: Vikas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-13 15:48:36

Myślę, że to niemożliwe, z IE można spróbować użyć window.event.toElement, ale nie działa z Firefoksem!

 1
Author: stefano m,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-04 19:12:14

Jak zaznaczono w tej odpowiedzi, możesz sprawdzić wartość document.activeElement. document jest zmienną globalną, więc nie musisz robić żadnej magii, aby użyć jej w swoim programie obsługi onBlur:

function myOnBlur(e) {
  if(document.activeElement ===
       document.getElementById('elementToCheckForFocus')) {
    // Focus went where we expected!
    // ...
  }
}
 1
Author: Kevin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:36
  • Dokument.activeElement może być węzłem nadrzędnym (na przykład węzłem ciała, ponieważ jest w fazie tymczasowej przełączającej się z celu na inny), więc nie jest użyteczny dla Twojego zakresu
  • ev.explicitOriginalTarget nie zawsze jest wartościowany

Więc najlepszym sposobem jest użycie onclick on body event do pośredniego zrozumienia węzła (event.target) jest na blur

 1
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-06 20:39:48

Edit: Hakerskim sposobem na to byłoby stworzenie zmiennej, która śledzi ostrość dla każdego elementu, na którym ci zależy. Tak więc, jeśli zależy ci na tym, że "myInput" stracił ostrość, Ustaw zmienną do niego na ostrość.

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

Oryginalna Odpowiedź: Możesz przekazać " to " do funkcji.

<input id="myInput" onblur="function(this){
   var theId = this.id; // will be 'myInput'
}" />
 0
Author: brock.holum,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-23 15:21:26

Sugeruję użycie zmiennych globalnych blurfrom i blurto. Następnie skonfiguruj wszystkie elementy, które chcesz przypisać ich pozycję w DOM do zmiennej blurfrom, gdy utracą ostrość. Dodatkowo skonfiguruj je tak, aby zyskanie ostrości ustawiało zmienną blurto na Ich pozycję w DOM. Następnie możesz użyć innej funkcji do analizy danych blurfrom i blurto.

 0
Author: stalepretzel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-23 23:40:42

Należy pamiętać, że rozwiązanie z explicitOriginalTarget nie działa dla skoków text-input-to-text-input.

Spróbuj zastąpić przyciski następującymi wejściami tekstowymi, a zobaczysz różnicę:

<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
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-03 22:06:35

Grałem z tą samą funkcją i dowiedziałem się, że FF, IE, Chrome i Opera mają możliwość dostarczenia elementu źródłowego zdarzenia. Nie testowałem Safari, ale wydaje mi się, że może mieć coś podobnego.

$('#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;
    }
    //...
});
 0
Author: EricDuWeb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-01 15:26:59

Nie lubię używać timeout podczas kodowania javascript, więc zrobiłbym to w odwrotny sposób Michiel Borkent. (Nie próbowałem kodu za, ale powinieneś dostać pomysł).

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

W głowie coś takiego

<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
Author: Ronan Quillevere,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-03 07:27:31

Możesz naprawić IE za pomocą:

 event.currentTarget.firstChild.ownerDocument.activeElement

Wygląda jak "explicitOriginalTarget" dla FF.

Antoine I J

 0
Author: Madbean,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-29 13:26:40

Napisałem alternatywne rozwiązanie Jak sprawić, by każdy element był skupiony i "blulable".

Polega na stworzeniu elementu jako contentEditable i ukryciu go wizualnie oraz wyłączeniu samego trybu edycji:

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

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

DEMO

Uwaga: testowane w Chrome, Firefox i Safari (OS X). Nie jestem pewien co do IE.


Related: szukałem rozwiązania dla VueJs, więc dla tych, którzy są zainteresowani / ciekawi jak zaimplementować taką funkcjonalność za pomocą dyrektywy Vue Focusable, proszę spojrzeć .

 0
Author: Serhii Matrunchyk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-24 22:41:04

Widzę tylko hacki w odpowiedziach, ale w rzeczywistości jest wbudowane rozwiązanie bardzo łatwe w użyciu : Zasadniczo można uchwycić element focus w ten sposób:

const focusedElement = document.activeElement

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

 -2
Author: Thomas J.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-15 08:52:31

W ten sposób:

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

Lub jeśli podłączysz słuchacz za pomocą JavaScript (jQuery w tym przykładzie):

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

Edit: przepraszam. Źle odczytałem pytanie.

 -3
Author: Armin Ronacher,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-23 17:44:20


Myślę, że łatwo jest to możliwe poprzez jquery, przekazując odniesienie do pola powodującego Zdarzenie onblur w "this".
Dla np.

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

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

Thanks
Monika

 -3
Author: Monika Sharma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-17 11:15:52

Mógłbyś zrobić tak:

<script type="text/javascript">
function myFunction(thisElement) 
{
    document.getElementByName(thisElement)[0];
}
</script>
<input type="text" name="txtInput1" onBlur="myFunction(this.name)"/>
 -3
Author: Shikekaka Yamiryuukido,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-17 16:10:01