将事件处理程序附加到twitter bootstrap popover中的按钮

时间:2012-11-03 01:25:06

标签: javascript jquery twitter-bootstrap event-handling popover

我正在使用twitter bootstrap popovers,

在popover中我添加了一个按钮,

我需要在按钮上附加click处理程序, 但popover工作的方式是每次它显示它删除并重新创建元素,而不是只显示/隐藏它,因此删除我与所述按钮关联的任何事件处理程序。

我正在用自己的按钮版本创建几个弹出窗口,所以只是将一个类应用于弹出窗口将不起作用(除非我为每个生成一个不同的类:/),该按钮可能有也可能没有它是自己的ID,因此无法应用ID。

如何将事件处理程序应用于twitter bootstrap popover内容中的某些内容?

7 个答案:

答案 0 :(得分:35)

我遇到了同样的问题,在我的情况下,$(body).on('click')解决方法不起作用,因为应用程序有批量点击按钮。

我改为做了以下事情。这样,我们可以将委托事件的范围限制为popover元素的父级。

$('a.foo').popover({
    html: true,
    title: 'Hello',
    placement: 'bottom',
    content: '<button id="close-me">Close Me!</button>'
}).parent().delegate('button#close-me', 'click', function() {
    console.log('World!');
});

JS小提琴:http://jsfiddle.net/dashk/5Yz7z/

P.S。我在我的应用程序中的Backbone.View内使用了这种技术。以下是Fiddle中代码的片段,以防您在Backbone.js中使用此代码...:http://jsfiddle.net/dashk/PA6wY/

EDITED 在Bootstrap 2.3中,您可以指定将添加弹出窗口的目标容器。现在,您不仅可以执行.parent()定位器,还可以专门监听容器...这可以使侦听器更具体(想象一下创建一个仅存在以包含弹出窗口的DIV。)

答案 1 :(得分:26)

这应该这样做。这将处理使用.popover类在元素内创建的任何现有和将来的按钮元素:

$('body').on('click', '.popover button', function () {
    // code here
});

答案 2 :(得分:10)

稍微更新DashK非常好的答案:.delegate()自jQuery 1.7起已被.on()取代(参见here)。

$('a.foo').popover({
    html: true,
    title: 'Hello',
    placement: 'bottom',
    content: '<button id="close-me">Close Me!</button>'
}).parent().on('click', 'button#close-me', function() {
    console.log('World!');
});

请在此处查看jsfiddle:http://jsfiddle.net/smingers/nCKxs/2/

我还有一些将.on()方法链接到$('a.foo')的问题;如果您遇到此类问题,请尝试将其添加到文档,正文或html中,例如:

$('a.foo').popover({
    html: true,
    title: 'Hello',
    placement: 'bottom',
    content: '<button id="close-me">Close Me!</button>'
});

$('body').on('click', 'button#close-me', function() {
    console.log('World!');
});

答案 3 :(得分:9)

对我有用的非常简单的解决方案是:

// suppose that popover is defined in HTML
$('a.foo').popover(); 

// when popover's content is shown
$('a.foo').on('shown.bs.popover', function() {
    // set what happens when user clicks on the button
    $("#my-button").on('click', function(){
        alert("clicked!!!");
    });
});

// when popover's content is hidden
$('a.foo').on('hidden.bs.popover', function(){
    // clear listeners
    $("#my-button").off('click');
});

为什么会这样: 基本上,popover的内容在打开popover之前没有监听器。

当显示popover时,bootstrap会触发其事件shown.bs.popover。我们可以使用jQuery $(a.foo)方法将此事件的事件处理程序附加到on。因此,当显示popover时,将调用处理程序(回调)函数。在此回调中,我们可以将事件处理程序附加到弹出窗口的内容中 - 例如:当用户单击弹出窗口中的此按钮时会发生什么。

关闭popover后,最好将所有附加的处理程序移除到popover的内容中。这是通过hidden.bs.popover处理程序完成的,该处理程序使用jQuery .off方法删除处理程序。这可以防止弹出窗口中的事件处理程序在再次打开弹出框时被调用两次(和更多)...

答案 4 :(得分:1)

如果在popover的内容中添加更复杂的结构(例如外部组件),则可能会遇到麻烦。对于这种情况,这应该可以解决问题。

var content = $('<button>Bingo?</button>');
content.on('click', function() {
    alert('Bingo!')
});

$('a.foo').popover({
    html: true,
    content: content
}).on('hidden.bs.popover', function() {
    content.detach(); # this will remove content nicely before the popover removes it
});

答案 5 :(得分:0)

试试这个

var content = function() {
    var button = $($.parseHTML("<button id='foo'>bar</button>"));
    button.on('click', '#foo', function() {
        console.log('you clicked me!');
    } );
    return button;
};

$( '#new_link' ).popover({
    "html": true,
    "content": content,
});

答案 6 :(得分:0)

$('.btn-popover').parent().delegate('button#close-me','click', function(){
  alert('Hello');
});

如果在静态html中设置了数据属性,则上述方法可以正常工作。谢谢:))