• 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

Object Storage Arubacloud
+1 głos
243 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 (27,530 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 (601,550 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 (253,340 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 (253,340 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 200 wizyt
pytanie zadane 18 lutego 2017 w JavaScript przez Adam Jakś Dyskutant (8,940 p.)
0 głosów
0 odpowiedzi 101 wizyt
0 głosów
1 odpowiedź 377 wizyt
pytanie zadane 31 marca 2023 w PHP przez Grzegorz Mikina Dyskutant (8,060 p.)

92,576 zapytań

141,426 odpowiedzi

319,652 komentarzy

61,961 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!

...