Ai
3 Star 0 Fork 1

Gitee 极速下载/html5tooltips-js

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
此仓库是为了提升国内下载速度的镜像仓库,每日同步一次。 原始仓库: https://github.com/ytiurin/html5tooltipsjs
克隆/下载
html5tooltips.js 20.08 KB
一键复制 编辑 原始数据 按行查看 历史
Eugene Tiurin 提交于 2018-07-08 05:45 +08:00 . Version 1.7.3
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753
/*
* Tooltips with smooth 3D animation.
* (c) Eugene Tiurin; MIT license
*
* Contributors: nomiad, Friedel Ziegelmayer, Arend van Beelen jr.,
* Peter Richmond, Bruno Wego, Kahmali Rose, Axosoft-Ashley, Jim Doyle,
* brunobatista
*
* 2018-07-08
*/
(function (root, factory) {
// UNIVERSAL MODULE DEFINITION
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define([], factory);
} else if (typeof module === 'object' && module.exports) {
// Node. Does not work with strict CommonJS, but
// only CommonJS-like environments that support module.exports,
// like Node.
module.exports = factory();
} else {
// Define global constructor
root.html5tooltips = factory();
}
}(this, function () {
'use strict';
var
tooltipHTML='\
<div class="html5tooltip" style="box-sizing:border-box;position:fixed;z-index:2147483647">\
<div class="html5tooltip-box" box>\
<div class="html5tooltip-text" text></div>\
<div class="html5tooltip-more" style="overflow:hidden;" more>\
<div class="html5tooltip-text" more-text></div>\
</div>\
</div>\
</div>\
',
html5tooltipsPredefined = {
animateFunction: {
fadeIn: "fadein",
foldIn: "foldin",
foldOut: "foldout",
roll: "roll",
scaleIn: "scalein",
slideIn: "slidein",
spin: "spin"
},
color: {
"daffodil": {r: 255, g: 230, b: 23},
"daisy": {r: 250, g: 211, b: 28},
"mustard": {r: 253, g: 183, b: 23},
"citrus zest": {r: 250, g: 170, b: 33},
"pumpkin": {r: 241, g: 117, b: 63},
"tangerine": {r: 237, g: 87, b: 36},
"salmon": {r: 240, g: 70, b: 57},
"persimmon": {r: 234, g: 40, b: 48},
"rouge": {r: 188, g: 35, b: 38},
"scarlet": {r: 140, g: 12, b: 3},
"hot pink": {r: 229, g: 24, b: 93},
"princess": {r: 243, g: 132, b: 174},
"petal": {r: 250, g: 198, b: 210},
"lilac": {r: 178, g: 150, b: 199},
"lavender": {r: 123, g: 103, b: 174},
"violet": {r: 95, g: 53, b: 119},
"cloud": {r: 195, g: 222, b: 241},
"dream": {r: 85, g: 190, b: 237},
"gulf": {r: 49, g: 168, b: 224},
"turquoise": {r: 35, g: 138, b: 204},
"sky": {r: 13, g: 96, b: 174},
"indigo": {r: 20, g: 59, b: 134},
"navy": {r: 0, g: 27, b: 74},
"sea foam": {r: 125, g: 205, b: 194},
"teal": {r: 0, g: 168, b: 168},
"peacock": {r: 18, g: 149, b: 159},
"ceadon": {r: 193, g: 209, b: 138},
"olive": {r: 121, g: 145, b: 85},
"bamboo": {r: 128, g: 188, b: 66},
"grass": {r: 74, g: 160, b: 63},
"kelly": {r: 22, g: 136, b: 74},
"forrest": {r: 0, g: 63, b: 46},
"chocolate": {r: 56, g: 30, b: 17},
"terra cotta": {r: 192, g: 92, b: 32},
"camel": {r: 191, g: 155, b: 107},
"linen": {r: 233, g: 212, b: 167},
"stone": {r: 231, g: 230, b: 225},
"smoke": {r: 207, g: 208, b: 210},
"steel": {r: 138, g: 139, b: 143},
"slate": {r: 119, g: 133, b: 144},
"charcoal": {r: 71, g: 77, b: 77},
"black": {r: 5, g: 6, b: 8},
"white": {r: 255, g: 255, b: 255},
"metalic silver": {r: 152, g: 162, b: 171},
"metalic gold": {r: 159, g: 135, b: 89},
"metalic copper": {r: 140, g: 102, b: 65}
},
stickTo: {
bottom: "bottom",
left: "left",
right: "right",
top: "top"
}
},
defaultOptions = {
animateDuration: 300,
animateFunction: html5tooltipsPredefined.animateFunction.fadeIn,
delay: 500,
disableAnimation: false,
hideDelay: 300,
persistent: false,
stickTo: html5tooltipsPredefined.stickTo.bottom,
stickDistance: 10
};
// UI COMPONENT CONSTRUCTOR
function Component(publicInterface,HTML)
{
function toArray(obj,fromIndex)
{
return Array.prototype.slice.call(obj,fromIndex);
}
function argsToObj(args)
{
var argTypes=toArray(args).map(function(a){return typeof a});
var obj={};
if(argTypes[0]==='object')
obj=args[0];
else if(argTypes[0]==='string'){
var keys=args[0].split(' ');
for(var i in keys)
obj[keys[i]]=args[1];
}
else if(argTypes[0]==='function')
obj={'':args[0]};
return obj;
}
function gainAnchorElements(elements,anchors)
{
var attrName;
for(var i=0;i<elements.length;i++){
for(var j=0;j<elements[i].attributes.length;j++){
attrName=elements[i].attributes.item(j).name
//dashToCamel
.replace(/-([a-z])/g,function(g){return g[1].toUpperCase()});
anchors[attrName]=anchors[attrName]||[];
anchors[attrName].push(elements[i]);
}
gainAnchorElements(elements[i].children,anchors)
}
}
function notifyObservers(propName)
{
clearTimeout(notifyTimeoutID[propName]);
notifyTimeoutID[propName]=setTimeout(function(){
for(var i in modelObservers[propName]) {
try {
modelObservers[propName][i](component.model[propName]);
} catch (e) {
}
}
if(modelObservers[''])
for(var i in modelObservers[''])
modelObservers[''][i]();
});
}
var
component=this,
eventCallbacks={},
modelObservers={},
notifyTimeoutID={};
// COMPONENT PROPERTIES
component.anchors=[];
component.elements=[];
component.model={};
component.publ=publicInterface||{};
// COMPONENT INTERFACE
component.destroy=function()
{
component.unmount();
};
component.dispatch=function(eventName){
var args=toArray(arguments,1);
setTimeout(function(){
for(var i in eventCallbacks[eventName])
eventCallbacks[eventName][i].apply(component.publ,args);
});
};
component.onModelUpdate=function(){
var updateCallbacks=argsToObj(arguments);
for(var propName in updateCallbacks){
component.model[propName]=component.model[propName]||null;
modelObservers[propName]=modelObservers[propName]||[];
modelObservers[propName].push(updateCallbacks[propName]);
notifyObservers(propName);
}
};
component.mount=function(parent){
parent = parent || document.body;
try{
var el,i=0;
while(el = component.elements[i++])
parent.appendChild(el);
}
catch(e){
throw "Could not mount component: "+e.message;
}
};
component.set=function(){
var userObj=argsToObj(arguments);
for(var propName in userObj){
component.model[propName]=userObj[propName];
notifyObservers(propName);
}
};
component.unmount=function()
{
var el,i=0;
while(el = component.elements[i++])
el.parentNode&&
el.parentNode.removeChild(el);
};
Object.defineProperty(component,'element',{
configurable:true,
enumerable:true,
get:function(){return component.elements[0]},
set:function(val){component.elements[0]=val}
});
// PUBLIC INTERFACE
['element','elements','model','set']
.forEach(function(propName){
Object.defineProperty(component.publ,propName,{
configurable:true,
enumerable:true,
get:function(){return component[propName]},
set:function(val){component[propName]=val}
});
});
component.publ.destroy=function(){
component.destroy();
};
component.publ.mount=function(parent){
component.mount(parent);
};
component.publ.on=function(){
var userEventCallbacks=argsToObj(arguments);
for(var eventName in userEventCallbacks){
eventCallbacks[eventName]=eventCallbacks[eventName]||[];
eventCallbacks[eventName].push(userEventCallbacks[eventName]);
}
};
component.publ.unmount=function(){
component.unmount();
};
// HTML-> DOM
if(HTML&&document){
var p=document.createElement('div');
p.innerHTML=HTML;
component.elements=toArray(p.children);
gainAnchorElements(component.elements,component.anchors);
}
}
// TOOLTIP UI COMPONENT
function HTML5TooltipUIComponent()
{
function animateElementClass(el, updateHandler)
{
if (!ttModel.disableAnimation) {
// getBoundingClientRect refreshes element render box
el.getBoundingClientRect();
el.classList.add("animating");
updateHandler&&updateHandler();
setTimeout(function() { el.classList.remove("animating"); }, ttModel.animateDuration);
}
else
updateHandler();
}
function applyAnimationClass(el, fromClass, toClass, updateHandler)
{
if (!ttModel.disableAnimation) {
el.classList.add(fromClass);
// getBoundingClientRect refreshes element render box
el.getBoundingClientRect();
el.classList.add("animating");
el.classList.remove(fromClass);
el.classList.add(toClass);
setTimeout(function() {
el.classList.remove("animating");
el.classList.remove(toClass);
if (updateHandler)
updateHandler();
}, ttModel.animateDuration);
}
else
if (updateHandler)
updateHandler();
}
function resetTooltipPosition()
{
if (ttElement.style.visibility !== 'collapse')
ttElement.style.visibility = 'collapse';
ttElement.style.left = '-9999px';
ttElement.style.top = '-9999px';
if (elMore.style.display !== 'none') {
elMore.style.display = 'none';
elMore.style.visibility = 'collapse';
elMore.style.height = 'auto';
}
}
function hide(cb)
{
isHiding = true;
applyAnimationClass(elBox, ttModel.animateFunction + "-to",
ttModel.animateFunction + "-from",
function(){
if(!isHiding)
return;
resetTooltipPosition();
cb&&cb();
});
return this;
}
function moveTooltip()
{
var targetRect, ttRect;
if (!component.model.target||ttElement.style.visibility !== 'visible')
return;
// update width
ttElement.style.width = "auto";
ttRect = ttElement.getBoundingClientRect();
var maxWidth = parseInt(ttModel.maxWidth);
if (maxWidth)
ttElement.style.width = ttRect.width > maxWidth ? maxWidth + "px" : "auto";
// position depend on target and tt width
targetRect = component.model.target.getBoundingClientRect();
ttRect = ttElement.getBoundingClientRect();
switch (ttModel.stickTo) {
case html5tooltipsPredefined.stickTo.bottom:
ttElement.style.left = targetRect.left + parseInt((targetRect.width - ttRect.width) / 2) + "px";
ttElement.style.top = targetRect.top + targetRect.height + parseInt(ttModel.stickDistance) + "px";
break;
case html5tooltipsPredefined.stickTo.left:
ttElement.style.left = targetRect.left - ttRect.width - parseInt(ttModel.stickDistance) + "px";
ttElement.style.top = targetRect.top + (targetRect.height - ttRect.height) / 2 + "px";
break;
case html5tooltipsPredefined.stickTo.right:
ttElement.style.left = targetRect.left + targetRect.width + parseInt(ttModel.stickDistance) + "px";
ttElement.style.top = targetRect.top + (targetRect.height - ttRect.height) / 2 + "px";
break;
case html5tooltipsPredefined.stickTo.top:
ttElement.style.left = targetRect.left + (targetRect.width - ttRect.width) / 2 + "px";
ttElement.style.top = targetRect.top - ttRect.height - parseInt(ttModel.stickDistance) + "px";
break;
}
}
function show()
{
isHiding = false;
if (ttElement.style.visibility !== 'visible') {
ttElement.style.visibility = 'visible';
setTimeout(function(){
moveTooltip();
applyAnimationClass(elBox, ttModel.animateFunction + "-from",
ttModel.animateFunction + "-to");
});
}
return this;
}
function showMore()
{
if (ttElement.style.visibility !== 'visible') {
ttElement.style.visibility = 'visible';
applyAnimationClass(elBox, ttModel.animateFunction + "-from",
ttModel.animateFunction + "-to");
if (ttModel.contentMore) {
elMore.style.display = 'block';
elMore.style.visibility = 'visible';
}
moveTooltip();
}
else if (elMore.style.display !== 'block' && ttModel.contentMore) {
elMore.style.display = 'block';
animateElementClass(ttElement);
moveTooltip();
var h = elMore.getBoundingClientRect().height;
elMore.style.visibility = 'visible';
elMore.style.height = '0px';
// animate more content
animateElementClass(elMore, function() {
elMore.style.height = h > 0 ? h + 'px' : "auto";
});
}
return this;
}
var
component=new Component(this,tooltipHTML),
elBox=component.anchors.box[0],
elText=component.anchors.text[0],
elMore=component.anchors.more[0],
elMoreText=component.anchors.moreText[0],
ttElement=component.elements[0],
isHiding = false;
resetTooltipPosition();
if(typeof window!=='undefined'){
window.addEventListener("resize", moveTooltip, false);
window.addEventListener("scroll", moveTooltip, false);
}
component.set(defaultOptions);
var ttModel=component.model;
component.onModelUpdate({
color:function(color){
if (html5tooltipsPredefined.color[color]) {
color = html5tooltipsPredefined.color[color];
color = "rgb(" + color.r + ", " + color.g + ", " + color.b + ")";
}
elBox.style.backgroundColor = color;
},
contentText:function(text){
component.anchors.text[0].innerHTML = text;
},
contentMore:function(more){
component.anchors.moreText[0].innerHTML = more;
},
stickTo:function(stickTo){
component.elements[0].className = "html5tooltip-" + stickTo;
}
});
// PUBLIC INTERFACE
this.hide=hide;
this.show=show;
this.showMore=showMore;
this.moveTooltip=moveTooltip;
component.publ.destroy = function(){
if(typeof window!=='undefined'){
window.removeEventListener("resize", moveTooltip);
window.removeEventListener("scroll", moveTooltip);
}
component.destroy();
}
component.publ.unmount = function(){
resetTooltipPosition();
component.unmount();
}
}
var userTooltips=[],DOMTooltips=[];
function createTooltip(target,options,tooltips)
{
var tooltip;
for(var i=tooltips.length;i--;)
if(tooltips[i].model.target===target){
tooltip=tooltips[i];
break;
}
if(!tooltip){
tooltip=new HTML5TooltipUIComponent;
tooltips.push(tooltip);
}
tooltip.set(options);
tooltip.set('target',target);
var hovered,focused;
function tryUnmountTooltip()
{
if (target===hovered || tooltip.element===hovered)
return;
if (tooltip.model.persistent)
tooltip.hide(function(){
tooltip.unmount();
});
else
tooltip.unmount();
}
function disposeTooltip()
{
hovered = null;
if (target===focused)
return;
if (tooltip.model.persistent)
setTimeout(tryUnmountTooltip, tooltip.model.hideDelay);
else
tryUnmountTooltip();
}
target.addEventListener("mouseenter",function(){
if (this===hovered || this===focused)
return;
hovered = this;
setTimeout(function() {
if (this===hovered){
tooltip.mount();
tooltip.show();
}
}.bind(this), tooltip.model.delay);
});
target.addEventListener("mouseleave",disposeTooltip);
target.addEventListener("focus",function(){
if (["INPUT", "TEXTAREA"].indexOf(this.tagName) === -1 &&
this.getAttribute("contenteditable") === null)
return;
focused = this;
tooltip.mount();
tooltip.showMore();
});
target.addEventListener("blur",function(){
focused = null;
if(hovered !== tooltip.element){
tooltip.unmount();
}
});
tooltip.element.addEventListener("mouseenter",function(){
hovered = this;
});
tooltip.element.addEventListener("mouseleave",disposeTooltip);
}
function getElementsByAttribute(attr, context)
{
var nodeList = (context || document).getElementsByTagName('*'),
nodes = [];
for (var i = 0, node; node = nodeList[i]; i++) {
if ( node.getAttribute(attr) )
nodes.push(node);
}
return nodes;
}
function extractOptionAttribute(target, attrName, defaultValue)
{
var
value = target.getAttribute(attrName),
nextParent = target;
while(!value && (nextParent = nextParent.parentNode) && nextParent.getAttribute)
value = nextParent.getAttribute(attrName);
return value||defaultValue;
}
function createDOMTooltips()
{
getElementsByAttribute("data-tooltip").forEach(function(target) {
createDefaultTooltip(target);
});
}
function createDefaultTooltip(target)
{
var options = {
disableAnimation: extractOptionAttribute(target, 'data-tooltip-disable-animation', defaultOptions.disableAnimation),
animateFunction: extractOptionAttribute(target, "data-tooltip-animate-function", defaultOptions.animateFunction),
color: extractOptionAttribute(target, "data-tooltip-color", ''),
contentMore: extractOptionAttribute(target, "data-tooltip-more", ''),
contentText: extractOptionAttribute(target, "data-tooltip", ''),
delay: extractOptionAttribute(target, "data-tooltip-delay", defaultOptions.delay),
hideDelay: extractOptionAttribute(target, "data-tooltip-hide-delay", defaultOptions.delay),
maxWidth: extractOptionAttribute(target, "data-tooltip-maxwidth", 'auto'),
persistent: extractOptionAttribute(target, "data-tooltip-persistent", defaultOptions.persistent),
stickTo: extractOptionAttribute(target, "data-tooltip-stickto", defaultOptions.stickTo)
};
createTooltip(target, options, DOMTooltips);
}
function getElementsBySelector(selector, context)
{
var nodes = [];
try {
nodes = Array.prototype.slice.call((context || document).querySelectorAll(selector));
}
catch (exc) {}
return nodes;
}
function createUserTooltips(userTooltipsOptions)
{
userTooltipsOptions.forEach(function(options) {
var targets=[];
if (options.targetSelector)
targets = getElementsBySelector(options.targetSelector);
targets.forEach(function(target) {
createTooltip(target,options,userTooltips);
});
});
}
var html5tooltips=function(userTooltipsOptions){
if(!Array.isArray(userTooltipsOptions))
userTooltipsOptions=[userTooltipsOptions];
//TODO: remove DOMTooltips that share target with userTooltips
createUserTooltips(userTooltipsOptions);
};
//Provides html property reading for AMD and CommonJS
html5tooltips.autoinit=
html5tooltips.refresh=function(){
createDOMTooltips();
};
html5tooltips.createDefaultTooltip = function (target) {
createDefaultTooltip(target);
}
html5tooltips.getTooltipByTarget=function(target){
for(var i=userTooltips.length;i--;)
if(userTooltips[i].model.target===target)
return userTooltips[i];
for(var i=DOMTooltips.length;i--;)
if(DOMTooltips[i].model.target===target)
return DOMTooltips[i];
};
function documentLoaded()
{
document.removeEventListener("DOMContentLoaded",documentLoaded, false);
window.removeEventListener("load",documentLoaded, false);
html5tooltips.refresh();
}
if(typeof window!=='undefined'){
if (document.readyState === "complete") {
documentLoaded();
} else {
document.addEventListener("DOMContentLoaded",documentLoaded, false);
window.addEventListener( "load", documentLoaded, false );
}
if (!window.html5tooltipsPredefined) {
window.html5tooltipsPredefined = html5tooltipsPredefined;
window.HTML5TooltipUIComponent=HTML5TooltipUIComponent;
}
}
return html5tooltips;
}));
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
JavaScript
1
https://gitee.com/mirrors/html5tooltips-js.git
git@gitee.com:mirrors/html5tooltips-js.git
mirrors
html5tooltips-js
html5tooltips-js
master

搜索帮助