#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. Хотя я не думаю, что это заслуживало понижения. Я понимаю вашу ситуацию, но у меня нет решения для этого. Удачи.