Skip to content

Instantly share code, notes, and snippets.

@a3r0id
Last active September 10, 2023 21:41
Show Gist options
  • Save a3r0id/827b1aff76f1afb01a2852915d2a63d4 to your computer and use it in GitHub Desktop.
Save a3r0id/827b1aff76f1afb01a2852915d2a63d4 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style type="text/css">
* {
font-family: 'Courier New', Courier, monospace;
}
.custom-tooltip {
box-shadow: 0 0 5px #000;
color: #ff0000;
font-size: 1.2rem;
padding: 5px;
position: absolute;
z-index: 1000;
}
</style>
</head>
<body>
<div style="width: 100%;">
<div id="trigger" style="text-align: center;outline: 1px solid rgb(180, 180, 180);width: 20vw;padding: 1px 1px;margin: 0 auto;user-select: none;">Hover Me</div>
</div>
<script type="module">
import { ToolTip } from 'ToolTip.js';
const tooltip = new ToolTip('#trigger', '<div>Hello World</div>', {
classNames: ['custom-tooltip']
});
</script>
</body>
</html>
/*
Author:
github.com/a3r0id
Description:
Basic tooltip class
*/
export class ToolTip{
// ## Synopsis ##
// > triggerSelector: the selector of the element that will trigger the tooltip
// > html: the html content of the tooltip
// > options: an object with the following properties:
// - offsetX: The horizontal offset of the tooltip from the trigger element (pixels)
// - offsetY: The vertical offset of the tooltip from the trigger element (pixels)
// - classNames: An array of class names to add to the tooltip wrapper
constructor(triggerSelector, html, options){
// add the tooltip style to the DOM
if (typeof ttpDomHasClass === "undefined") {
window.ttpDomHasClass = true;
let style = document.createElement('style');
style.type = 'text/css';
style.innerHTML = `
.tooltip{
position: absolute !important;
top: 0;
left: 0;
background-color: #fffffffe;
z-index: 9999 !important;
}
`;
document.getElementsByTagName('head')[0].appendChild(style);
}
// properties
this.trigger = document.querySelector(triggerSelector);
this.tooltip = null;
this.html = html;
this.options = options;
this.id = Math.random().toString(36).substr(2, 9);
// events
this.trigger.addEventListener("mouseenter", this.show.bind(this));
this.trigger.addEventListener("mouseleave", this.hide.bind(this));
this.trigger.addEventListener("click", this.show.bind(this));
this.trigger.addEventListener("mousemove", this.move.bind(this));
// options
if (this.options === undefined) this.options = {};
this.offsetX = this.options.offsetX || 10;
this.offsetY = this.options.offsetY || 10;
this.classNames = this.options.classNames || [];
this.classNames.push("tooltip");
}
move = (e) => {
// move the tooltip
if (this.tooltip === null) return;
this.tooltip.style.left = e.clientX + this.offsetX + "px";
this.tooltip.style.top = e.clientY + this.offsetY + "px";
};
show = (e) => {
// create the tooltip
if (this.tooltip !== null) return;
this.tooltip = document.createElement("div");
this.tooltip.setAttribute("data-tooltip-id", this.id);
this.tooltip.className = this.classNames.join(" ");
this.tooltip.innerHTML = this.html;
document.body.prepend(this.tooltip);
this.initToMouse(e);
};
initToMouse = (e) => {
// initialize the tooltip to the mouse position
this.tooltip.style.left = e.clientX + 10 + "px";
this.tooltip.style.top = e.clientY + 10 + "px";
};
hide = () => {
// remove the tooltip from the DOM
if (this.tooltip === null) return;
this.tooltip.remove();
this.tooltip = null;
};
refreshTrigger(){
// setter: refresh the trigger element
// useful if the trigger element is dynamically added to the DOM
this.trigger = document.querySelector(this.triggerSelector);
return this;
}
}
export class ToolTip{constructor(t,i,s){if("undefined"==typeof ttpDomHasClass){window.ttpDomHasClass=!0;let e=document.createElement("style");e.type="text/css",e.innerHTML=`.tooltip{position: absolute !important;top: 0;left: 0;background-color: #fffffffe;z-index: 9999 !important;}`,document.getElementsByTagName("head")[0].appendChild(e)}this.trigger=document.querySelector(t),this.tooltip=null,this.html=i,this.options=s,this.id=Math.random().toString(36).substr(2,9),this.trigger.addEventListener("mouseenter",this.show.bind(this)),this.trigger.addEventListener("mouseleave",this.hide.bind(this)),this.trigger.addEventListener("click",this.show.bind(this)),this.trigger.addEventListener("mousemove",this.move.bind(this)),void 0===this.options&&(this.options={}),this.offsetX=this.options.offsetX||10,this.offsetY=this.options.offsetY||10,this.classNames=this.options.classNames||[],this.classNames.push("tooltip")}move=t=>{null!==this.tooltip&&(this.tooltip.style.left=t.clientX+this.offsetX+"px",this.tooltip.style.top=t.clientY+this.offsetY+"px")};show=t=>{null===this.tooltip&&(this.tooltip=document.createElement("div"),this.tooltip.setAttribute("data-tooltip-id",this.id),this.tooltip.className=this.classNames.join(" "),this.tooltip.innerHTML=this.html,document.body.prepend(this.tooltip),this.initToMouse(t))};initToMouse=t=>{this.tooltip.style.left=t.clientX+10+"px",this.tooltip.style.top=t.clientY+10+"px"};hide=()=>{null!==this.tooltip&&(this.tooltip.remove(),this.tooltip=null)};refreshTrigger(){return this.trigger=document.querySelector(this.triggerSelector),this}}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment