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>
25.02.2020, 11:31 [1441 просмотр]