JSFiddle - React, Tailwind, and code Playground
HTML
<div data-tooltip="Это – внутренность дома" id="house">
<div data-tooltip="Это – крыша" id="roof"></div>
<p>Жили-были на свете три поросёнка. Три брата.</p>
<p>Все одинакового роста, кругленькие, розовые, с одинаковыми весёлыми хвостиками.</p>
<p>Даже имена у них были похожи. Звали поросят Ниф-Ниф, Нуф-Нуф и Наф-Наф. Всё лето они кувыркались в зелёной траве, грелись на солнышке, нежились в лужах.</p>
<p>Но вот наступила осень. <a href="http://ru.wikipedia.org/wiki/Три_поросёнка" data-tooltip="Читать дальше…">Наведи на меня</a></p>
</div>
CSS
* {
box-sizing: border-box;
}
body {
height: 2000px;
padding: 0;
margin: 0;
position: relative;
/* подсказка должна работать при прокрутке */
}
#house {
position: relative;
margin-top: 50px;
width: 400px;
border: 1px solid brown;
margin-top: 100px;
margin-left: 100px;
}
#roof {
width: 0;
height: 0;
border-left: 200px solid transparent;
border-right: 200px solid transparent;
border-bottom: 20px solid brown;
margin-top: -20px;
}
p {
text-align: justify;
margin: 10px 3px;
}
.tip {
position: absolute;
top: -25%;
transform: translateX(50%);
border: 1px solid blue;
padding: 10px;
background-color: white;
z-index: 99;
}
.tip-bottom {
position: absolute;
bottom: -25%;
transform: translateX(50%);
border: 1px solid blue;
padding: 10px;
background-color: white;
z-index: 99;
}
JavaScript
let currentTarget = null;
document.querySelector('#house').addEventListener('mouseover', (event) => {
let target = event.target;
if (!target.getAttribute('data-tooltip') && !target.tagName == 'P') {
return;
}
if (currentTarget) {
for (let i = 0; i < currentTarget.children.length; i++) {
if (currentTarget.chilren[i] == target) return;
}
}
if (target.tagName == 'P') {
currentTarget = target.closest('#house');
target = target.closest('#house');
}
else {
currentTarget = target;
}
let div = document.createElement('div');
div.innerHTML = target.getAttribute('data-tooltip');
div.classList.add('tip');
currentTarget.appendChild(div);
if (div.offsetHeight > (parseInt(getComputedStyle(document.querySelector('#house')).marginTop) - pageYOffset)) {
div.classList.remove('tip');
div.classList.add('tip-bottom');
}
})
document.querySelector('#house').addEventListener('mouseout', (event) => {
let target = event.target;
for (let i = 0; i < currentTarget.children.length; i++) {
if (event.relatedTarget == currentTarget.children[i] && !event.relatedTarget.getAttribute('data-tooltip')) {
return;
}
}
try {
currentTarget.removeChild(currentTarget.querySelector('.tip-bottom'));
}
catch(e) {
console.log(e);
}
try {
currentTarget.removeChild(currentTarget.querySelector('.tip')) || relatedTarget.removeChild(relatedTarget.querySelector('.tip'));
}
catch(e) {
console.log(e);
}
currentTarget = null;
})