Clone and restore "tooltiped" elements
You need to call the tooltip()
method again. Optionally you should destroy the tooltip before cloning / removing the item for cleaning up the data.
Working Fiddle
$('footer p').tooltip();
$('#destroy').click(function(){
// optionally remove bindings
$('footer p').tooltip('destroy');
window.backup = $('footer').clone();
$('footer p').remove();
})
$('#restore').click(function(){
$('footer').replaceWith(window.backup);
// apply tooltip again
//window.backup.find("p").tooltip();
$('footer p').tooltip();
});
For the scenario you've shown in your question, I would use $().detach()
to remove it from the DOM while at the same time keeping the event handlers and the data added to it with $().data()
intact. In terms of the fiddle you've put in the question:
$('#destroy').click(function(){
var $footer_p = $('footer p');
window.backup = $footer_p;
$footer_p.detach();
})
$('#restore').click(function(){
var $footer = $('footer');
$footer.append(window.backup);
});
Here's an updated fiddle
What happens behind the scenes is that Bootstrap uses $().data()
to add a JavaScript object of class Tooltip
to your DOM element, and adds a bunch of event handlers. You need to preserve these.
If for some reason, you cannot use $().detach()
, then you would have to recreate the tooltip by calling $().tooltip()
.
Why is $().clone(true, true)
not working?
You call $().clone()
with parameters to deep clone the DOM hierarchy and preserve the event handlers and the data set with $().data()
so why is it not working? Is it not the case that the clone should have a reference to the Tooltip
object created by Bootstrap?
Yes, the event handlers are preserved, and the clone does have a reference to the Tooltip
object. However, this object it itself not cloned. More importantly, it is not adapted to refer to the new DOM node created by $().clone()
. (So even if jQuery would clone it, it would still not work.) It does receive the event that would trigger the tooltip but Tooltip.prototype.show
performs this check:
var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])
if (e.isDefaultPrevented() || !inDom) return
The inDom
variable will be true if this.$element
is in the DOM. However, this refers to the original element for which the tooltip was created, not the clone. Since that element is no longer in the DOM, then inDom
is false and the next line returns, so the tooltip is never shown.
For giggles, take a clone of a DOM element on which you created a Bootstrap tooltip, do not remove the original element but add the clone somewhere else on the page. Then trigger the tooltip on the clone. The tooltip will appear on the original element. :)
What I described above is the general way Bootstrap's jQuery plugins work: they use $().data()
to add JavaScript objects to the elements on which they operate. There's also a Dropdown
class for dropdowns, a Modal
class for modals, etc.