Проблема:
Иногда необходимо дождаться события для выполнения определенного участка кода. Например, получить идентификатор элемента после его появления в DOM. Использование метода setTimeout ведёт к дублированию кода при работе с несколькими объектами или событиями. Также необходимо в каждом случае продумывать задержку или задавать константу, после которой будет выполнен вызов функции. В связи с этим принято решение реализовать собственную функцию, получающую на вход:
- Check - функция, возвращающая true, если событие произошло, и false - если не произошло.
- Callback - функция, выполняющаяся после события ( check = true ).
- Time (необязательный параметр) - задержка в миллисекундах, определяющая задержку перед повторным вызовом check функции.
- Limit (необязательный параметр) - максимальная глубина стека (количество проверок выполнения события).
Реализация:
Создадим модуль, а внутри виджет с расширением корневой компонент.
Корневой компонент позволяет создать виджет, код которого будет исполняться на всех страницах при загрузке системы. Это позволяет нам, единожды создав функцию, использовать её на всех виджетах и формах.
Добавим виджет код на форму компонента с следующим содержимым:
Код:
<script>
function wait(check, callback, time=100, limit=30) {
if (check()) {
return callback();
}
if (!limit) {
return;
}
setTimeout(() => {
wait(check, callback, limit % 10 === 0 ? time*2 : time, limit-1);
}, time);
}
</script>
Теперь функция wait доступна во всех скриптах.
Время ожидания перед следующим опросом события увеличивается вдвое, если оставшаяся глубина стека делится на 10 с нулевым остатком. Это позволит постепенно увеличивать задержку для опроса события. По умолчанию time = 100, limit= 30 (суммарное время ожидания события около 15 секунд).
Пример:
- Добавим в приложении поле для ввода текста (имя свойства - hello_world).
- Добавим виджет Код с следующим содержимым:
Код:
<script>
function checkSelector(selector) {
if (document.querySelector(selector))
return true;
return false;
}
wait(
function() {return checkSelector("#hello_world")},
function() {
let helloWorldField = document.querySelector("#hello_world");
helloWorldField.value = "Hello world";
}
);
</script>
Теперь, при создании элемента приложения, в поле для ввода увидим "Hello world".