2012-06-23 30 views
5

Tôi có đầu vào văn bản chuẩn có sự kiện mờ. Sự kiện mờ sẽ kích hoạt khi có bất kỳ nội dung nào trong tài liệu được nhấp (ngoài mục nhập VÀ <div id='show-anyways'></div>).Làm mờ jQuery không được kích hoạt nếu div được nhấp/tập trung

Vấn đề của tôi là tôi không biết cách thêm <div id='show-anyways'></div> để phủ nhận chức năng sự kiện mờ.

Hy vọng rằng tôi đã giải thích cho bản thân mình đủ tốt, tôi biết đó là một tình huống kỳ lạ. Hãy cho tôi biết nếu bạn cần thêm thông tin.

+2

hiển thị những gì bạn đã mã hóa cho đến thời điểm này. –

+1

Bạn sẽ cần phải có 'e.preventDefault',' e.stopPropagation', hoặc xác định cái nào đã được nhấp và dừng bọt trước khi nó chạm vào mục tiêu. Lỗ hổng thiết kế mà tôi cảm thấy là bạn có trình xử lý sự kiện mờ trên DOM? Tôi có hiểu điều đó đúng không? –

Trả lời

10

Sử dụng các mục tiêu sự kiện để xác định những gì được nhấp. Sau sẽ theo dõi tất cả các nhấp chuột vào tài liệu và không kích hoạt blur() nếu phần tử là DIV hoặc Input.

var $input=$('#MY-Input-ID'); 

$(document).click(function(evt){ 
    var $tgt=$(evt.target); 
    if(!$tgt.is('#show-anyways') && !$tgt.is($input)){ 
     $input.blur() 
    } 
}) 

Nó sẽ không kích hoạt trên các yếu tố

+0

Tôi thực sự phải kết thúc bằng việc sử dụng $ (tài liệu) .nhấp vào giải pháp của tôi vì sự kiện input.blur ban đầu sẽ không kích hoạt nếu chuỗi nhấp/tiêu điểm được nhập -> # show-anyways -> document.click. Do đó, sự kiện giữa # show-anyways và document.click sẽ không kích hoạt sự kiện input.blur ... – sadmicrowave

+2

Lưu ý: cách tốt để kiểm tra nhấp chuột trong div và tất cả các con của nó là thêm '&&! $ tgt.is ($ ('*', $ ('# show-anyways'))) 'cho các câu lệnh có điều kiện trong hàm nhấp chuột ở trên. – garromark

+0

@garromark chỉ kiểm tra hậu duệ của phần tử ... '$ tgt.closest ('# show-anyways'). Length' sẽ kiểm tra hậu duệ và phần tử .. không chắc tại sao tôi không sử dụng số đó – charlietfl

0

có thể thử thêm một số logic như thế nào?

$('input').blur(function(e){ 
var tester = e.target; 
if ($(tester).attr('id') == 'show-anyways'){ 
return false; 
} 
else { 
// do something? 
} 

}); 

điều này cơ bản sẽ kích hoạt khi bị mờ, nếu nó xảy ra thì sẽ trả về false và ngừng làm bất cứ điều gì. nhưng nếu nó không hiển thị thì nó có thể làm sự kiện mờ của bạn?

chưa được kiểm tra, nhưng ý bạn là gì?

+2

đây chính là ý của tôi, nhưng e.target trả về 'đầu vào' cho tôi trên sự kiện mờ ... vì vậy tôi không thể đến giải pháp của bạn là gì ... – sadmicrowave

+0

tìm thấy nó - cấu trúc trong sự kiện là originalEvent.explicitOriginalTarget – sadmicrowave

+0

Đáng buồn ban đầuEvent.explicitOriginalTarget chỉ là Gecko. – Yogh

1

CẬP NHẬT: đã viết lại hoàn toàn giải pháp của tôi. Trình xử lý sự kiện blur được gắn với sự kiện mất tiêu điểm: nếu sự kiện tương tự như sự kiện mouseout, chúng tôi có thể biết yếu tố nào sẽ tập trung, nhưng không có may mắn như vậy. Do đó, chúng tôi phải bắt đầu ghi lại các sự kiện .click - và kích hoạt một số chức năng dựa trên sự kiện đó thay vì nghe các sự kiện blur.

var inputIsBlurred = function() { 
    console.log('Run away!!!'); 
}; 
$(document).click(function(e){ 
    var $target = $(e.target); 
    console.log($target); 
    if ($target.is('#some_input') // fired by an input - no special effects 
     || $target.is('#show-anyways') // fired by 'show-anyways' div 
     || $target.parents('#show-anyways').length > 0 // ... or its children 
) { 
     return true; // move along, nothing to do here 
    } 
    inputIsBlurred(); 
});​ 

Đây là a fiddle để chơi cùng. Xin lỗi vì sự nhầm lẫn đó gây ra bởi câu trả lời ban đầu của tôi. (

1

Có một vài điều còn thiếu trong các giải pháp khác, điều quan trọng nhất là bạn cần phải kiểm tra xem đầu vào có tập trung trước khi gọi sự kiện mờ của bạn hay không. được gọi không chỉ khi bạn nhấp vào một nơi khác: bạn cũng có thể gọi nó khi bạn chuyển đến tab khác trong trình duyệt của mình hoặc nếu bạn nhấn tab hoặc shift + tab để chuyển đến đầu vào tiếp theo/trước đó. Cuối cùng, bạn cần cân nhắc việc sử dụng hàm jQuery closest() khi bạn kiểm tra xem phần tử đích có phải là ngoại lệ cho sự kiện làm mờ của bạn hay không (nó có thể là con của ngoại lệ của bạn).

Vì vậy, tôi đã đưa ra chức năng nguyên mẫu jQuery này:

$.fn.extend({ 
 

 
    blurIfNot : function(options, handler) 
 
    { 
 
     var defaults = 
 
     { 
 
      except : [], 
 
      maxParent : null // A DOM element within which 
 
          // a matching element may be found 
 
     }; 
 
     var opt = $.extend({}, defaults, options); 
 
     var time = new Date().getTime(); 
 
     
 
     this.each(function() 
 
     { 
 
      var thisInp = $(this); 
 
      thisInp[0].blurIfNot = {}; 
 
      time += 1000000000000; 
 
      
 
      var except = opt.except; 
 
      
 
      if ($.isFunction(opt.except)) 
 
      { except = opt.except.call(thisInp[0]); } 
 
      
 
      function fire_blur_event(_tar, evt, mousedown) 
 
      { 
 
       var proceed = true; 
 
       
 
       for (var i in except) 
 
       { 
 
        if (_tar.is(thisInp) || 
 
        _tar.closest(except[i], opt.maxParent).length) 
 
        { 
 
         proceed = false; 
 
         break; 
 
        } 
 
       } 
 
       if (proceed) 
 
       { 
 
        thisInp[0].blurIfNot.focus = false; 
 
        handler.call(thisInp[0], evt); 
 
       } 
 
       else if (mousedown) 
 
       { 
 
        $('html').one('mouseup', function(e) 
 
        { 
 
         thisInp[0].focus(); 
 
        }); 
 
       } 
 
      } 
 
      
 
      if (!thisInp[0].blurIfNot.isset) 
 
      { 
 
       $('html').mousedown(function(e) 
 
       { 
 
        if (thisInp[0].blurIfNot.focus) 
 
        { 
 
         var tar = $(e.target); 
 
         
 
         if (!tar.is('input')) 
 
         { fire_blur_event(tar, e, true); } 
 
        } 
 
       }); 
 
       
 
       $(window).blur(function(e) 
 
       { 
 
        if (thisInp[0].blurIfNot.focus) 
 
        { 
 
         thisInp[0].blurIfNot.focus = false; 
 
         handler.call(thisInp[0], e); 
 
        } 
 
       }); 
 
      } 
 
      else 
 
      { // to be able to update the input event if you have 
 
       // created new inputs dynamically 
 
       $('input').off('focus.blufIfNot' + time); 
 
      } 
 
      
 
      $('input').on('focus.blurIfNot' + time, function(e) 
 
      { 
 
       var tar = $(e.target); 
 
       
 
       if (tar[0] == thisInp[0]) 
 
       { thisInp[0].blurIfNot.focus = true; } 
 
       
 
       else if (thisInp[0].blurIfNot.focus) 
 
       { fire_blur_event(tar, e); } 
 
      }); 
 
      
 
      thisInp[0].blurIfNot.isset = true; 
 
     }); 
 
     return this; 
 
    } 
 
}); 
 

 
$('#input_blur_if_not').blurIfNot(
 
{ 
 
    except : [ 
 
     $('.autocomplete'), $('.question') 
 
    ], 
 
    // You can also define the elements with a function: 
 
    // except : function() 
 
    // { 
 
    //  return [ $(this).parent().find('.autocomplete') ]; 
 
    // }, 
 
    maxParent : $('#parent')[0] // optional 
 
}, 
 
function(e) 
 
{ 
 
    var rand = Math.random(); 
 
    
 
    $('#test').css('padding', rand * 100 + "px"). 
 
    html(rand + " blur !"); 
 
});
.autocomplete { 
 
    background: #eee; 
 
} 
 
.autocomplete, input { 
 
    width: 200px; 
 
    padding: 3px; 
 
    border: 1px solid #555; 
 
} 
 
.question { 
 
    display:inline-block; 
 
    border-radius:50%; 
 
    background:#137dba; 
 
    color:#fff; 
 
    font-weight:bold; 
 
    padding:2px 7px; 
 
    cursor:pointer; 
 
} 
 
#test { 
 
    position:absolute; 
 
    top:0; 
 
    left:260px; 
 
    color:red; 
 
    font-weight:bold; 
 
    padding:10px 0; 
 
    vertical-align:bottom; 
 
}
<script src="http://code.jquery.com/jquery-latest.js"></script> 
 

 
<div id="parent"> 
 
    
 
    <input value="an input" /> 
 
    <br><br> 
 
    <input id="input_blur_if_not" value="input with autocomplete menu" /> 
 
    
 
    <div class="question">?</div> 
 
    <div class="autocomplete"> 
 
     <div>option 1</div> 
 
     <div>option 2</div> 
 
    </div> 
 
    <br> 
 
    <input value="another input" /> 
 
    <div id="test"></div> 
 
    
 
</div>

Tested trong Chrome và IE11. Hãy bình luận nếu bạn cần giải thích thêm.

+0

rất toàn diện . Cảm ơn bạn đã dành thời gian để kiểm tra và đăng bài này. – sadmicrowave

Các vấn đề liên quan