Запуск onBlur для нескольких элементов как единого блока

#javascript #jquery

#javascript #jquery

Вопрос:

У меня есть два входных данных, которые вместе образуют единую семантическую единицу (например, входные данные часов и минут вместе образуют ввод времени). Если оба входных сигнала теряют фокус, я хочу вызвать некоторую функцию Javascript, но если пользователь просто переключается между этими двумя, я не хочу ничего запускать.

Я пытался обернуть эти два входных параметра в div и добавить onBlur в div, но это никогда не срабатывает.

Затем я попытался добавить ONBLUR к обоим входам и заставить их проверять другой атрибут:focus через jQuery, но, похоже, что при срабатывании onBlur следующий элемент еще не получил фокус.

Есть предложения о том, как этого добиться?

РЕДАКТИРОВАТЬ: Кто-то усомнился в цели этого. Я хотел бы обновить несколько других полей на основе значений, содержащихся в обоих этих входных данных, но в идеале я не хочу обновлять другие поля, если пользователь все еще находится в процессе обновления второго ввода (например, если пользовательские вкладки с первого на второй ввод).

Ответ №1:

Я привел рабочий пример здесь: https://jsfiddle.net/bs38V/5 /

Он использует это:

 $('#t1, #t2').blur(function(){
    setTimeout(function(){
        if(!$('#t1, #t2').is(':focus')){
            alert('all good');
        }
    },10);
});
  

Ответ №2:

 var focus = 0;
$(inputs).focus(function() { focus   });
$(inputs).blur(function() {
    focus--;
    setTimeout(function() {
        if (!focus) {
            // both lost focus
        }
    }, 50);
});
  

Комментарии:

1. Да, но поскольку вы можете сфокусироваться только на одном элементе, вы могли бы также использовать true и false .

2. Если вы используете логический флаг, вы в определенной степени полагаетесь на порядок запуска события.

3. Спасибо, похоже, что это должно сработать, хотя это больше проблем, чем я надеялся, что это будет : (

4. Вопрос в том, был ли у фокуса шанс сработать до истечения тайм-аута. При ненулевом таймауте это, вероятно, гарантировано, при нулевом зависит от внутренних компонентов движка JS, которые мне не очень интересно знать подробно.

Ответ №3:

Альтернативный подход заключается в проверке relatedTarget события размытия. Как указано в документации MDN, это будет элемент, который получает фокус (если он есть). Вы можете обработать событие размытия и проверить, был ли теперь сделан акцент на другом вашем вводе. Я использовал data- атрибут для их идентификации, но вы с таким же успехом можете использовать id или какую-то другую информацию, если это лучше подходит для вашей ситуации.

Мой код взят из проекта angular, над которым я работал, но принцип должен быть переведен на ванильный JS / другие фреймворки.

 <input id="t1" data-customProperty="true" (blur)="onBlur($event)">
<input id="t2" data-customProperty="true" (blur)="onBlur($event)">
  
 onBlur(e: FocusEvent){
    const semanticUnitStillHasFocus = (val.relatedTarget as any)?.dataset?.customProperty === "true";

    // Do whatever you like with this knowledge
}
  

Ответ №4:

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

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

Без контекста сложно помочь вам больше.

d.

Комментарии:

1. Это скорее комментарий, чем ответ.

2. Просто чтобы привести пример того, почему такое поведение может быть полезным, мой сценарий заключается в том, что я хочу, чтобы пользователь вводил адрес what3words в 3 отдельных текстовых поля. Адрес необязателен, но частичный адрес недопустим. Я хочу проверить, что либо все 3 входных параметра содержат слово, либо все они пустые. Я не хочу, чтобы проверка запускалась, когда первый ввод размывается, потому что у пользователя не было возможности ввести другие 2 слова в этот момент. Я хочу, чтобы проверка запускалась, когда пользователь удаляется от всех 3 входных данных.

3. Мне искренне жаль, что мой ответ не смог помочь вам @Tim. Хотя я не думаю, что это заслуживало понижения. Я понимаю вашу ситуацию, но у меня нет решения для этого. Удачи.