关于javascript:如何在动态元素上绑定引导弹出窗口

How to bind bootstrap popover on dynamic elements

我正在动态列表上使用Twitter Bootstrap的弹出窗口。 列表项有一个按钮,当我单击该按钮时,它将显示弹出窗口。 当我在非动态环境下进行测试时,它可以正常工作。

这是我的非动态JavaScript代码

1
2
3
4
5
6
7
8
9
10
11
12
13
$("button[rel=popover]").popover({
    placement : 'right',
    container : 'body',
    html : true,
    //content:" This is your div content"
    content: function() {
      return $('#popover-content').html();
    }

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

但是,它在动态列表上效果不佳。 当我单击"两次"按钮时,它可以显示,并且仅显示我单击第一时间的列表项之一。

我的HTML:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 <ul id="project-list" class="nav nav-list">
   <li class='project-name'>
     project name 1
         <button class="pop-function" rel="popover"></button>
     
   
</li>

   <li class='project-name'>
     project name 2
        <button class="pop-function" rel="popover"></button>
     
   
</li>


 
</ul>



    <button class="pop-sync"></button>
    <button class="pop-delete"></button>

我的动态JavaScript:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
$(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');
 });

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


更新资料

如果弹出窗口的选择器是一致的,则可以使用popover构造函数的selector属性。

1
2
3
4
5
6
7
8
9
10
11
var popOverSettings = {
    placement: 'bottom',
    container: 'body',
    html: true,
    selector: '[rel="popover"]', //Sepcify the selector here
    content: function () {
        return $('#popover-content').html();
    }
}

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

演示版

其他方法:

  • (标准方式)再次将弹出框绑定到要插入的新项目。将popoversettings保存在一个外部变量中。
  • 使用Mutation Event / Mutation Observer标识是否已将特定元素插入到ul或元素上。
  • 资源

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    var popOverSettings = { //Save the setting for later use as well
        placement: 'bottom',
        container: 'body',
        html: true,
        //content:" This is your div content"
        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'>     project name 2        <button class='pop-function' rel='popover'></button>        
    </li>
    "
    );
    });

    但是不建议将DOMNodeInserted Mutation Event用于性能问题和支持。也已弃用此方法。因此,最好的选择是保存设置并在使用新元素更新后绑定。

    演示版

    另一种推荐的方法是根据MDN使用MutationObserver而不是MutationEvent,但是同样,某些浏览器中的支持还是未知的,并且性能令人担忧。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    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);

    演示版


    可能为时已晚,但这是另一种选择:

    1
    2
    3
    4
    5
    6
    7
    8
     $('body').popover({
        selector: '[rel=popover]',
        trigger: 'hover',
        html: true,
        content: function () {
            return $(this).parents('.row').first().find('.metaContainer').html();
        }
    });


    我做到了,对我有用。
    "内容"是placesContent对象。不是html内容!

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    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);
    }

    1
    Add

    试试这个HTML

    1
    2
    3
    4
    5
    Do Popover 1
    Do Popover

    Content 1
    Content 2

    jQuery的:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    $(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();
            }
        });
      });
    });

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

    HTML:

    1
     

    jQuery的:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    $(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
                });
             });
         }
    });