Как запустить событие размытия Javascript после события щелчка, которое вызывает размытие? - PullRequest
25 голосов
/ 03 ноября 2010

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

У меня есть поле ввода с событием размытия, которое проверяет его содержание, икнопка, которая заполнит поле ввода при нажатии.Проблема при нажатии кнопки вызывает событие размытия ввода, а затем событие нажатия кнопки, поэтому содержимое, вставленное кнопкой, не соответствует действительности.

См. http://jsfiddle.net/jakecr/dL3K3/

Я знаю, чтоправильное поведение, но я не могу придумать, как обойти проблему.

Ответы [ 6 ]

34 голосов
/ 26 марта 2012

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

проверь эту скрипку, которую я сделал на твоем примере. http://jsfiddle.net/dL3K3/31/

$(function(){
    var flag = true;
    $('input').blur(function(){
        if(!$(this).val() && flag){
            alert("Grrr, It's empty");
        }
    });

    $('button').mousedown(function(){
        flag = false;
    });    
    $('button').mouseup(function(){
        flag = true;
        $('input').val('content').focus();
    });

});

-Edit-

В соответствии с предложением @mclin, использование события mousedown и protectDefault предотвратит размытие. И вы можете просто оставить исходное событие клика без изменений -

http://jsfiddle.net/dL3K3/364/

$(function(){
    $('input').blur(function(){
        if(!$(this).val()){
            alert("Grrr, It's empty");
        }
    });

    $('button').mousedown(function(e){
        e.preventDefault();
    });    
    $('button').click(function(){
        $('input').val('content');
    });

});

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

19 голосов
/ 31 января 2013

У меня есть лучшее решение, чем у Йони Джа: Вызовите warnDefault для события mousedown кнопки. OnBlur никогда не происходит, поэтому вы можете делать что угодно в событии click.

Это лучше, потому что это не меняет поведение щелчка, заставляя вещи происходить при нажатии мыши, а не мыши, что может быть неожиданным.

8 голосов
/ 30 декабря 2010

Это также может помочь:

Установите таймер, который задерживает действие события размытия, прежде чем оно запускает событие нажатия кнопки.

// Namespace for timer var setTimer = { timer: null }

    $('input,select').blur(function () {
        setTimer.timer = setTimeout(function () {
           functionCall();
        }, 1000);
    });

    $('input,select').focus(function () {
        setTimer.timer = setTimeout(function () {
            functionCall();
        }, 1000);
    });

    $("#btn").click(function () {
        clearTimeout(setTimer.timer);
        functionCall();
    });
1 голос
/ 03 ноября 2010

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

Пример использования jQuery:

$('input').blur(function() {
    validate(this);
});

$('submit').click(function() {
   //modify the input element
   validate(inputElement);
});

var validate = function(obj) {
   // validate the object
}
0 голосов
/ 28 октября 2015

Иногда бывает полезно получить дочерний объект при наведении мыши, но родитель хочет скрыть своих потомков при размытии.Мы можем отменить скрытие дочерних элементов, затем подождать, пока произойдет наведение мыши, а затем заставить размытие произойти, когда мы будем готовы

js

var cancelHide = false;

$('.my-input').blur(function() {
    if (!cancelHide) {
        $('.my-item').hide();
    }
});

$('.my-input').click(function() {
    $('.my-item').show();
});

$('.my-item').mousedown(function() {
    cancelHide = true;
});

$('.my-item').mouseup(function() {
    var text = $(this).text();
    alert(text);
    cancelHide = false;
    $('.my-input').blur();
});

html

<input type="text" class="my-input"/>
<div class="my-item">Hello</div>
<div class="my-item">Lovely</div>
<div class="my-item">World</div>

css

.my-item {
    display:none;
}

https://jsfiddle.net/tic84/on421rxg/

При щелчке по элементам списка будет появляться предупреждение только при наведении мышинесмотря на то, что родитель пытается скрыть их от размытия

0 голосов
/ 23 февраля 2012

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

Я думаю, у меня есть элегантное решение для этого:

var alreadyValidated = 'true';

setInterval(function(){
    if(document.activeElement.id != 'validation-field-id'){
        if(alreadyValidated=='false'){
            alreadyValidated = 'true';
            validate(document.activeElement);       
        }
    }
    else {
        alreadyValidated = 'false';
    }
}, 200);

В наши дни все современные браузеры поддерживают document.activeElement.

...