Twitter bootstrap popovers、
ポップオーバーにボタンを追加していますが、
click
ハンドラーをボタンにアタッチする必要がありますが、ポップオーバーが機能する方法は、表示/非表示ではなく、要素の削除と再作成を表示するたびに、イベントハンドラーを削除することですこのボタンに関連付けられています。
私はすべて独自のバージョンのボタンでいくつかのポップオーバーを作成していますので、クラスをポップオーバーに適用するだけでは機能しません(各クラスごとに異なるクラスを生成しない限り:/)、ボタンには独自のIDがある場合とない場合があります、IDを適用できません。
Twitter bootstrap popover?のコンテンツ内の何かにイベントハンドラを適用するにはどうすればよいですか?
私は同じ問題を抱えていましたが、私の場合、$(body).on('click')
の回避策は機能しません。アプリケーションにたくさんのクリックボタンがあるからです。
代わりに次のことを行いました。このようにして、デリゲートイベントのスコープをポップオーバー要素の親だけに制限できます。
$('a.foo').popover({
html: true,
title: 'Hello',
placement: 'bottom',
content: '<button id="close-me">Close Me!</button>'
}).parent().delegate('button#close-me', 'click', function() {
console.log('World!');
});
JSフィドル: http://jsfiddle.net/dashk/5Yz7z/
追伸この手法は、アプリケーションのBackbone.View
内で使用しました。 Backbone.js
でこれを使用している場合に備えて、Fiddleのコードの抜粋を以下に示します。 http://jsfiddle.net/dashk/PA6wY/
編集Bootstrap 2.3では、ポップオーバーを追加するターゲットコンテナを指定できます。parent()ロケータを実行する代わりに、コンテナ固有のイベントをリッスンすることもできます。 ..これにより、リスナーをより具体的にすることができます(ポップオーバーを含むためだけに存在するDIVを作成することを想像してください)。
これでうまくいくはずです。これにより、.popoverクラスを持つ要素内に作成された既存および将来のボタン要素が処理されます。
$('body').on('click', '.popover button', function () {
// code here
});
DashK の非常に良い答えを少し更新するだけです:.delegate()はjQuery 1.7の時点で.on()に置き換えられました( here を参照)。
$('a.foo').popover({
html: true,
title: 'Hello',
placement: 'bottom',
content: '<button id="close-me">Close Me!</button>'
}).parent().on('click', 'button#close-me', function() {
console.log('World!');
});
こちらのjsfiddleを参照してください: http://jsfiddle.net/smingers/nCKxs/2/
また、.on()メソッドを$( 'a.foo')にチェーンする際に問題が発生しました。このような問題が発生した場合は、ドキュメント、本文、またはhtmlに追加してみてください。例:
$('a.foo').popover({
html: true,
title: 'Hello',
placement: 'bottom',
content: '<button id="close-me">Close Me!</button>'
});
$('body').on('click', 'button#close-me', function() {
console.log('World!');
});
私のために働いた非常に簡単な解決策は次のとおりです。
_// suppose that popover is defined in HTML
$('a.foo').popover();
// when popover's content is shown
$('a.foo').on('shown.bs.popover', function() {
// set what happens when user clicks on the button
$("#my-button").on('click', function(){
alert("clicked!!!");
});
});
// when popover's content is hidden
$('a.foo').on('hidden.bs.popover', function(){
// clear listeners
$("#my-button").off('click');
});
_
これが機能する理由:基本的にポップオーバーのコンテンツには、ポップオーバーが開かれるまでリスナーがありません。
ポップオーバーが表示されると、bootstrap=はそのイベント_shown.bs.popover
_を起動します。jQueryon
を使用して、このイベントのイベントハンドラーを$(a.foo)
にアタッチできます。したがって、ポップオーバーが表示されると、ハンドラー(コールバック)関数が呼び出されます。このコールバックでは、イベントハンドラーをポップオーバーのコンテンツにアタッチできます。たとえば、ユーザーがポップオーバー内のこのボタンをクリックするとどうなります。
ポップオーバーを閉じた後、ポップオーバーのコンテンツに接続されているすべてのハンドラーを削除することをお勧めします。これは、jQuery _hidden.bs.popover
_メソッドでハンドラーを削除する_.off
_ハンドラーを介して行われます。これにより、ポップオーバーが再び開かれたときに、ポップオーバー内のイベントハンドラーが2回(以上)呼び出されるのを防ぎます。
外部コンポーネントなど、ポップオーバーのコンテンツにさらに複雑な構造を追加すると、問題が発生する可能性があります。この場合、これでうまくいくはずです。
var content = $('<button>Bingo?</button>');
content.on('click', function() {
alert('Bingo!')
});
$('a.foo').popover({
html: true,
content: content
}).on('hidden.bs.popover', function() {
content.detach(); # this will remove content nicely before the popover removes it
});
$('.btn-popover').parent().delegate('button#close-me','click', function(){
alert('Hello');
});
データ属性が静的htmlで設定されている場合、上記の方法は正常に機能します。ありがとう:)
これを試して
var content = function() {
var button = $($.parseHTML("<button id='foo'>bar</button>"));
button.on('click', '#foo', function() {
console.log('you clicked me!');
} );
return button;
};
$( '#new_link' ).popover({
"html": true,
"content": content,
});