#javascript #css
Вопрос:
Я закодировал отбрасывание тени в поле для изображений в моем элементе, где оно будет реагировать на положение мыши. Это хорошо работает, если эффект тени коробки должен выполняться только на одном элементе. Однако при работе с несколькими элементами он начинает запаздывать/заикаться. Мне неясно, что является причиной этого. Я надеюсь, что кто-нибудь сможет это прояснить.
Вот короткое видео того, что я испытываю:- https://drive.google.com/file/d/1ULahZWR5sKt-yaDEIjEvK3TFa1g1n65d/view
Прилагается мой код;
HTML:
<div class="header-image">
<img class="images shadow-effect" src="./images/baby-swimming-classes.jpg" alt="Baby Swimming Class">
<img class="images shadow-effect" src="./images/children-swimming-classes.jpg" alt="Children Swimming Class">
<img class="images shadow-effect" src="./images/pre-competitive-swimming-classes.jpg" alt="Pre-Competitive Swimming Class">
<img class="images shadow-effect" src="./images/adult-swimming-classes.jpg" alt="Adult Swimming Class">
</div>
Язык JavaScript:
$(document).ready(function() {
const eleShadow = Object.values($('.shadow-effect'));
const shadowMax = 20; //px
// 1. Getting the required information
function boxShadow(e) {
//Screen width and height
const {
width: screenWidth,
height: screenHeight
} = screen;
//Mouse position
const {
clientX: mouseX,
clientY: mouseY
} = e;
//Position of objects
const {
x: eleX,
y: eleY,
width: eleWidth,
height: eleHeight
} = eleShadow[0].getBoundingClientRect();
const shadowX = (((eleX (eleWidth / 2)) - mouseX) / screenWidth) * shadowMax;
const shadowY = (((eleY (eleHeight / 2)) - mouseY) / screenHeight) * shadowMax;
// eleShadow[0].style.boxShadow = `${shadowX}px ${shadowY}px 0 #EF5B5B`;
$(".shadow-effect").css("box-shadow",
`${shadowX}px ${shadowY}px 0 #EF5B5B`
);
// For each individual element
}
$(document).on('mousemove', boxShadow);
})
Обновить:-
Это сглаживает до 3 изображений, когда появляется 4-е изображение. Он начинает отставать. Однако иногда 4 изображения выглядят гладко, но когда я обновляю их, они могут снова заикаться.
Ответ №1:
Слишком много событий срабатывает, так как это mousemove
событие включено document
. Попробуйте немного снизить скорость срабатывания триггеров.
/* eslint-disable no-undef*/
$(document).ready(function () {
const eleShadow = Object.values($(".shadow-effect"));
const shadowMax = 20; //px
// Throttle function: Input as function which needs to be throttled and delay is the time interval in milliseconds
let timerId;
const throttleFunction = (func, delay) => {
// If setTimeout is already scheduled, no need to do anything
if (timerId) {
return;
}
// Schedule a setTimeout after delay seconds
timerId = setTimeout(function () {
func();
// Once setTimeout function execution is finished, timerId = undefined so that in <br>
// the next scroll event function execution can be scheduled by the setTimeout
timerId = undefined;
}, delay);
};
// 1. Getting the required information
function boxShadow(e) {
//Screen width and height
const { width: screenWidth, height: screenHeight } = window.screen;
//Mouse position
const { clientX: mouseX, clientY: mouseY } = e;
//Position of objects
const {
x: eleX,
y: eleY,
width: eleWidth,
height: eleHeight
} = eleShadow[0].getBoundingClientRect();
const shadowX = ((eleX eleWidth / 2 - mouseX) / screenWidth) * shadowMax;
const shadowY =
((eleY eleHeight / 2 - mouseY) / screenHeight) * shadowMax;
// eleShadow[0].style.boxShadow = `${shadowX}px ${shadowY}px 0 #EF5B5B`;
$(".shadow-effect").css(
"box-shadow",
`${shadowX}px ${shadowY}px 0 #EF5B5B`
);
// For each individual element
}
$(document).on("mousemove", (e) => throttleFunction(() => boxShadow(e), 50));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Static Template</title>
</head>
<body>
<div class="header-image">
<img
class="images shadow-effect"
src="https://tinyjpg.com/images/social/website.jpg"
alt="Baby Swimming Class"
width="200"
/>
<img
class="images shadow-effect"
src="https://tinyjpg.com/images/social/website.jpg"
alt="Children Swimming Class"
width="200"
/>
<img
class="images shadow-effect"
src="https://tinyjpg.com/images/social/website.jpg"
alt="Pre-Competitive Swimming Class"
width="200"
/>
<img
class="images shadow-effect"
src="https://tinyjpg.com/images/social/website.jpg"
alt="Adult Swimming Class"
width="200"
/>
</div>
</body>
</html>
Вы можете поиграть с задержкой и найти оптимальное соотношение производительности и опыта
Комментарии:
1. Спасибо @Akhil, я попробую это сделать. Тем не менее, я понимаю, что может быть вызвано слишком много событий, но почему это нормально, когда у меня есть эффект на 3 изображениях, 1 элементе ввода и элементе кнопки, но он плохо работает на 4 изображениях.
2. Ха, это не работает. даже с таймаутом в 25 мс.. он все еще отстает/заикается. Может ли это быть проблемой с производительностью компьютера?
3. Я перестал использовать функцию эффекта тени и просто использую стиль теней в css, который меняется в направлении при нажатии … он также отстает. Не уверен, что функция больше не является проблемой, хм .
Ответ №2:
Я обнаружил, что проблема заикания/задержки связана не с JavaScript, а с размером файла. Из-за того, что размер файла одного из изображений слишком велик. Сжатие изображений помогло бы. Кроме того, сохранение изображений в качестве оригинальных со свойством и значением ниже также вызывает заикание.
object-fit: cover;
Использование любого другого значения, кроме обложки, по-видимому, решает проблему при сохранении изображений, но это не то, что я хочу в контейнере изображений.