Different behavior of blur event in different browsers

后端 未结 3 556
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-15 10:14

Consider this example where I have 2 input fields:



And consider t

相关标签:
3条回答
  • 2020-12-15 10:39

    According to this archive of whatwg.org:

    An element is focusable if the user agent's default behavior allows it to be focusable or if the element is specially focusable, but only if the element is either being rendered or is a descendant of a canvas element that represents embedded content.

    It seems that all browsers also don't make visibility:hidden and display:none input elements focusable. The following JavaScript tests in which cases is an element focusable.

    function isFocusable(type) {
        var element = document.getElementById(type);
        result += type + ' is';
        try {
            element.focus();
            if (element != document.activeElement)
                result += ' not';
        } catch (e) {
          result += ' not (error thrown)';
        }
        result += ' focusable<br>';
    }
    

    var result = '';
    
    function isFocusable(type) {
      var element = document.getElementById(type);
      result += type + ' is';
      try {
        element.focus();
        if (element != document.activeElement)
          result += ' not';
      } catch (e) {
        result += ' not (error thrown)';
      }
      result += ' focusable<br>';
    }
    
    isFocusable('text');
    isFocusable('hidden');
    isFocusable('disabled');
    isFocusable('readonly');
    isFocusable('visiblity-hidden');
    isFocusable('display-none');
    isFocusable('div-hidden');
    
    document.getElementById('browser-version').innerHTML = navigator.userAgent;
    document.getElementById('logger').innerHTML += result;
    <input id=text type=""></input>
    <input id=hidden type="hidden"></input>
    <input id=disabled disabled></input>
    <input id=readonly readonly></input>
    <input id=visiblity-hidden style="visibility:hidden"></input>
    <input id=display-none style="display:none"></input>
    <div id=div-hidden sytle="visibility:hidden" tabindex=1>
      </input>
    
      <div id=browser-version></div>
    
      <div id=logger></div>

    Here's the output in Firefox 34.0.5 and Chrome 39.0.2

    Gecko/20100101 Firefox/34.0
    text is focusable
    hidden is not focusable
    disabled is not focusable
    readonly is focusable
    visiblity-hidden is not focusable
    display-none is not focusable
    div-hidden is focusable
    
    AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36
    text is focusable
    hidden is not focusable
    disabled is not focusable
    readonly is focusable
    visiblity-hidden is not focusable
    display-none is not focusable
    div-hidden is focusable
    
    0 讨论(0)
  • 2020-12-15 10:56

    As you know, the issue is that different browsers choose to call event handlers in different orders. One solution is to give the other events a chance to fire by setting a timer for 0 milliseconds, and then checking the fields to see which (if any) is focused.

    a.onfocus = function() {show(b);};
    
    a.onblur = function() {
        setTimeout(function() {
            //if neither filed is focused
            if(document.activeElement !== b && document.activeElement !== a){
                hide(b);
            }
                }, 0);
    };
    
    //same action as for a
    b.onblur = a.onblur;
    

    Tested in Chrome, Firefox, Internet Explorer, and Safari. See full working example (edited version of your fiddle) at JSFiddle.net.

    0 讨论(0)
  • 2020-12-15 10:56

    You can use an extravarible to check whether b is focused before hiding b. It worked in IE, Chrome & Firefox. I don;t have any other browser. You can check it.

    var focusedB = false;
    $("#a").focus(function(){
         $("#b").show();   
     });
     //if b is focused by pressing tab bar.
     $("#a").keydown(function(e){
         if(e.which === 9){
              focusedB = true;  
          }
       });
       $("#b").blur(function(){
            $("#b").hide();
       });
       $("#a").blur(function(){
           if(focusedB){
                focusedB = false;
            }else{
                $("#b").hide();
            }
        });
        $( "#b" ).mousedown(function() {
           focusedB = true;
        });
    
    0 讨论(0)
提交回复
热议问题