1. ホーム
  2. javascript

[解決済み] ブートストラップポップオーバーを動的要素に結合する方法

2022-02-10 20:13:52

質問

ダイナミックリストにTwitter Bootstrapのポップオーバーを使用しています。リストアイテムにボタンがあり、ボタンをクリックするとポップオーバーが表示されるはずです。非ダイナミックでテストしたときは問題なく動作しました。

これは非ダイナミックリストのための私のJavaScriptです。

$("button[rel=popover]").popover({ 
    placement : 'right',
    container : 'body',
    html : true,
    //content:" <div style='color:red'>This is your div content</div>"
    content: function() {
      return $('#popover-content').html();
    }

    })
    .click(function(e) {
        e.preventDefault();
});

しかし、ダイナミックリストではうまくいきません。ボタンを2回クリックすると、1回目にクリックしたリスト項目のうち1つだけが表示されることがあります。

私のhtmlです。

 <ul id="project-list" class="nav nav-list">
   <li class='project-name'>
     <a >project name 1
         <button class="pop-function" rel="popover" ></button>
     </a>
   </li>
   <li class='project-name'>
     <a>project name 2
        <button class="pop-function" rel="popover" ></button>
     </a>
   </li>

 </ul>

<div id="popover-content" style="display:none">
    <button class="pop-sync"></button>
    <button class="pop-delete"></button>
</div>

私のダイナミック用JavaScriptです。

$(document).on("click", "#project-list li" , function(){
   var username = $.cookie("username");
   var projectName = $(this).text()
   $("li.active").removeClass("active");
   $(this).addClass("active");
   console.log("username: " +username + " project name: "+projectName );
});


$(document).on("click", "button[rel=popover]", function(){
    $(this).popover({ 
       placement : 'right',
       container : 'body',
       html : true,
    content: function() {
       return $('#popover-content').html();
        }

    }).click(function(e){
    e.preventDefault();
    })

});


//for close other popover when one popover button click
$(document).on("click", "button[rel=popover]" , function(){

        $("button[rel=popover]").not(this).popover('hide');
 });

類似の問題を検索してみましたが、私の問題を解決するものはまだ見つかっていません。 どなたかアイデアをお持ちの方がいらっしゃいましたら、ぜひ教えてください。ご協力ありがとうございます。

解決方法を教えてください。

更新情報

もしポップオーバーが一貫したセレクタを持つのであれば、次のものを利用することができます。 selector プロパティを使用します。

var popOverSettings = {
    placement: 'bottom',
    container: 'body',
    html: true,
    selector: '[rel="popover"]', //Sepcify the selector here
    content: function () {
        return $('#popover-content').html();
    }
}

$('body').popover(popOverSettings);

デモ

その他の方法

  1. ( 標準的な方法 ) 挿入される新しいアイテムにポップオーバーを再度バインドします。popoversettings を外部変数に保存します。
  2. 使用方法 Mutation Event / Mutation Observer に特定の要素が挿入されているかどうかを識別するために使用します。 ul または要素を指定します。

ソース

var popOverSettings = { //Save the setting for later use as well
    placement: 'bottom',
    container: 'body',
    html: true,
    //content:" <div style='color:red'>This is your div content</div>"
    content: function () {
        return $('#popover-content').html();
    }

}

$('ul').on('DOMNodeInserted', function () { //listed for new items inserted onto ul
    $(event.target).popover(popOverSettings);
});

$("button[rel=popover]").popover(popOverSettings);
$('.pop-Add').click(function () {
    $('ul').append("<li class='project-name'>     <a>project name 2        <button class='pop-function' rel='popover'></button>     </a>   </li>");
});

しかし DOMNodeInserted Mutation Eventは、サポートと同様にパフォーマンスの問題のため、使用できません。これは、これまで 非推奨 もあります。そのため、設定を保存し、新しい要素に更新した後にバインドするのが最善の方法です。

デモ

もう一つのお勧めの方法は 変異オブザーバ MDNによると、MutationEventの代わりに、MutationEventを使用するようですが、やはりいくつかのブラウザでのサポートは不明で、パフォーマンスが心配されます。

MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
// create an observer instance
var observer = new MutationObserver(function (mutations) {
    mutations.forEach(function (mutation) {
        $(mutation.addedNodes).popover(popOverSettings);
    });
});

// configuration of the observer:
var config = {
     attributes: true, 
     childList: true, 
     characterData: true
};

// pass in the target node, as well as the observer options
observer.observe($('ul')[0], config);

デモ