• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

wywołanie funkcji po zdarzeniu i jakimś czasie

Object Storage Arubacloud
+1 głos
127 wizyt
pytanie zadane 2 kwietnia 2021 w JavaScript przez kajman_Rrzeczny Użytkownik (960 p.)
Jak wykonać funkcje (której zdarzenie zostało spełnione) po x czasie gdzie te zdarzenie może zachodzić wielokrotnie.

Otóż zrobiłem funkcje, po najechaniu na element pojawia się dymek ale chcę by on się pojawiał po 1 sekundzie od zdarzenia które miało miejsce. Spróbowałem metodą setTimeout, ale działało do czasu, najechania na element po raz któryś tam, gdy najechałem po raz 6 czy tam 7, przeglądarka się zawieszała i zwracała błędy. Chyba metoda setTimeout nie nadaje się do tego typu mechanik.
komentarz 2 kwietnia 2021 przez ScriptyChris Mędrzec (190,190 p.)

Pokaż kod, który powodował zawieszanie się. Możesz spróbować na event najechania myszką dodać klasę CSS, która będzie mieć tranzycję na visibility lub opacity z opóźnieniem.

komentarz 2 kwietnia 2021 przez kajman_Rrzeczny Użytkownik (960 p.)

@ScriptyChris,

plik js

function tooltips(param) {     // display/hid tooltip
     
    let tooltip = null;
 
    function createElement(param, propeties) {    
        const newEl = document.createElement("div");
         
 
        newEl.textContent = param
        newEl.className = "tooltip"
         
        document.querySelector("body").appendChild(newEl)
         
        newEl.style.top = (propeties.y - newEl.offsetHeight - 10) + "px"
        newEl.style.left = (propeties.x + propeties.wth/2 - newEl.offsetWidth/2) + "px"
     
        tooltip = newEl
         
    }
     
    function displayTooltip(param) {   // disp
        let valueTooltip = param.target.getAttribute("title");
 
        param.target.removeAttribute("title");
         
        createElement(valueTooltip, {
            wth: param.target.offsetWidth,
            x: param.target.offsetLeft,
            y: param.target.offsetTop
        })
 
        tooltip.classList.add("transition");
    }
 
    function hidTooltip(param) {   // hidden 
        document.body.removeChild(tooltip);
 
        param.target.setAttribute("title", tooltip.textContent)
    }
     
    const titles = document.querySelectorAll("[title]");    // all tags has attribute title
     
    for (let index = 0; index < titles.length; index++) {
        titles[index].addEventListener("mouseenter", displayTooltip);
        titles[index].addEventListener("mouseleave", hidTooltip);
    }
 
};

plik CSS 

.tooltip {  /* basic form */
    font-family: "Comic Sans MS", cursive;
    display: inline-block;
    color: #fff;
    background-color: #000;
    padding: 7px;
    border-radius: 5px;
    position: absolute;
    font-size: 12px;
    width: 60px;
    text-align: center;
 
    opacity: 0;
}
 
.transition {   
    opacity: 1;
    -webkit-transition: opacity .2s ease-in-out;
    transition: opacity .2s ease-in-out;
}
 
.tooltip::after {
    content: "";
    display: block;
    background-color: #000;
    border-width: 0 2px 2px 0;
    width: 12px;
    height: 12px;
    position: absolute;
    bottom: -6px;
    left: 30px;
    -webkit-transform: rotate(45deg);
    -moz-transform: rotate(45deg);
    -ms-transform: rotate(45deg);
    -o-transform: rotate(45deg);
    transform: rotate(45deg);
}

efekt w przeglądarce: wyświetlenie się dymku natychmiast po zdarzeniu najechania

gdy dodawałem setTimeout do funkcji displayTooltip() w taki sposób:

setTimeout(function displayTooltip(param) {   // disp
        let valueTooltip = param.target.getAttribute("title");
 
        param.target.removeAttribute("title");
         
        createElement(valueTooltip, {
            wth: param.target.offsetWidth,
            x: param.target.offsetLeft,
            y: param.target.offsetTop
        })
 
        tooltip.classList.add("transition");
    }, 1000);

dymek nie wyświetlał się i consola zwracała error że funkcja nie jest zdefiniowana ( Uncaught ReferenceError: displayTooltip is not define at tooltips ), próbowałem też do funkcji createElement i do całej funkcji tooltip (tej największej) i problem był podobny

następnie zrobiłem tak w funkcji createElement, zrobiłem nową funkcje

function createElement(param, propeties) {    
        const newEl = document.createElement("div");
         
 
        newEl.textContent = param
        newEl.className = "tooltip"
         
        setTimeout(function displayAfterTime(param) {
            document.querySelector("body").appendChild(newEl)
             
            newEl.style.top = (propeties.y - newEl.offsetHeight - 10) + "px"
            newEl.style.left = (propeties.x + propeties.wth/2 - newEl.offsetWidth/2) + "px"
        }, 1000)
         
        tooltip = newEl
         
    }

efekt raz działa raz nie działa, jakby przeglądarka nie nadążała i  i strasznie się zawieszała

a w pliku metoda removeChild przetała działać

ps przepraszam jeżeli kod nie jest czytelny

 

komentarz 2 kwietnia 2021 przez ScriptyChris Mędrzec (190,190 p.)

gdy dodawałem setTimeout do funkcji displayTooltip() w taki sposób:

Skąd w funkcji displayTooltip ma się znaleźć argument param, skoro go tam nie przekazujesz? To powinno rzucać błąd w stylu "cannot read property target of undefined".

consola zwracała error że funkcja nie jest zdefiniowana ( Uncaught ReferenceError: displayTooltip is not define at tooltips )

Hmm, ale przecież tą funkcję zadeklarowałeś. Którego miejsca w kodzie dotyczy ten błąd?

W każdym razie, ten kod jest na tyle rozrzucony, że przydało by się gdybyś udostępnił go w serwisie, który umożliwia przetestowanie go, np. CodePen lub JSFiddle. Jeśli to, co wstawiłeś to jakiś mały fragment całości, to udostępnij we wspomnianym serwisie tylko ten kod, który pozwoli odtworzyć problem. Łatwiej to będzie przetestować.


Screeny wstawiaj proszę z zewnętrznych serwisów (np. imgur.com), bo na tych praktycznie nie da się rozczytać błędów.

komentarz 2 kwietnia 2021 przez kajman_Rrzeczny Użytkownik (960 p.)

ps nie wiem jak odpowiadać na poszczególne fragmenty komentarzy więc ctrl c i v

Skąd w funkcji displayTooltip ma się znaleźć argument param, skoro go tam nie przekazujesz? To powinno rzucać błąd w stylu "cannot read property target of undefined".

Paremetr "param" jest po to by wskazywać na element na którym jest wykonywana funkcja

param.target, jeżeli o to chodzi, w każdy razie działa.

 

Teraz wymyśliłem że w funkcji displayTooltip zrobiłem funkcje displayAfterTime() z setTimeout, i do niej wsadziłem dodawanie classy w której się znajdują style tranzycji opacity, i wszystko działa

function displayTooltip(param) {   // disp
        let valueTooltip = param.target.getAttribute("title");

        param.target.removeAttribute("title");
        
        createElement(valueTooltip, {
            wth: param.target.offsetWidth,
            x: param.target.offsetLeft,
            y: param.target.offsetTop
        })

        setTimeout(function displayAfterTimeout(params) {
            
            tooltip.classList.add("transition");
        
        }, 1250)
    };

 

W każdym razie, ten kod jest na tyle rozrzucony, że przydało by się gdybyś udostępnił go w serwisie, który umożliwia przetestowanie go, np. CodePen lub JSFiddle. Jeśli to, co wstawiłeś to jakiś mały fragment całości, to udostępnij we wspomnianym serwisie tylko ten kod, który pozwoli odtworzyć problem. Łatwiej to będzie przetestować.

tak zrobię

 

Screeny wstawiaj proszę z zewnętrznych serwisów (np. imgur.com), bo na tych praktycznie nie da się rozczytać błędów.

zwrócę na to uwagę

 

 

komentarz 2 kwietnia 2021 przez ScriptyChris Mędrzec (190,190 p.)

ps nie wiem jak odpowiadać na poszczególne fragmenty komentarzy więc ctrl c i v

 Użyj opcji cytatu - w prawym górnym roku edytora tekstu jest przycisk z ikonką cudzysłowia. Alternatywnie - chyba jest (lub był) taki zwyczaj w Sieci - można umownie oznaczyć cytat poprzedzając cytowany tekst znakiem większości >

Paremetr "param" jest po to by wskazywać na element na którym jest wykonywana funkcja

param.target, jeżeli o to chodzi, w każdy razie działa.

To dziwne, bo umieszczasz funkcję displayTooltip jako callback do setTImeout, który nie zawoła jej z parametrem, więc param powinno być undefined i powodować błąd przy próbie odczytu param.target. Chyba, że mówiąc "działa" masz na myśli inną funkcję displayTooltip, którą przekazujesz do event listenera, wtedy tam jest przekazany obiekt zdarzenia i on już zawiera property target.

1 odpowiedź

0 głosów
odpowiedź 2 kwietnia 2021 przez VBService Ekspert (253,400 p.)
edycja 2 kwietnia 2021 przez VBService

Nie pokazałeś kodu, ciężko się odnieść, ale np.:

Css   Codepen

<div class="a"></div>
<div class="b"></div>
* {
  box-sizing: border-box;
}
div {
  width: 100px;
  height: 30px;
  transition: opacity 2s linear 1s;
}
div.a:hover ~ div.b {
  opacity: 1;
}
.a {
  border: 2px solid red;
}
.b {
  opacity: 0;
  border: 2px solid limegreen;
  box-shadow: inset 0 0 10px limegreen;
}

CSS :hover on other element  [ 1 ] [ 2 ]

 

Css + JS   Codepen

<div class="a">Najedź na mnie myszką</div>
<div class="b">Najedź na mnie myszką</div>
<div class="c">Najedź na mnie myszką</div>
<div class="d">Najedź na mnie myszką</div>
<div class="message">Zjedź ze mnie ;-)</div>
* {
  box-sizing: border-box;
}
div {
  font: 1em/1.8em monospace;
  width: 200px;
  height: 30px;
  text-align: center;
  margin: 6em 1em;
}
.a {
  border: 2px solid red;
}
.b {
  border: 2px solid limegreen;
}
.c {
  border: 2px solid yellow;
}
.d {
  border: 2px solid black;
}
.message {
  position: absolute;
  top: 0;
  left: 0;
  opacity: 0;
  background-color: black;
  color: white;
  transition: opacity 2s linear 1s;
}
.show-message {
  opacity: 1;
}
const div_msg = document.querySelector('div.message'),
      divs = document.querySelectorAll('div:not(.message)');
let div_margin;

divs.forEach(div => {
  div.addEventListener('mouseover', () => {
    div_margin = window.getComputedStyle(div, null).getPropertyValue('margin-top');
    div_margin = div_margin.replace('px', '') * 1;
    div_msg.classList.add('show-message'); 
  })
  div.addEventListener('mousemove', e => {       
    div_msg.style.left = `${e.pageX}px`;
     div_msg.style.top = `${(e.pageY - div_margin)}px`;
  })
  div.addEventListener('mouseout', () => {
    div_msg.classList.remove('show-message');
  }) 
})

Podobne pytania

0 głosów
1 odpowiedź 441 wizyt
0 głosów
1 odpowiedź 131 wizyt

92,579 zapytań

141,432 odpowiedzi

319,657 komentarzy

61,963 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...