Demo-Component/media/uikit-v2/js/components/tooltip.js

236 lines
7.9 KiB
JavaScript

/*! UIkit 2.27.5 | http://www.getuikit.com | (c) 2014 YOOtheme | MIT License */
(function(addon) {
var component;
if (window.UIkit2) {
component = addon(UIkit2);
}
if (typeof define == 'function' && define.amd) {
define('uikit-tooltip', ['uikit'], function(){
return component || addon(UIkit2);
});
}
})(function(UI){
"use strict";
var $tooltip, // tooltip container
tooltipdelay, checkIdle;
UI.component('tooltip', {
defaults: {
offset: 5,
pos: 'top',
animation: false,
delay: 0, // in miliseconds
cls: '',
activeClass: 'uk-active',
src: function(ele) {
var title = ele.attr('title');
if (title !== undefined) {
ele.data('cached-title', title).removeAttr('title');
}
return ele.data("cached-title");
}
},
tip: '',
boot: function() {
// init code
UI.$html.on('mouseenter.tooltip.uikit focus.tooltip.uikit', '[data-uk-tooltip]', function(e) {
var ele = UI.$(this);
if (!ele.data('tooltip')) {
UI.tooltip(ele, UI.Utils.options(ele.attr('data-uk-tooltip')));
ele.trigger('mouseenter');
}
});
},
init: function() {
var $this = this;
if (!$tooltip) {
$tooltip = UI.$('<div class="uk-tooltip"></div>').appendTo("body");
}
this.on({
focus : function(e) { $this.show(); },
blur : function(e) { $this.hide(); },
mouseenter : function(e) { $this.show(); },
mouseleave : function(e) { $this.hide(); }
});
},
show: function() {
this.tip = typeof(this.options.src) === 'function' ? this.options.src(this.element) : this.options.src;
if (tooltipdelay) clearTimeout(tooltipdelay);
if (checkIdle) clearInterval(checkIdle);
if (typeof(this.tip) === 'string' ? !this.tip.length:true) return;
$tooltip.stop().css({top: -2000, visibility: 'hidden'}).removeClass(this.options.activeClass).show();
$tooltip.html('<div class="uk-tooltip-inner">' + this.tip + '</div>');
var $this = this,
pos = UI.$.extend({}, this.element.offset(), {width: this.element[0].offsetWidth, height: this.element[0].offsetHeight}),
width = $tooltip[0].offsetWidth,
height = $tooltip[0].offsetHeight,
offset = typeof(this.options.offset) === "function" ? this.options.offset.call(this.element) : this.options.offset,
position = typeof(this.options.pos) === "function" ? this.options.pos.call(this.element) : this.options.pos,
tmppos = position.split("-"),
tcss = {
display : 'none',
visibility : 'visible',
top : (pos.top + pos.height + height),
left : pos.left
};
// prevent strange position
// when tooltip is in offcanvas etc.
if (UI.$html.css('position')=='fixed' || UI.$body.css('position')=='fixed'){
var bodyoffset = UI.$('body').offset(),
htmloffset = UI.$('html').offset(),
docoffset = {top: (htmloffset.top + bodyoffset.top), left: (htmloffset.left + bodyoffset.left)};
pos.left -= docoffset.left;
pos.top -= docoffset.top;
}
if ((tmppos[0] == 'left' || tmppos[0] == 'right') && UI.langdirection == 'right') {
tmppos[0] = tmppos[0] == 'left' ? 'right' : 'left';
}
var variants = {
bottom : {top: pos.top + pos.height + offset, left: pos.left + pos.width / 2 - width / 2},
top : {top: pos.top - height - offset, left: pos.left + pos.width / 2 - width / 2},
left : {top: pos.top + pos.height / 2 - height / 2, left: pos.left - width - offset},
right : {top: pos.top + pos.height / 2 - height / 2, left: pos.left + pos.width + offset}
};
UI.$.extend(tcss, variants[tmppos[0]]);
if (tmppos.length == 2) tcss.left = (tmppos[1] == 'left') ? (pos.left) : ((pos.left + pos.width) - width);
var boundary = this.checkBoundary(tcss.left, tcss.top, width, height);
if(boundary) {
switch(boundary) {
case 'x':
if (tmppos.length == 2) {
position = tmppos[0]+"-"+(tcss.left < 0 ? 'left': 'right');
} else {
position = tcss.left < 0 ? 'right': 'left';
}
break;
case 'y':
if (tmppos.length == 2) {
position = (tcss.top < 0 ? 'bottom': 'top')+'-'+tmppos[1];
} else {
position = (tcss.top < 0 ? 'bottom': 'top');
}
break;
case 'xy':
if (tmppos.length == 2) {
position = (tcss.top < 0 ? 'bottom': 'top')+'-'+(tcss.left < 0 ? 'left': 'right');
} else {
position = tcss.left < 0 ? 'right': 'left';
}
break;
}
tmppos = position.split('-');
UI.$.extend(tcss, variants[tmppos[0]]);
if (tmppos.length == 2) tcss.left = (tmppos[1] == 'left') ? (pos.left) : ((pos.left + pos.width) - width);
}
tcss.left -= UI.$body.position().left;
tooltipdelay = setTimeout(function(){
$tooltip.css(tcss).attr('class', ['uk-tooltip', 'uk-tooltip-'+position, $this.options.cls].join(' '));
if ($this.options.animation) {
$tooltip.css({opacity: 0, display: 'block'}).addClass($this.options.activeClass).animate({opacity: 1}, parseInt($this.options.animation, 10) || 400);
} else {
$tooltip.show().addClass($this.options.activeClass);
}
tooltipdelay = false;
// close tooltip if element was removed or hidden
checkIdle = setInterval(function(){
if(!$this.element.is(':visible')) $this.hide();
}, 150);
}, parseInt(this.options.delay, 10) || 0);
},
hide: function() {
if (this.element.is('input') && this.element[0]===document.activeElement) return;
if (tooltipdelay) clearTimeout(tooltipdelay);
if (checkIdle) clearInterval(checkIdle);
$tooltip.stop();
if (this.options.animation) {
var $this = this;
$tooltip.fadeOut(parseInt(this.options.animation, 10) || 400, function(){
$tooltip.removeClass($this.options.activeClass)
});
} else {
$tooltip.hide().removeClass(this.options.activeClass);
}
},
content: function() {
return this.tip;
},
checkBoundary: function(left, top, width, height) {
var axis = "";
if(left < 0 || ((left - UI.$win.scrollLeft())+width) > window.innerWidth) {
axis += "x";
}
if(top < 0 || ((top - UI.$win.scrollTop())+height) > window.innerHeight) {
axis += "y";
}
return axis;
}
});
return UI.tooltip;
});