Есть ли способ использовать event.метод preventDefault с focusOut? Если нет, то почему?

я хотел бы предотвратить событие по умолчанию от focusOut (или blur) событие и сохранить фокус в определенном поле ввода.

это то, что я уже попробовал:

  • используя event.preventDefault() в начале и в конце функции (для тестовых целей, а не для стиля)

  • return false; для предотвращения распространения

  • установка фокуса на элемент непосредственно в элементе (но я обнаружил, что фокус все еще переключается, потому что переключатель фокуса выполняется после the .on() функции выполняет. Я знаю, что мог бы использовать setTimeout, но я хотел бы избежать этого и выяснить суть проблемы.)

  • используя blur вместо focusOut

мой код такой:

    _triggerEventHide: function(inst, eventType) {
        inst.$target.on(eventType, function(event) {
            event.preventDefault();
            if (!$.suggestBox.$divCont.hasClass($.suggestBox.mouseOverClassName)) {
                $.suggestBox.$divCont.css({display: 'none'});   //reposition Suggestbox
            } else {
                inst.target.focus(); 
            }
            event.preventDefault();
            return false;
        });
     }

отметим, что $target представляет элемент jQuery-wrapped и target представляет собственный DOM элемент.

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

  1. preventDefault не работает на событии фокусировки – здесь данный ответ является альтернативным путем использования любого рода манипуляций с событиями.

  2. фокус назад текстовое поле на фокус, если не имеет требуемого значения - здесь решение было использовать setTimeout() чтобы вернуть фокус к исходному элементу, что нормально, но я хотел бы понять суть проблемы, почему preventDefault() здесь не работает.

  3. jQuery preventDefault () не работает – я пробовал некоторые возможные решения из этой темы, такие как использование event.stopImmediatePropagation() и event.stop(), но все напрасно.

Я ценю любое время, знания и решения (включая попытки), внесенные в этом вопросе. Мне бы очень хотелось узнать...

здесь jsFiddle чтобы показать вам проблему... не стесняйтесь играть с ней и попробовать различные решения.

3 ответов


после некоторых исследований я обнаружил, что только определенные события "отменяются".

  • цитата из http://help.dottoro.com/ljwolcsp.php

    вы можете проверить, можно ли отменить событие с помощью свойства cancelable во всех браузерах, кроме Internet Explorer до версии 9. Хотя свойство cancelable существует в Firefox, оно всегда возвращает true, независимо от состояния события cancelable. Нет способ определения возможности отмены события в Internet Explorer до версии 9.

    обратите внимание, что использование метода preventDefault и свойства returnValue для события без отмены не вызывает ошибки. Когда обработчик событий возвращает false, событие будет отменено. Его можно использовать вместо метода preventDefault и свойства returnValue. См. Пример 2 ниже.

  • каждое событие в Javascript имеет отменяемый свойство, определяемое как "true", если событие можно предотвратить, или "false", если событие нельзя отменить. Ref:http://help.dottoro.com/ljeosnqv.php

  • пример скрипта из http://help.dottoro.com/ljeosnqv.php демонстрируя это свойство можно найти здесь на jsFiddle (для экономии места). Обратите внимание на комментарии в коде о том, как Firefox всегда возвращает true для свойства cancelable в объекте event.

общий принцип бытия:

 $('selector').on(eventType, function (event) {
    alert(('cancelable' in event));   //will return true
    alert(event.cancelable);      //will return true if event can be cancelled
                                  //NOTE: Firefox mistakenly always returns true
});
  • события имеют заданный порядок возникновения в зависимости от ситуации. Например, если нажать кнопку мыши, порядок eventTriggers будет: mousedown, mouseup и click. Ref: www.w3.org/TR/DOM-Level-2-Events/events.html#Events-Event-initMouseEvent

  • цитата из http://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/events.html#Events-flow-cancelation

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

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


МОЕ РЕШЕНИЕ:

что удалось найти решение к моей проблеме и более / менее этой проблеме. По сути, у меня уже был eventListener с элементом для focusin, и я хотел, чтобы этот элемент сохранял фокус.

<div id='display'></div>
$('#idBox').on('focusin', function () {
  $('#div').append('focused');
  //do something
}

Первоначально я попытался использовать событие setTimeout, когда я щелкнул, но я обнаружил, что это не было хорошо, потому что это вызвало мое событие focusin снова. Так что нам нужно событие. это отправлено перед действием DOM по умолчанию переключения фокуса. Я нашел это там is событие, которое соответствует этому требованию, но доступно только IE... типичный. К вашему сведению, это:"onbeforedeactivate" и отменено. Однако, поскольку совместимость с кросс-браузером важна, мы не должны использовать этот eventTrigger. Скорее я обнаружил, что событие mousedown происходит до того, как DOM начинает изменять фокус стереотипы поведения.

Так что мы могли бы сделать это:

$(document).on('mousedown', function(event) { 
       target = event.target;     // the element clicked on
       myTarget = document.getElementById("idBox");   // the element to keep focus
       if (target !== myTarget) {   
           event.preventDefault();  //prevent default DOM action
           event.stopPropagation();   //stop bubbling
           return false;   // return
       }
});

есть много других способов сделать это. Мне лично не нравится устанавливать eventListener для всего документа, но для демонстрации основ он служит своей цели.


сноску: Отличная статья для чтения, чтобы узнать больше об обработке событий в Javascript-этоhttp://help.dottoro.com/ljtdqwlx.php Удивительный ресурс, на который я наткнулся.


мы знаем, что это функция click, которая вызывает проблему. Таким образом, в обычном проводнике, таком как chrome, вы можете отключить событие mousedown, а затем preventDefault.

но это не работает в ie, но мы можем использовать событие beforedeactivate вместо http://msdn.microsoft.com/en-us/library/windows/apps/jj569321.aspx. Это может быть deteact в ie, когда фокус меняется. так что просто предотвратите это.

код будет такой:

       $inp.on('blur', function(){

            self.hide();
        });

        isIE && $inp.on('beforedeactivate', function(evt){
            mousedown && evt.preventDefault();
        });

        $holder.on('mousedown', function(evt){
            evt.preventDefault();
            mousedown = 1;
        });

inst.$target.on("blur", function() {
     if (!$.suggestBox.$divCont.hasClass($.suggestBox.mouseOverClassName)) {
        $.suggestBox.$divCont.css({'display': 'none'});   //reposition Suggestbox
        return true;
        } 
      inst.target.focus();
      return false;
         });

нужно увидеть ваш html. Я не думаю, что вы правильно называете вещи EX:

$.suggestBox Я думаю, что должно быть $(".suggestBox") , но я не могу сказать, не видя ваш htnl