jqueryevent-handlingjquery-eventspreventdefault

Is there a way to use event.preventDefault with focusOut? If not, why?


I would like to prevent the default event from a focusOut (or blur) event and keep the focus set to the specific input field.

This is what I have already tried:

My code is this:

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

Note that $target represents the jQuery-wrapped element and target represents the native DOM element.

I’ve done some research and have found already a few articles relating to my question, but none of them answer this exact question.

  1. preventDefault does not work on focus event – Here, the answer given is an alternate route to using any kind of event manipulation.

  2. Focus back textbox on focus out if does not have required value – Here, the solution was to use setTimeout() to set the focus back to the original element, which is all right, but I’d like to understand the heart of the issue, why preventDefault() is not working here.

  3. jQuery preventDefault() not working – I tried some possible solutions from this thread, such as using event.stopImmediatePropagation() and event.stop(), but all for naught.

I appreciate any time, knowledge and solutions (including attempts) contributed in this matter. I would really like to learn…

Here is a jsFiddle to show you the problem… feel free to play around with it and try different solutions.


Solution

  • After some more research I've found out that only certain events are 'cancelable'.

    The general principal being:

     $('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
    });
    

    MY SOLUTION:

    That being said I did manage to find a solution to my problem and more/less this problem. Essentially I had an eventListener with an element for focusin already and I wanted this element to keep focus.

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

    Initially I tried using a setTimeout event when I clicked off, but I found that wasn't good because it triggered my focusin event again. So what we need is an event that is dispatched before the DOM's default action of switching focus. I did find that there is an event that meets this requirement, but is only available to IE... typical. For your information it is: "onbeforedeactivate" and it is cancelable. However since cross browser compatibility is important, we should not use this eventTrigger. Rather I found that the event mousedown occurs before the DOM starts its focus-changing behaviours.

    So what we could do is:

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

    There are many other ways of going about it. I personally don't like setting an eventListener to the entire document, but to demonstrate the basics it serves its purpose.


    Footnote: A great article to read to learn more about event handling in Javascript is http://help.dottoro.com/ljtdqwlx.php An amazing resource I stumbled across.