web-dev-qa-db-ja.com

動的要素にbootstrapポップオーバーをバインドする方法

動的リストで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つのみが表示されます。

私の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');
 });

同様の問題を検索しましたが、問題を解決するものがまだ見つかりません。誰かアイデアがあれば、教えてください。ご協力ありがとうございます。

47
user2150267

更新

ポップオーバーに一貫性のあるセレクターがある場合は、ポップオーバーコンストラクターの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. Standard Way)挿入される新しいアイテムにポップオーバーを再度バインドします。 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の代わりに MutationObserver を使用することですが、一部のブラウザーでのサポートも不明であり、パフォーマンスが懸念されます。

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);

デモ

83
PSL

おそらく手遅れですが、これは別のオプションです:

 $('body').popover({
    selector: '[rel=popover]',
    trigger: 'hover',
    html: true,
    content: function () {
        return $(this).parents('.row').first().find('.metaContainer').html();
    }
});
11
Cipriano

私はこれをしました、そしてそれは私のために働きます。 「コンテンツ」はplacesContentオブジェクトです。 HTMLコンテンツではありません!

var placesContent = $('#placescontent');
$('#places').popover({
        trigger: "click",
        placement: "bottom",
        container: 'body',
        html : true,
        content : placesContent,
    });

$('#places').on('shown.bs.popover', function(){
  $('#addPlaceBtn').on('click', addPlace);
}
<div id="placescontent"><div id="addPlaceBtn">Add</div></div>
6
nurp

このHTMLを試してください

<a href="#" data-toggle="popover" data-popover-target="#popover-content-1">Do Popover 1</a>
<a href="#" data-toggle="popover" data-popover-target="#popover-content-2">Do Popover</a>

<div id="popover-content-1" style="display: none">Content 1</div>
<div id="popover-content-2" style="display: none">Content 2</div>

jQuery:

$(function() {
  $('[data-toggle="popover"]').each(function(i, obj) {
    var popover_target = $(this).data('popover-target');
    $(this).popover({
        html: true,
        trigger: 'focus',
        placement: 'right',
        content: function(obj) {
            return $(popover_target).html();
        }
    });
  });
});

それが役立つことを願って、幸せなコーディング!

2