Niedawno utworzyłem pewną aplikację HTML+JS+WASM, która otwiera osobne okna z elementami interfejsu. Aby łatwiej było zrozumieć, główny plik to będzie "rodzic", a plik otwierany w osobnym oknie, to będzie "dziecko". Architektonicznie, rodzic co pół sekundy uruchamia pewną funkcję w WASM, która wywołuje funkcję JavaScript, a owa funkcja we wszystkich dzieciach uruchamia określoną funkcję. Cykliczność jest zrealizowana przez setTimeout
.
Na komputerze (przegladarka Firefox i Chrome) działa to prawidłowo, tak, jak chciałem i wydawało się po temacie, nie ma znaczenia, czy dane okno jest zminimalizowane, zmaksymalizowane, widoczne, ukryte.
Okazało się, że na telefonie z Androidem, w Chrome działa to problematycznie. Jeżeli na wierzchu jest rodzic, a pod spotem okno z dzieckiem, to działa dobrze, ale jeżeli okno dziecka jest na wierzchu, a rodzic pod spotem, to raz nie uruchamia się, raz uruchamia się, ale rzadziej. Jedynie, jeżeli rodzic uruchamia Worker i ten Worker wysyła wiadomość zyklicznie, to działa prawidłowo, ale nie zawsze apka działa z workerem.
Zrobiłem do testów samo setTimeout, żeby to sprawdzić na telefonie, po obu stronach jest funkcja, która zwiększa licznik u siebie i po drugiej stronie, czyli testuję setTimeout i u rodzica i u dziecka. Na komputerze tak samo działa dobrze, czyli niezależnie od tego, jak ułożę okna, oba liczniki "biją" równomiernie, co ok. pół sekundy. Natomiast na telefonie, to już nie za bardzo. Licznik wywoływany przez skrypt pod spodem bije licznik wolniej, a będący aktualnie na wierzchu bije zgodnie z zamiarem.
Plik index.html
, czyli rodzic
<!doctype html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Rodzic</title>
</head>
<body>
<input type="button" onclick="OpenChild()" value="Otwórz okno">
<input type="button" onclick="ChildTestWindow()" value="Start">
<br>
To jest rodzic<br>
Rodzic:<span id="counter1">0</span><br>
Dziecko:<span id="counter2">0</span><br>
<script type='text/javascript'>
let ChildObjWin = null;
function OpenChild()
{
const WinX = 0;
const WinY = 0;
const WinW = 640;
const WinH = 480;
ChildObjWin = window.open("child.html", "_blank", "left=" + WinX + "px,top=" + WinY + "px,width=" + WinW + "px,height=" + WinH + "px");
}
function ChildTestWindow()
{
const T = document.getElementById("counter1").innerHTML;
document.getElementById("counter1").innerHTML = parseInt(T) + 1;
if (ChildObjWin)
{
ChildObjWin.TestFunc();
}
setTimeout(ChildTestWindow, 500);
}
function FuncFromChildToParent()
{
const T = document.getElementById("counter2").innerHTML;
document.getElementById("counter2").innerHTML = parseInt(T) + 1;
}
</script>
</body>
</html>
Plik child.html
, czyli dziecko
<!doctype html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Dziecko</title>
</head>
<body>
<input type="button" onclick="ParentTest()" value="Start">
<br>
To jest dziecko<br>
Rodzic:<span id="counter1">0</span><br>
Dziecko:<span id="counter2">0</span><br>
<script type='text/javascript'>
function PrintInfo(Msg)
{
document.getElementById("info").innerHTML = document.getElementById("info").innerHTML + Msg + "<br>";
}
function TestFunc()
{
const T = document.getElementById("counter2").innerHTML;
document.getElementById("counter2").innerHTML = parseInt(T) + 1;
}
function ParentTest()
{
const T = document.getElementById("counter1").innerHTML;
document.getElementById("counter1").innerHTML = parseInt(T) + 1;
if (opener)
{
opener.FuncFromChildToParent();
}
setTimeout(ParentTest, 500);
}
</script>
</body>
</html>
Czym to może być spowodowane, że dobrze to działa tylko na komputerze, a na telefonie już są kłopoty? Jak spowodować (i nie chodzi tu tylko o sam setTimeout), żeby skrypt JavaScript działał tak samo niezależnie od tego, czy jest w zakładce na wierzchu, czy pod spodem, skoro on ma działać?