web-dev-qa-db-fra.com

Attacher un gestionnaire d’événements au bouton de la popover bootstrap de Twitter

J'utilise les popovers bootstrap de Twitter,

Dans le popover j'ajoute un bouton,

Je dois attacher un gestionnaire click au bouton, .__, mais la façon dont fonctionne popover est de montrer à chaque fois qu'il supprime et recrée l'élément, au lieu de simplement afficher/masquer, supprimant ainsi tous les gestionnaires d'événements auxquels j'ai ledit bouton.

Je crée plusieurs popovers, chacun avec sa propre version du bouton. Il ne suffit donc pas d'appliquer une classe à la popover (à moins que je ne génère une classe différente pour chaque classe: /), le bouton peut avoir ou non son propre ID. , donc ne peut pas appliquer un ID.

Comment puis-je appliquer un gestionnaire d'événements à quelque chose dans le contenu du popover bootstrap de Twitter?

24
Hailwood

J'ai eu le même problème, et dans mon cas, la solution de contournement $(body).on('click') ne fonctionnera pas, car l'application doit cliquer sur des boutons.

J'ai fait le suivant à la place. De cette façon, nous pouvons limiter la portée de l'événement délégué au seul parent de l'élément 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 Fiddle: http://jsfiddle.net/dashk/5Yz7z/

P.S. J'ai utilisé cette technique dans un Backbone.View dans mon application. Voici l'extrait du code dans Fiddle, si vous l'utilisez également dans Backbone.js ...: http://jsfiddle.net/dashk/PA6wY/

EDITEDIn Bootstrap 2.3, vous pouvez spécifier un conteneur cible auquel popover sera ajouté. Maintenant, au lieu d'utiliser le localisateur .parent (), vous pouvez également écouter des événements spécifiques au conteneur ... Cela peut rendre l'écouteur encore plus spécifique (imaginez créer un DIV qui n'existe que pour contenir le popover.)

35
DashK

Cela devrait le faire. Cela prendra en charge tous les éléments de bouton existants et futurs créés dans un élément avec la classe .popover:

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

Juste pour mettre légèrement à jour la très bonne réponse de DashK : .delegate () a été remplacé par .on () à partir de jQuery 1.7 (voir 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!');
});

Voir jsfiddle ici: http://jsfiddle.net/smingers/nCKxs/2/

J'ai également eu quelques problèmes avec l'enchaînement de la méthode .on () à $ ('a.foo'); Si vous rencontrez un tel problème, essayez de l'ajouter au document, au corps ou au code HTML, par exemple:

$('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!');
});
10
smingers

La solution très simple qui a fonctionné pour moi est la suivante:

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

Pourquoi cela fonctionne: Fondamentalement, le contenu de popover n'a aucun écouteur jusqu'à ce que le popover soit ouvert.

Lorsque popover est affiché, bootstrap déclenche son événement shown.bs.popover. Nous pouvons attacher un gestionnaire d'événements sur cet événement à $(a.foo) à l'aide de la méthode jQuery on. Ainsi, lorsque popover est affiché, la fonction handler (callback) est appelée. Dans ce rappel, nous pouvons attacher des gestionnaires d'événements au contenu du popover - par exemple: que se passe-t-il lorsque l'utilisateur clique sur ce bouton dans le popover?.

Une fois Popover fermé, il est judicieux de supprimer tous les gestionnaires attachés au contenu de Popover. Cela se fait via le gestionnaire hidden.bs.popover, qui supprime les gestionnaires avec la méthode jQuery .off. Cela évite que les gestionnaires d'événements à l'intérieur du popover soient appelés deux fois (et plus) lorsque le popover est ouvert à nouveau ...

9
mrtn

Vous pouvez avoir des problèmes si vous ajoutez une structure plus complexe dans le contenu de popover, par exemple un composant externe. Dans ce cas, cela devrait faire l'affaire.

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
});
1
Patrik Šimek
$('.btn-popover').parent().delegate('button#close-me','click', function(){
  alert('Hello');
});

Si les attributs de données sont définis en HTML statique, la méthode ci-dessus fonctionne correctement. Merci :)

0
Sandeep

essaye ça

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,
});
0
wahhzu