2013-07-24 17 views
9

ユーザーがポップオーバーの外の場所をクリックすると、ブートストラップのポップオーバーを非表示にしようとしています。 (私は実際にBootstrapの作成者がこの機能を提供しない理由を確信していません)ポップオーバーの外側をクリックしたときにブートストラップのポップオーバーを非表示にする

私は次のコードon the webを見つけましたが、実際にはわかりません。

// Hide popover on click anywhere on the document except itself 
$(document).click(function(e) { 
    // Check for click on the popup itself 
    $('.popover').click(function() { 
     return false; // Do nothing 
    }); 
    // Clicking on document other than popup then hide the popup 
    $('.pop').popover('hide'); 
}); 

私が混乱する主なものは、ライン$('.popover').click(function() { return false; });です。この行はclickイベントのイベントハンドラを追加しませんか?それによって、後に続くpopover('hide')への呼び出しがポップオーバーを隠すのを防ぐことはできますか?

さらに優れた技術を見た人はいますか?

注:この質問のバリエーションはこれまでに質問されていますが、これらの質問に対する回答には、上記のコードよりも複雑なコードが含まれています。だから私の質問は、私は私のコメントで述べたようにうまくいけば、あなたの質問

例HTML

<div class="well> 
    <a class="btn" data-toggle="popover" data-content="content.">Popover</a> 
    <a class="btn btn-danger bad">Bad button</a> 
</div> 

JS

var $popover = $('[data-toggle=popover]').popover(); 

//first event handler for bad button 
$('.bad').click(function() { 
    alert("clicked"); 
}); 


$(document).on("click", function (e) { 
    var $target = $(e.target), 
     isPopover = $(e.target).is('[data-toggle=popover]'), 
     inPopover = $(e.target).closest('.popover').length > 0 

    //Does nothing, only prints on console and wastes memory. BAD CODE, REMOVE IT 
    $('.bad').click(function() { 
     console.log('clicked'); 
     return false; 
    }); 

    //hide only if clicked on button or inside popover 
    if (!isPopover && !inPopover) $popover.popover('hide'); 
}); 

に答える私はhttp://jsfiddle.net/BcczZ/2/を作っ

+0

これを読む:http:// stackoverflow。com/questions/1357118/event-preventdefault-vs-return-false – Icarus

+0

@Icarus:ありがとうございますが、それは本当に私の質問に答えません。 falseを返すと処理が止まることはわかっていますが、クリックハンドラを追加すると、それに続く行の動作がどのように変わるのでしょうか?ポップオーバーが閉じられた後にクリックが機能しなくなるのはなぜですか? –

+0

そのコードはあなたが記述したものとまったく同じです。誰かが文書のどこかをクリックするたびに(.popoverを含む)、絶対に何もしないイベントリスナーが追加されます。同じイベントのために同じ要素に多くのイベントリスナーが存在する可能性があるので、メモリを浪費します。 – Dogoku

答えて

8

上記のコード、について実際にありますイベントハンドラは上書きされず、スタックするだけです。 .badボタンには既にイベントハンドラがあるので、他のイベントハンドラと一緒に起動します。

jsfiddleでコンソールを開き、ページのどこかで(ポップオーバーボタンではなく)5回押してから、あなたは

を押した回数のクリックされた印刷された同じ量を確認する必要がありbad buttonそれは


PSホープ:あなたが考えてみれば を、あなたはすでに、特にjQueryのでは、この出来事を見ました。 複数のjqueryプラグインを使用してページに存在するすべての$(document).ready(...)を考えてください。その行は、ドキュメントのreadyイベントにイベントハンドラを登録するだけです。

+0

デモのおかげでよかったです。もともと私が投稿したコードを見ると、一日中偽を返すだけの新しいハンドラを追加できるので、私にとっては理想的とは思えない。ページがリフレッシュされていない場合、それらの数は増える可能性があります。理想的ではないようです。 –

+0

「悪いボタン」を扱うコードを削除し、残りのコードを使用してください。あなたがそれを望むように動作するはずです – Dogoku

1

もっとイベントベースのソリューションを作成しました。

var $toggle = $('.your-popover-button'); 
$toggle.popover(); 

var hidePopover = function() { 
    $toggle.popover('hide'); 
}; 

$toggle.on('shown', function() { 
    var $popover = $toggle.next(); 
    $popover.on('mousedown', function(e) { 
     e.stopPropagation(); 
    }); 
    $toggle.on('mousedown', function(e) { 
     e.stopPropagation(); 
    }); 
    $(document).on('mousedown',hidePopover); 
}); 

$toggle.on('hidden', function() { 
    $(document).off('mousedown', hidePopover); 
}); 
0

短い答え 1よりも飛び出し、古いポップオーバーはの

$count=0;$(document).click(function(evt){if($count==0){$count++;}else{$('[data-toggle="popover"]').popover('hide');$count=0;}});$('[data-toggle="popover"]').popover();$('[data-toggle="popover"]').on('click', function(e){$('[data-toggle="popover"]').not(this).popover('hide');$count=0;}); 
0

非を非表示になりますとき、飛び出しのonblurがポップオーバー
を非表示になりますときmin.jsに

をブートストラップするためにこれを挿入します上記のソリューションは私が100%働いていた理由は、もう一度同じポップオーバーをダブルクリックしなければならなかったからです。私は単純かつ効果的にゼロからソリューションを書いた

$('[data-toggle="popover"]').popover({ 
     html:true, 
     trigger: "manual", 
     animation: false 
    }); 

    $(document).on('click','body',function(e){ 
     $('[data-toggle="popover"]').each(function() { 
      $(this).popover('hide'); 
     }); 

     if (e.target.hasAttribute('data-toggle') && e.target.getAttribute('data-toggle') === 'popover') { 
      e.preventDefault(); 
      $(e.target).popover('show'); 
     } 
     else if (e.target.parentElement.hasAttribute('data-toggle') && e.target.parentElement.getAttribute('data-toggle') === 'popover') { 
      e.preventDefault(); 
      $(e.target.parentElement).popover('show'); 
     } 
    }); 
関連する問題