jQuery 如何在动态元素上绑定引导弹出窗口

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16990573/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 18:13:27  来源:igfitidea点击:

How to bind bootstrap popover on dynamic elements

javascriptjquerydomtwitter-bootstrappopover

提问by user2150267

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.

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

this is my JavaScript for non-dynamic list

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

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:

我的 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:

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

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.

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

回答by PSL

Update

更新

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

如果您的 popover 将有一个一致的选择器,那么您可以使用selectorpopover 构造函数的属性。

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 Observerto identify if a particular element has been inserted on to the ulor an element.
  1. 标准方式)再次将弹出框绑定到正在插入的新项目。将 popoversettings 保存在外部变量中。
  2. 使用Mutation Event/Mutation Observer来标识特定元素是否已插入到ul或 元素上。

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 DOMNodeInsertedMutation Event for performance issues as well as support. This has been deprecatedas well. So your best bet would be to save the setting and bind after you update with new element.

但是不建议使用DOMNodeInsertedMutation Event 来解决性能问题以及支持。这也已被弃用。因此,最好的办法是在使用新元素更新后保存设置并绑定。

Demo

演示

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

另一种推荐的方法是根据 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

演示

回答by Cipriano

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

回答by nurp

I did this and it works for me. "content" is placesContent object. not the html 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>

回答by Somwang Souksavatd

try this HTML

试试这个 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:

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!

希望它有所帮助,快乐编码!