如何在动态元素上绑定bootstrap popover

时间:2013-06-07 18:21:41

标签: javascript jquery dom twitter-bootstrap popover

我在动态列表中使用Twitter Bootstrap的popover。列表项有一个按钮,当我单击按钮时,它应该显示弹出窗口。当我在非动态测试时,它工作正常。

这是我的非动态列表的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();
});

但是,它在动态列表上效果不佳。当我单击“两次”按钮时,它会显示出来,只显示一个列表项我点击一次。

我的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');
 });

我搜索过类似的问题,但我仍然找不到解决问题的方法。如果有人有想法,请告诉我。谢谢你的帮助。

5 个答案:

答案 0 :(得分:82)

<强>更新

如果您的popover将具有一致的选择器,那么您可以使用popover构造函数的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);

<强> Demo

其他方式:

  1. 标准方式)再次将弹出窗口绑定到要插入的新项目。将popoversettings保存在外部变量中。
  2. 使用Mutation Event / Mutation Observer来确定特定元素是否已插入ul或元素。
  3. 来源

    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来解决性能问题和支持。这也是deprecated。因此,最好的办法是在使用新元素更新后保存设置和绑定。

    Demo

    另一种推荐的方法是根据MDN使用MutationObserver而不是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);
    

    Demo

答案 1 :(得分:11)

可能太晚了,但这是另一种选择:

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

答案 2 :(得分:6)

我这样做了,对我有用。 “content”是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>

答案 3 :(得分:2)

尝试此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();
        }
    });
  });
});

希望对您有所帮助,祝您编程愉快!

答案 4 :(得分:0)

这就是我编写代码的方式,以便它可以使用弹出框功能处理动态创建的元素。使用此代码,您可以触发弹出窗口以默认显示。

HTML:

<div rel="this-should-be-the-target">
</div>

jQuery:

$(function() {
    var targetElement = 'rel="this-should-be-the-target"';
    initPopover(targetElement, "Test Popover Content");

    // use this line if you want it to show by default
    $(targetElement).popover('show');
    
    function initPopover(target, popOverContent) {
        $(target).each(function(i, obj) {
            $(this).popover({
                placement : 'auto',
                trigger : 'hover',
                "html": true,
                content: popOverContent
            });
         });
     }
});