2012-06-23 12 views
5

Bir bulanıklık olay olan standart metin girişi var duruldu. Bulanıklaştırma olayı, belgedeki herhangi bir şey tıklandığında (<div id='show-anyways'></div> girişinden farklı olarak) tetiklenmelidir.jQuery bulanıklık

Sorunum bulanıklık olay işlevini tersine çevirecek <div id='show-anyways'></div> nasıl ekleneceğini bilmiyorum olmasıdır.

Umarım kendimi yeterince iyi açıkladım ben biraz garip bir durum olduğunu biliyorum. Daha fazla bilgiye ihtiyacınız varsa lütfen bize bildirin.

+2

Şimdiye kadar kodladığınızı gösterin. –

+1

"e.preventDefault", "e.stopPropagation" öğelerinin ya da hedefe ulaşmadan önce tıklatılıp tıklatıldığını belirlemeniz gerekir. Hissettiğim tasarım kusuru, DOM'ta bir bulanıklık olay işleyiciniz var mı? Bunu doğru mu anladım? –

cevap

10

tıklandığında ne olduğunu belirlemek için olay hedefini kullanın. Aşağıdaki belge üzerinde tüm tıklamaları izlemek ve eleman div veya Girdi ise bulanıklığı() tetiklemez.

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

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

Bu unsurları tetiklemez Herhangi bir önlemeBağlantı kurulumu var

+0

Aslında, input.blur olayı, tıklama/odak sırası girildiyse -> # show-anyways -> document.click 'den başlayacağından, çözümüm için $ (document) .click kullanmaya gitmem gerekiyordu. Bu nedenle, # show-anyways ve document.click arasındaki olay, input.blur olayını tetiklemez ... – sadmicrowave

+2

Not: bir div ve bir çocuğun içindeki tıklamaları kontrol etmenin iyi bir yolu '&&! $ tgt.is ($ ('*', $ ('# show-anyways'))) 'yukarıdaki tıklama işlevindeki koşullu ifadelere. – garromark

+0

@garromark sadece elemanın descendentlerini kontrol eder ... '$ tgt.closest ('# show-anyways'). Length 'descendents ve elementi kontrol edecek .. emin değilim neden bu bir – charlietfl

0

gibi bazı mantık eklemeyi deneyin olabilir? bulanıklık meydana geldiğinde

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

}); 

bu temelde targed/nelerin tıklandığı kontrol eder ve olmak olur gösteri neyse o zaman return false ve bir şey yapmadan duracak, ateşler. ama eğer göstermiyorsa, o zaman bulanıklık olayınızı yapabilir mi? Bu ne demek

denenmemiş, ama nedir?

+2

bu tam olarak ne demek istediğim, ama e.target bulanıklık olayında benim için 'giriş'i' döndürüyor ... böylece çözümünüzün ne olduğuna ulaşamıyorum ... – sadmicrowave

+0

bulundu - olaydaki yapı originalEvent.explicitOriginalTarget – sadmicrowave

+0

Sadly originalEvent.explicitOriginalTarget yalnızca Gecko'dur. – Yogh

1

GÜNCELLEME: tamamen benim çözüm yeniden yazmak zorunda kaldı. blur olay işleyicisi, odağı kaybeden etkinliğe eklenir: mouseout olayına benzerse, hangi öğenin odağı alacağını biliyor olabiliriz, ancak böyle bir şans yoktur. Bu yüzden, .click olaylarını yakalamaya ve blur olaylarını dinlemek yerine buna bağlı olarak bazı işlevleri tetiklememiz gerekiyor.

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

Burada a fiddle ile oynamak için. Orijinal cevabımın neden olduğu karışıklık için özür dilerim. (

1

Diğer çözümlerden eksik olan birkaç şey var: En önemlisi, bulanıklık olayını çağırmadan önce girişin odaklanıp odaklanmadığını kontrol etmeniz gerektiğidir. sadece başka bir yere tıkladığınızda değil, tarayıcınızdaki başka bir sekmeye gittiğinizde veyaBir sonraki/bir önceki girişe gitmek içinveya shift + tab. Son olarak, hedef öğesinin blur olayınızın bir istisnası olup olmadığını kontrol ettiğinizde jQuery işlevini closest() kullanmayı düşünmeniz gerekir (istisna durumunuzun çocuğu olabilir).

Yani, bu jQuery prototip fonksiyonu ile geldi:

$.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>

Chrome ve IE11 içinde test edilmiştir. Daha fazla açıklamaya ihtiyacınız varsa yorum yapmaktan çekinmeyin.

+0

çok kapsamlı . Bunu test etmek ve yayınlamak için zaman ayırdığınız için teşekkür ederiz. – sadmicrowave

İlgili konular