(function() { 'use strict'; var TooltipManager = function (element) { this.element = $(element); // If tooltip container already exist, use it. this.tooltip = $('div.' + this.className.split(/\s+/).join('.')); // Otherwise, create new one. if (!this.tooltip.length) { this.tooltip = $('<div />', { 'class': this.className }).appendTo(this.element); } this.hide(); _.bindAll(this); this.bindEvents(); }; TooltipManager.prototype = { // Space separated list of class names for the tooltip container. className: 'tooltip', SELECTOR: '[data-tooltip]', bindEvents: function () { this.element.on({ 'mouseover.TooltipManager': this.showTooltip, 'mousemove.TooltipManager': this.moveTooltip, 'mouseout.TooltipManager': this.hideTooltip, 'click.TooltipManager': this.click }, this.SELECTOR); }, getCoords: function (pageX, pageY) { return { 'left': pageX - 0.5 * this.tooltip.outerWidth(), 'top': pageY - (this.tooltip.outerHeight() + 15) }; }, show: function () { this.tooltip.show().css('opacity', 1); }, hide: function () { this.tooltip.hide().css('opacity', 0); }, showTooltip: function(event) { this.prepareTooltip(event.currentTarget, event.pageX, event.pageY); if (this.tooltipTimer) { clearTimeout(this.tooltipTimer); } this.tooltipTimer = setTimeout(this.show, 500); }, prepareTooltip: function(element, pageX, pageY) { pageX = typeof pageX !== 'undefined' ? pageX : element.offset().left + element.width()/2; pageY = typeof pageY !== 'undefined' ? pageY : element.offset().top + element.height()/2; var tooltipText = $(element).attr('data-tooltip'); this.tooltip .html(tooltipText) .css(this.getCoords(pageX, pageY)); }, // To manually trigger a tooltip to reveal, other than through user mouse movement: openTooltip: function(element) { this.prepareTooltip(element); this.show(); if (this.tooltipTimer) { clearTimeout(this.tooltipTimer); } }, moveTooltip: function(event) { this.tooltip.css(this.getCoords(event.pageX, event.pageY)); }, hideTooltip: function() { clearTimeout(this.tooltipTimer); // Wait for a 50ms before hiding the tooltip to avoid blinking when // the item contains nested elements. this.tooltipTimer = setTimeout(this.hide, 50); }, click: function(event) { var showOnClick = !!$(event.currentTarget).data('tooltip-show-on-click'); // Default is false if (showOnClick) { this.show(); if (this.tooltipTimer) { clearTimeout(this.tooltipTimer); } } else { this.hideTooltip(event); } }, destroy: function () { this.tooltip.remove(); // Unbind all delegated event handlers in the ".TooltipManager" // namespace. this.element.off('.TooltipManager', this.SELECTOR); } }; window.TooltipManager = TooltipManager; $(document).ready(function () { window.globalTooltipManager = new TooltipManager(document.body); }); }());