setInterval не выключается
Всем привет, ребят помогите пожалуйста решить проблему с функцией. Много времени убил, не знаю в чем проблема. Функция должна работать так, когда зажимаю кнопку мыши, функция должна работать непрерывно, а когда отпускаю кнопку, то прекращать выполнение. Но очень часто функция зависает и clearInterval продолжает бесконечно добавлять блоки на страницу. В чем может быть проблема?
function showGifts() {
let intervalMousedown;
let intervalMouseup;
let offsetX;
let offsetY;
function renderItems() {
let gift = document.createElement('div');
$('body').append(
$(gift)
.clone()
.offset({
left: offsetX - 10,
top: offsetY - 30,
}),
);
}
document.addEventListener('mousedown', () => {
clearTimeout(intervalMouseup);
intervalMousedown = setInterval(() => {
renderItems();
}, 60);
});
document.addEventListener('mouseup', () => {
let arr = document.querySelectorAll('.gift');
clearInterval(intervalMousedown);
intervalMouseup = setTimeout(() => {
arr.forEach((gift) => {
gift.remove();
});
}, 4100);
});
document.addEventListener('mousemove', (e) => {
offsetX = e.pageX;
offsetY = e.pageY;
});
}
showGifts();
Ответы (1 шт):
Проблема с зависанием функции может быть связана с тем, что внутри функции renderItems() создается новый элемент div с классом gift и добавляется в тело документа ($('body')). Если пользователь многократно нажимает на кнопку мыши, то может создаться большое количество элементов, что может привести к значительному замедлению работы браузера.
Для решения этой проблемы можно использовать механизм, который будет проверять количество созданных элементов div и удалять их при превышении определенного значения. Например, можно добавить следующий код внутри функции renderItems()
const maxGifts = 50;
const gifts = document.querySelectorAll('.gift');
if (gifts.length >= maxGifts) {
gifts[0].remove();
}
let gift = document.createElement('div');
gift.classList.add('gift');
$('body').append(
$(gift).clone().offset({
left: offsetX - 10,
top: offsetY - 30,
})
);
Также может быть полезным добавить проверку на наличие активных интервалов перед их очисткой, чтобы избежать ошибок. Например, можно использовать следующий код для очистки интервалов:
if (intervalMousedown) {
clearInterval(intervalMousedown);
}
if (intervalMouseup) {
clearTimeout(intervalMouseup);
}
Если проблема сохраняется даже после добавления кода, который я предложил ранее, то может быть полезно проверить другие причины зависания функции.
Одна из возможных причин - это то, что не все созданные элементы div удаляются после отпускания кнопки мыши. Это может приводить к тому, что многие элементы остаются на странице, что замедляет ее работу и вызывает зависание.
Чтобы убедиться, что все элементы удаляются корректно, вы можете добавить вывод в консоль количества элементов div перед и после их удаления:
document.addEventListener('mouseup', () => {
let arr = document.querySelectorAll('.gift');
console.log(`before remove: ${arr.length}`);
clearInterval(intervalMousedown);
intervalMouseup = setTimeout(() => {
arr.forEach((gift) => {
gift.remove();
});
console.log(`after remove: ${document.querySelectorAll('.gift').length}`);
}, 4100);
});
Если проблема сохраняется, можно попробовать изменить частоту создания элементов div в функции renderItems(), чтобы уменьшить количество элементов, создаваемых за короткий промежуток времени. Например, можно увеличить интервал до 100 миллисекунд
intervalMousedown = setInterval(() => {
renderItems();
}, 100);