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

alert wykonuje się przed instrukcjami zawartymi przed nim w kodzie

Aruba Cloud VPS - 50% taniej przez 3 miesiące!
+1 głos
383 wizyt
pytanie zadane 21 kwietnia 2023 w JavaScript przez koczo21 Początkujący (450 p.)

Cześć,

Tworzę aktualnie grę w statki i mam sytuację gdzie po kliknięciu w dane pole musi się wykonać akcja(zmiana stylu obiektu) i następnie pokazać alert z komentarzem. Okazuje się, że mimo, iż alert jest zawarty w kodzie poniżej, to wykonuje się pierwszy w kolejności i dopiero po kliknięciu "ok" na alercie styl obiekty się zmienia. Aby to zobrazować przesyłam poniżej krótki kod, gdzie po kliknięciu submita najpierw pojawia się alert, a potem wykonuje polecenie zmiany koloru, mimo, że linia z "alert" jest poniżej linii zmieniającej kolor. 

<!DOCTYPE html>
<html lang="pl">

<head>
	<meta charset="utf-8"/>
	
	<script type="text/javascript">
	
	function zmiana()
		{
		document.getElementById("kolor").style.color="red";
		alert("zmiana koloru");
		}
		
	</script>	
</head>

<body>
	<input type="submit" value="zmien kolor" onclick="zmiana()"/>
	<div id="kolor">jaki mam kolor?</div>
</body>

</html>

Czy jest możliwość, aby alert wyświetlił się dopiero po zmianie koloru? Z góry dziękuję za wszystkie odpowiedzi :) 

3 odpowiedzi

+2 głosów
odpowiedź 21 kwietnia 2023 przez Gynvael Coldwind Nałogowiec (30,110 p.)

TL;DR: musisz przerzucić alert do kolejnego zadania (taska);

setTimeout(() => { alert("blabla"); }, 0);  // to zamiast alert()

Dłuższa wersja:

JS wykonuje się w "zadaniach" (taskach), gdzie strona się nie "odmalowuje" w trakcie wykonywania danego zadania (tylko pomiędzy zadaniami). Co więcej, alert() jest blokujący i blokuje wykonanie danego zadania do końca.

Więc musisz przerobić kod tak, żeby funkcja zmiana() wykonała się do samego końca, potem strona się automatycznie "przemalowała", a dopiero potem wywołał się alert.

Ten kod który napisałem po prostu wrzuca kolejne zadanie na listę do wykonania za 0 milisekund (czyli de facto od razu po tym zadaniu (i po automatycznym przemalowaniu)), w który wywoływany jest nasz alert. Może da się to zrobiła ładniej, ale to zadziała ;)

Więcej info: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Event_loop

komentarz 21 kwietnia 2023 przez koczo21 Początkujący (450 p.)
Super, wygląda na to, że działa i rozwiązuje mój problem, dzięki za błyskawiczną reakcję :) Dzięki, też za wytłumaczenie i lekturę, człowiek się doszkoli i będzie wiedział na przyszłość :)
+1 głos
odpowiedź 21 kwietnia 2023 przez Comandeer Guru (606,240 p.)

Ciekawe. Wynika to z tego, że co prawda operacje na DOM są synchroniczne w kodzie, ale muszą jeszcze spowodować ponowny rendering – a alert(), zgodnie ze specyfikacją, pauzuje całą stronę, w tym przerysowanie zmian w DOM-ie. Stąd kolor pojawia się na stronie po zamknięciu komunikatu.

Rozwiązanie jest proste: dać przeglądarce czas na przerysowanie, wrzucając alert() do np. setTimeout():

setTimeout( () => alert( 'whatever' ) );

 

0 głosów
odpowiedź 22 kwietnia 2023 przez VBService Ekspert (256,320 p.)
edycja 22 kwietnia 2023 przez VBService

W ramach ciekawostki, możesz też użyć requestIdleCallback

[ on-line ]

function zmiana() {
  document.getElementById("kolor").style.color="red";
  requestIdleCallback(() => {
    alert("zmiana koloru");
  });
}

 

BTW, jeżeli zmiana koloru wiąże się z zastosowanie np. w css

transition: color 250ms;

powoduje to, że setTimeout(() => { ... }, 0) z ustawionym delay na 0 (zero) nie spełnia swojego zadania.

Sprawdź: on-line.

 

 

P.S. może rozważ np. użycie modal box-a, jak alternatywy dla "okienka" alert w js.

Sprawdź: on-line.

komentarz 23 kwietnia 2023 przez koczo21 Początkujący (450 p.)
Dzięki, nie miałem żadnego rozwiązania, a teram mam już kilka :) Odnośnie tego modal box-a to rozumiem, że musi on się pojawić w wolnej przestrzeni na stronie, albo po prostu zastąpić jakiś obiekt? bo z tego co rozumiem, to nie działa on tak, że przysłania to co już jest pokazane na stronie.
komentarz 23 kwietnia 2023 przez VBService Ekspert (256,320 p.)
edycja 23 kwietnia 2023 przez VBService

Modal jest wyświetlany na warstwie umieszczonej możliwie jak najwyżej na stronie na całym innym kontentem, odpowiada za to 

z-index: 9999;

sprawdź, zamień transparent na jakiś kolor w #alert

#alert {
  ...
  z-index: 9999;

  background-color: blue;  /* transparent  */

  user-select: none;
}

lub nawet tak

#alert {
  ...
  z-index: 9999;

  background-image: linear-gradient(white, black);

  user-select: none;
}

sprawdź, on-line.

 

albo po prostu zastąpić jakiś obiekt?

nie ma potrzeby zastępowania żadnego obiektu. Kod html dla

<div id="alert">

  ...

</div>

jest po porostu "ukryty"

#alert {
  display: none;

  ...
}

i za pomocą js jest "wyświetlany"

function zmiana() {
  document.body.classList.toggle('red');
  document.querySelector('#alert').style.display = 'block';
}

a tu jest "ukrywany" po kliknięciu w button

<button onclick="this.closest('#alert').style.display='none'">ok</button>

 

ten kod html dla modal-a, możesz umieścić gdziekolwiek w kodzie strony

<div id="alert">
  <div class="message-box">
    <p>zmiana koloru</p>
    <button onclick="this.closest('#alert').style.display='none'">ok</button>
  </div>
</div>

za jego "wyświetlanie" niezależne od layout-u strony odpowiada kod css

#alert {
  display: none;
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  z-index: 9999;

  background-color: transparent;  
  user-select: none;
}

 

Podobne pytania

0 głosów
0 odpowiedzi 234 wizyt
pytanie zadane 18 lutego 2017 w JavaScript przez Adam Jakś Dyskutant (8,940 p.)
0 głosów
0 odpowiedzi 123 wizyt
0 głosów
1 odpowiedź 488 wizyt
pytanie zadane 31 marca 2023 w PHP przez Grzegorz Mikina Dyskutant (8,060 p.)

93,175 zapytań

142,185 odpowiedzi

321,977 komentarzy

62,506 pasjonatów

Advent of Code 2024

Top 15 użytkowników

  1. 1401p. - dia-Chann
  2. 1380p. - Łukasz Piwowar
  3. 1372p. - CC PL
  4. 1370p. - Łukasz Eckert
  5. 1351p. - Tomasz Bielak
  6. 1312p. - Łukasz Siedlecki
  7. 1302p. - rucin93
  8. 1181p. - rafalszastok
  9. 1164p. - Adrian Wieprzkowicz
  10. 1155p. - Piotr Aleksandrowicz
  11. 1149p. - Michał Telesz
  12. 1124p. - ssynowiec
  13. 1113p. - Michal Drewniak
  14. 1101p. - Dominik Łempicki (kapitan)
  15. 1087p. - Marcin Putra
Szczegóły i pełne wyniki

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

Wprowadzenie do ITsec, tom 1 Wprowadzenie do ITsec, tom 2

Można już zamawiać dwa tomy książek o ITsec pt. "Wprowadzenie do bezpieczeństwa IT" - mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy aż 15% zniżki! Dziękujemy ekipie Sekuraka za fajny rabat dla naszej Społeczności!

...