adev-tooltip.js
class Tooltip {
constructor() {
this.tooltipElement = this.createTooltipElement();
this.init();
}
init() {
document.querySelectorAll('[data-adev-tooltip]:not(.tooltip-init)').forEach(element => {
element.classList.add('tooltip-init');
element.addEventListener('mouseover', (event) => this.showTooltip(event));
element.addEventListener('mouseout', () => this.hideTooltip());
element.addEventListener('touchstart', (event) => this.showTooltip(event));
element.addEventListener('touchend', () => this.hideTooltip());
element.addEventListener('touchcancel', () => this.hideTooltip());
});
}
createTooltipElement() {
let tooltipElement = document.querySelector('.adev-tooltip');
if (!tooltipElement) {
tooltipElement = document.createElement('div');
tooltipElement.className = 'adev-tooltip';
document.body.appendChild(tooltipElement);
}
return tooltipElement;
}
showTooltip(event) {
let target = event.target;
if (!target.getAttribute('data-title')) {
target = target.closest('[data-title]');
}
this.tooltipElement.textContent = target.dataset.title;
this.tooltipElement.style.display = 'block';
const position = target.getBoundingClientRect();
const tooltipPosition = this.tooltipElement.getBoundingClientRect();
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
const top = (position.top + scrollTop) - this.tooltipElement.scrollHeight;
const viewportWidth = document.documentElement.clientWidth;
let tooltipPositionSide;
if (position.left + tooltipPosition.width <= viewportWidth) {
this.tooltipElement.style.left = `${position.left}px`;
this.tooltipElement.style.right = 'auto';
tooltipPositionSide = 'left';
} else if (viewportWidth - position.right + tooltipPosition.width <= viewportWidth) {
this.tooltipElement.style.right = `${viewportWidth - position.right}px`;
this.tooltipElement.style.left = 'auto';
tooltipPositionSide = 'right';
} else {
this.tooltipElement.style.left = '0';
this.tooltipElement.style.right = 'auto';
tooltipPositionSide = 'left';
}
this.tooltipElement.style.top = `${top - 5}px`;
this.tooltipElement.style.visibility = 'visible';
this.tooltipElement.setAttribute('data-tooltip-position', tooltipPositionSide);
}
hideTooltip() {
if (this.tooltipElement) {
this.tooltipElement.style.display = 'none';
}
}
}
document.addEventListener('adev:tooltip:init', function (e) {
new Tooltip();
});
document.dispatchEvent(new CustomEvent('adev:tooltip:init'));
.adev-tooltip {
position: absolute;
width: max-content;
max-width:240px;
padding: 8px 12px;
background: #000;
color: #fff;
font-size: 12px;
border-radius: 5px;
z-index: 10000;
visibility: hidden;
display: none;
}
.adev-tooltip::after {
content: '';
position: absolute;
--size: 13px;
width: var(--size);
height: var(--size);
background: #000;
bottom: 0;
left: 3px;
transform: rotate(45deg)translateX(50%);
z-index: 1;
}
.adev-tooltip[data-tooltip-position="right"]::after {
left: auto;
right: 10px;
}
data-adev-tooltip
on element and data-title
for the text.
<div class="shipping-icon" data-adev-tooltip data-title="Your Text here">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12a9 9 0 1 0 18 0a9 9 0 0 0-18 0m9-4v4m0 4h.01"/></svg>
</div>