How to bind bootstrap popover on dynamic elements

那年仲夏 提交于 2019-11-26 05:57:39

问题


I\'m using Twitter Bootstrap\'s popover on the dynamic list. The list item has a button, when I click the button, it should show up popover. It works fine when I tested on non-dynamic.

this is my JavaScript for non-dynamic list

$(\"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();
});

However, It doesn\'t work well on dynamic list. It can show up when I click the button \"twice\" and only show up one of list items I click fist time.

MY 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>

My JavaScript for dynamic:

$(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\');
 });

I have searched similar problems, but I still can\'t find the one to solve my problem. If anyone has some ideas, please let me know. Thanks your help.


回答1:


Update

If your popover is going to have a selector that is consistent then you can make use of selector property of popover constructor.

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

Other ways:

  1. (Standard Way) Bind the popover again to the new items being inserted. Save the popoversettings in an external variable.
  2. Use Mutation Event/Mutation Observer to identify if a particular element has been inserted on to the ul or an element.

Source

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

But it is not recommended to use DOMNodeInserted Mutation Event for performance issues as well as support. This has been deprecated as well. So your best bet would be to save the setting and bind after you update with new element.

Demo

Another recommended way is to use MutationObserver instead of MutationEvent according to MDN, but again support in some browsers are unknown and performance a concern.

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




回答2:


Probably way too late but this is another option:

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



回答3:


I did this and it works for me. "content" is placesContent object. not the html content!

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>



回答4:


try this 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();
        }
    });
  });
});

hope it help, happy coding!



来源:https://stackoverflow.com/questions/16990573/how-to-bind-bootstrap-popover-on-dynamic-elements

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!