БлогNot. JavaScript: модальное окно в функции, выполняемой после загрузки страницы

JavaScript: модальное окно в функции, выполняемой после загрузки страницы

Требовалась совсем простая вещь - чтобы условие задачи (и/или другой контент) уже были загружены и видимы на странице, а потом вызвалась функция task1, которая выполняет ввод данных из окна диалога prompt.

Увы, обычное

window.addEventListener('load', 
 function(e) { 
  task1();
 }
);

не помогло - в "Хроме" и "Опере" контента при появлении модального окна всё равно не было видно, а он появлялся только после вывода окна alert с результатом.

В принципе, помогло

window.addEventListener('load', 
 function(e) { 
  setTimeout(task1,300);
 }
);

, но не факт, что сработает в мобильных браузерах.

Вариант, при котором показанный ниже код у меня сработал во всех типовых настольных браузерах (Chrome, Firefox, Opera, IE11) - применять document.addEventListener('readystatechange') вместо обычного window.addEventListener('load') и при этом ещё отложить на небольшой таймаут запуск функции (setTimeout(task1,300))

Второе, что показывает код - "назойливый" контроль ввода, пока пользователь не введёт 5 допустимых числовых значений, модальные окна "не пускают его дальше". К счастью, в ряде современных браузеров (Chrome, Firefox) пользователь может запретить странице создавать дальнейшие окна диалога.

Третье - оператор continue в JavaScript, как и в PHP, может выходить "наверх" из нескольких вложенных циклов сразу (см. метку again:).

Четвёртое - как "вытащить" из массива набор скалярных переменных? Удобно в виде

let [a,b,c,x,y] = arr;

, но тогда не работает в IE11. Поэтому "сделано по старинке".

Условие самой задачи видно из листинга. Предполагается, что документ будет сохранён как файл .html в кодировке Юникода utf-8.

<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="utf-8">
<title>Задача</title>
</head>
<body>

<div>
 <p>
  30. Даны действительные положительные числа a, b, c, x, y. 
  Выяснить, пройдет ли кирпич с ребрами a, b, c в прямоугольное 
  отверстие со сторонами x, y.
 </p>
 <p>
  Просовывать кирпич в отверстие разрешается только так, 
  чтобы каждое из его ребер было параллельно или 
  перпендикулярно каждой из сторон отверстия
 </p>
</div>

<script>

function task1() { //Вводим сразу 5 чисел в массив, не выпускаем из цикла, пока неправильно
 let defdata = '1,2,3,3,2'; //Значения по умолчанию
 again: 
 do { 
  let data = prompt('Введите a,b,c,x,y (через запятую)',defdata);
  if (data == null) continue; 
  let arr = data.split(',');
  if (arr.length != 5) {
   alert('Не найдено 5 значений!'); 
   defdata = arr.join(','); continue; //Вернуть ввод и продолжить
  }
  for (let i=0; i<5; i++) {
   if (isNaN(arr[i])) {
    alert('Не найдено числа в этом элементе: '+arr[i]); 
    defdata = arr.join(','); continue again;
   }
   arr[i] = parseFloat(arr[i]);
  }
  //Если всё верно - расчёт:
  let a=arr[0],b=arr[1],c=arr[2],x=arr[3],y=arr[4]; //или let [a,b,c,x,y] = arr; если не нужен IE11
  let msg = ''; 
  if (a <= x && b <= y ||
      b <= x && a <= y ||
      a <= x && c <= y ||
      c <= x && a <= y ||
      c <= x && b <= y ||
      b <= x && c <= y) 
   msg = 'Да'; 
  else msg = 'Нет';
  alert (msg); 
  return;
 } while (1);
}

document.addEventListener('readystatechange', 
 function(e) { 
  if (e.target.readyState == 'complete') {
   setTimeout(task1,300);
  }
 }
);

</script>
<noscript>
 <p>Включите JavaScript в браузере!</p>
</noscript>

</body></html>

Заметим также, что для "назойливого ввода" цикл необязателен, если заменять неправильно вводимые данные значениями по умолчанию, например, так, как сделано в этом маленьком "сумматоре элементов массива" на JavaScript:

<script>
 const N = 5;
 let n = parseInt(prompt('Введите размерность ('+N+'):',N));
 if (n==null || isNaN(n) || n<1) {
  n = N;
  alert ('Неверная размерность, исправлена на '+N);
 }
 let arr=[];
 let s = prompt('Введите элеметы массива ('+n+') через запятую');
 if (s==null || s.split(',').length!=n) {
  alert ('Не найдено '+n+' значений, исправили на 1..'+n);
  arr=Array(n).fill(0).map((_,i)=>i+1);
  s=arr.join(',');
 }
 arr = s.split(','); //Элементы arr остаются строками!
 let sum = arr.reduce((prev,curr)=>prev+parseFloat(curr),0);
 alert ('Сумма элементов массива ['+arr.join(',')+']='+sum);
</script>
<noscript>Включите JavaScript!</noscript>

Обратите внимание, что без parseFloat или parseInt ничего не выйдет, будут сцепляться строки, как и вот в этом вычислении суммы цифр числа:

<script>
 function sumOfDigits (n) {
  if (isNaN(n)) return undefined;
  let arr = String(n).split(''); 
  let sum = arr.reduce( (prev, curr) => prev+parseInt(curr),0); 
  return sum;
 }
 alert (sumOfDigits(12345)); //15
</script>
<noscript>
 Включите JavaScript в браузере!
</noscript>

теги: javascript числа программирование учебное

25.02.2020, 11:31; рейтинг: 156