Когда происходит событие "размытия", как я могу узнать, какой элемент фокуса пошел * на *?

Предположим, что я прикрепляю функцию blur к окну ввода HTML следующим образом:

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

Есть ли способ получить идентификатор элемента, вызвавшего событие blur для запуска (элемент, который был нажат) внутри функции? Как?

Например, предположим, что у меня такой пробел:

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

Если я нажимаю на диапазон сразу после того, как элемент ввода имеет фокус, элемент ввода потеряет фокус. Как функция знает, что было нажато mySpan?

PS: Если событие onclick диапазона будет происходить до события onblur элемента ввода, моя проблема будет решена, потому что я могу установить некоторое значение статуса, указывающее, что был выбран определенный элемент.

PPS: Основой этой проблемы является то, что я хочу инициировать управление автозаполнением AJAX извне (из элемента, которое можно щелкнуть), чтобы показать свои предложения, без предложения немедленно исчезнуть из-за события blur на элементе ввода. Поэтому я хочу проверить функцию blur, если был нажат один конкретный элемент, и если да, проигнорируйте событие размытия.

Ответ 1

Хм... В Firefox вы можете использовать explicitOriginalTarget, чтобы вытащить элемент, на который был нажат. Я ожидал, что toElement сделает то же самое для IE, но он, похоже, не работает... Однако вы можете вытащить вновь сфокусированный элемент из документа:

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

Предостережение: Этот метод не работает для изменений фокуса, вызванных табуляцией полей с помощью клавиатуры и вообще не работает в Chrome или Safari. Большая проблема с использованием activeElement (кроме IE) заключается в том, что он не постоянно обновляется до тех пор, пока событие blur не будет обработано и может вообще не иметь никакого действительного значения во время обработки! Это можно смягчить с помощью варианта метода, в котором Мичиел использовал:

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 не фокусируется на нажатых кнопках (против вкладок на вкладку).

Ответ 2

2015 ответ: согласно События пользовательского интерфейса, вы можете использовать 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 />

Ответ 3

Я решил это в конечном итоге с тайм-аутом на событии onblur (благодаря совету друга, который не является StackOverflow):

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

Работает как в FF, так и в IE.

Ответ 4

Возможно использование события mousedown документа вместо размытия:

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

Ответ 5

Можете ли вы отменить то, что вы проверяете и когда? То есть, если вы помните, что было размыто последним:

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

а затем в onClick для вашего диапазона вызовите функцию() с обоими объектами:

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

Затем ваша функция может решить, нужно ли запускать элемент управления Ajax.AutoCompleter. Функция имеет объект с щелчком и размытый объект. OnBlur уже произошло, поэтому он не заставит предложения исчезнуть.

Ответ 6

Я также пытаюсь заставить Autocompleter игнорировать размытие, если какой-то конкретный элемент щелкнул и имеет рабочее решение, но только для Firefox из-за 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);
                }
            }
        }
    );

Этот код обертывает по умолчанию метод OnBlur автозаполнения и проверяет, установлены ли параметры ignoreBlurEventElement. если он установлен, он проверяет каждый раз, чтобы увидеть, если элемент clicked игнорируетсяBlurEventElement или нет. Если это так, Autocompleter не работает onBlur, иначе он вызывает onBlur. Единственная проблема заключается в том, что он работает только в Firefox, потому что свойство explicitOriginalTarget имеет специфику Mozilla. Теперь я пытаюсь найти другой способ, чем использование explicitOriginalTarget. Решение, о котором вы упомянули, требует, чтобы вы добавляли onclick поведение вручную к элементу. Если мне не удастся решить проблему kernelOriginalTarget, я думаю, что я последую за вашим решением.

Ответ 7

Я думаю, что это не возможно, с IE вы можете попробовать использовать window.event.toElement, но он не работает с firefox!

Ответ 8

Используйте что-то вроде этого:

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>

Ответ 9

Как отмечено в этом ответе, вы можете проверить значение document.activeElement. document - глобальная переменная, поэтому вам не нужно делать какую-либо магию, чтобы использовать ее в своем обработчике onBlur:

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

Ответ 10

У экземпляров FocusEvent есть атрибут relatedTarget, но до версии 47 FF, в частности, этот атрибут возвращен null, из 48 уже работает.

Ответ 11

  • document.activeElement может быть родительским node (например, body node, потому что он находится во временном переключении фазы с цели на другой), поэтому он не может использоваться для вашей области
  • ev.explicitOriginalTarget не всегда оценивается

Таким образом, лучший способ - использовать onclick в событии body для косвенного понимания вашего node (event.target) на размытии

Ответ 12

Edit: Хакерный способ сделать это - создать переменную, которая отслеживает фокус для каждого элемента, о котором вы заботитесь. Итак, если вам неловко, что "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'
}" />

Ответ 13

Я предлагаю использовать глобальные переменные blurfrom и blurto. Затем настройте все элементы, которые вы хотите присвоить своей позиции в DOM переменной blurfrom, когда они потеряют фокус. Кроме того, настройте их так, чтобы наложение фокуса задало переменную blurto в их положение в DOM. Затем вы можете использовать другую функцию для анализа данных blurfrom и blurto.

Ответ 14

помните, что решение с 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">

Ответ 15

Я играл с этой же функцией и узнал, что 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;
    }
    //...
});

Ответ 16

Мне не нравится использовать тайм-аут при кодировании javascript, чтобы я сделал это противоположным образом Мичиэля Боркента. (Не пробовал код позади, но вы должны получить идею).

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

Ответ 17

Вы можете исправить IE с помощью

 event.currentTarget.firstChild.ownerDocument.activeElement

Он выглядит как "explicitOriginalTarget" для FF.

Антуан и J

Ответ 18

Я написал альтернативное решение чтобы сделать любой элемент уязвимым и "прочным" .

Он основан на создании элемента как contentEditable и скрывает его визуально и отключает сам режим редактирования:

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

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

DEMO

Примечание. Протестировано в Chrome, Firefox и Safari (OS X). Не уверен в IE.


Связанный: Я искал решение для VueJs, поэтому для тех, кому интересно или интересно, как реализовать такую ​​функциональность с помощью Vue Focusable, пожалуйста, взять искать.

Ответ 19

  • document.activeElement может быть родительским node, поэтому он может использоваться для вашей области
  • ev.explicitOriginalTarget не всегда оценивается

Таким образом, лучший способ - использовать событие onclick для косвенного понимания вашего node на размытии или нет

Ответ 20

Я вижу только ответы в ответах, но на самом деле встроенное решение очень простое в использовании: В основном вы можете захватить элемент фокусировки следующим образом:

const focusedElement = document.activeElement

https://developer.mozilla.org/en-US/docs/Web/API/Document/activeElem ent

Ответ 21

Таким образом:

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

Изменить: извините. Я неправильно понял вопрос.

Ответ 22


Я думаю, что его легко можно использовать через jquery, передав ссылку поля, вызывающее событие onblur в "this".
Например,

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

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

Спасибо
Monika

Ответ 23

Вы можете сделать это следующим образом:

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