zpět k lekci

„Chytrý“ tooltip

důležitost: 5

Napište funkci, která zobrazí tooltip nad elementem, jen když návštěvník přesune ukazatel myši na něj, ale ne přes něj.

Jinými slovy, jestliže návštěvník přesune ukazatel nad element a zastaví se tam, tooltip se zobrazí. Ale pokud jen přesune myš přes element jinam, pak to není třeba – kdo by chtěl další blikání?

Technicky můžeme změřit rychlost ukazatele nad elementem, a pokud je nízká, pak předpokládáme, že ukazatel vstoupil „na element“ a zobrazíme tooltip. Pokud je vysoká, budeme ukazatel ignorovat.

Vytvořte k tomu univerzální objekt new Setrvání(možnosti).

Jeho možnosti:

  • elem – sledovaný element.
  • over – funkce, která bude volána, když ukazatel vstoupí na element, tedy když se nad ním pohybuje pomalu nebo se na něm zastavil.
  • out – funkce, která bude volána, když ukazatel opustí element (pokud byla předtím volána over).

Příklad použití takového objektu s tooltipem:

// příklad tooltipu
let tooltip = document.createElement('div');
tooltip.className = "tooltip";
tooltip.innerHTML = "Tooltip";

// objekt bude sledovat myš a volat over/out
new Setrvání({
  elem,
  over() {
    tooltip.style.left = elem.getBoundingClientRect().left + 'px';
    tooltip.style.top = elem.getBoundingClientRect().bottom + 5 + 'px';
    document.body.append(tooltip);
  },
  out() {
    tooltip.remove();
  }
});

Demo:

Jestliže pohybujete myší nad „hodinami“ rychle, nic se neděje. Pokud jí pohybujete pomalu nebo se nad nimi zastavíte, zobrazí se tooltip.

Prosíme všimněte si, že tooltip „neblikne“, když se kurzor přesune mezi podelementy hodin.

Otevřít pískoviště s testy.

Algoritmus vypadá jednoduše:

  1. Umístíme na element handlery onmouseover/out. Můžeme zde použít i onmouseenter/leave, ale ty jsou méně univerzální a kdybychom zavedli delegování, nefungovaly by.
  2. Když na element vstoupí ukazatel myši, začneme měřit rychlost v mousemove.
  3. Pokud je rychlost nízká, spustíme over.
  4. Když opustíme element a bylo spuštěno over, spustíme out.

Jak ale měřit rychlost?

Prvním nápadem může být spustit každých 100 ms funkci, která změří vzdálenost mezi předchozími a současnými souřadnicemi. Bude-li malá, bude rychlost nízká.

Naneštěstí v JavaScriptu není žádný způsob, jak zjistit „aktuální souřadnice myši“. Neexistuje žádná funkce jako getCurrentMouseCoordinates().

Jediný způsob, jak zjistit souřadnice, je naslouchat událostem myši, např. mousemove, a zjišťovat souřadnice z objektu události.

Vytvoříme tedy handler pro mousemove, aby sledoval souřadnice a pamatoval si je. A pak je jednou za 100 ms budeme porovnávat.

P.S. Prosíme všimněte si, že testy v řešení používají dispatchEvent, aby viděly, zda tooltip funguje správně.

Otevřít řešení s testy na pískovišti.