2012-11-03 4 views
23

ich den Twitter Bootstrap popovers verwenden,Attach-Ereignishandler Schaltfläche in twitter Bootstrap popover

Im popover Ich füge einen Knopf,

Ich brauche einen click Handler auf den Knopf zu befestigen, aber Die Art, wie Popover funktioniert, ist jedes Mal, wenn es anzeigt, dass das Element entfernt und neu erstellt wird, anstatt es nur anzuzeigen/zu verbergen, wodurch alle Event-Handler entfernt werden, die mit dem Button verknüpft sind.

Ich erstelle mehrere Popovers alle mit ihrer eigenen Version der Schaltfläche, so nur eine Klasse auf das Popover anwenden wird nicht funktionieren (es sei denn, ich erzeuge eine andere Klasse für jeden: /), die Schaltfläche möglicherweise oder nicht Es hat eine eigene ID, kann also keine ID anwenden.

Wie kann ich einen Event-Handler auf etwas im Inhalt des Twitter-Bootstrap-Popover anwenden?

+0

Sie haben zwei Möglichkeiten. # 1: Binden Sie es erneut, nachdem das Popover geöffnet wurde, oder # 2 binden Sie es mithilfe der Ereignisdelegierung. Was muss der Button tun? –

+0

Viele verschiedene Dinge, einige senden Formulare (via js), einige einfach schließen das Popover, – Hailwood

Antwort

35

ich hatte das gleiche Problem, und in meinem Fall, die $(body).on('click') Abhilfe wird nicht funktionieren, da die Anwendung hat viele Klick-Schaltflächen.

Ich habe stattdessen Folgendes getan. Auf diese Weise können wir den Umfang des Delegate-Ereignisses auf das übergeordnete Element des Popover-Elements beschränken.

$('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. Ich habe diese Technik innerhalb einer Backbone.View in meiner Anwendung verwendet. Hier ist der Ausschnitt aus dem Code in Fiddle, falls Sie dies in Backbone.js auch verwenden ...: http://jsfiddle.net/dashk/PA6wY/

EDITED In Bootstrap 2.3 können Sie einen Zielcontainer festlegen, welche popover wird hinzugefügt werden. Anstatt den parent() - Locator zu verwenden, können Sie auch speziell auf den Container gerichtete Ereignisse abhören ... Dies kann den Listener noch spezifischer machen (Stellen Sie sich vor, Sie erstellen ein DIV, das nur das Popover enthält.)

+0

Große Antwort für Versionen vor 2.3, benutzte dieses für 2.1.1 und es funktionierte gut. – mccainz

26

Dies sollte es tun. Diese kümmert sich um jegliche bestehenden und zukünftigen Schaltfläche Elemente innerhalb eines Elements mit der .popover Klasse erstellt:

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

Das wird nur funktionieren, wenn ich will, dass alle Tasten das gleiche tun – Hailwood

+0

Richtig, tut mir leid, ich habe gerade diesen Punkt in Dein ursprünglicher Beitrag. Gibt es einen Grund, warum Sie nicht jedem Popover eine bestimmte Klasse zuweisen können? – manishie

+0

Große Antwort !!!! Ich habe stundenlang nach diesem gesucht :) – adamdehaven

0

versuchen diese

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

Wenn Datenattribute in statische hTML gesetzt sind die obige Methode funktioniert gut. Danke :)

9

Nur leicht zu aktualisieren DashK 's sehr gute Antwort: .delegate() wurde von .on() ab jQuery 1.7 ersetzt (siehe 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!'); 
}); 

Siehe jsfiddle hier: http://jsfiddle.net/smingers/nCKxs/2/

Ich habe auch mit Chaining die .on() -Methode auf $ hatte einige Probleme ('a.foo'); Wenn Sie ein solches Problem auftritt, versuchen Sie es zu dem Dokument, Körper hinzufügen oder html, z.B .:

$('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!'); 
}); 
+0

Aufbauend auf dieser Antwort in ähnlicher Weise, dies für mich gearbeitet, aber auch: '$ ('a.foo') popover ({ html:. Wahr, Titel: 'Hallo', Platzierung:‚bottom ', Inhalt:' ' }). Eltern (' body '). On (' klicken ',' button # schließen-mich ', funktion() { console.log ('Popover-Taste geklickt!'); }); ' – tofirius

1

Sie in Schwierigkeiten geraten können, wenn Sie komplexere Struktur in popover Inhalt hinzufügen, zum Beispiel eine externe Komponente. Für diesen Fall sollte dies den Zweck erfüllen.

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

Sehr einfache Lösung, die für mich gearbeitet ist:

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

Warum dies funktioniert: Grundsätzlich popover Inhalt hat keinen Zuhörer, bis der popover geöffnet wird.

Wenn Popover angezeigt wird, löst Bootstrap sein Ereignis shown.bs.popover aus. Wir können einen Ereignishandler für dieses Ereignis an $(a.foo) mit der Methode jQuery on anhängen. Wenn Popover angezeigt wird, wird die Handler (Callback) -Funktion aufgerufen. In diesem Callback können wir Event-Handler an den Inhalt des Popover anhängen - zum Beispiel: Was passiert, wenn der Benutzer auf diesen Button im Popover klickt.

Nachdem das Popover geschlossen wurde, ist es eine gute Idee, alle angehängten Handler zum Inhalt des Popovers zu entfernen. Dies geschieht über den Handler hidden.bs.popover, der Handler mit der Methode jQuery .off entfernt. Dies verhindert, dass Ereignishandler innerhalb des Popover zweimal (und mehr) aufgerufen werden, wenn das Popover erneut geöffnet wird ...

+0

Es wäre gut, wenn Sie erklären könnten, warum das funktioniert. Ansonsten nette Antwort! – ArtOfCode

+0

Danke. Erklärung hinzugefügt, hoffe es hilft ;-) – mrtn