如何注册滚动事件?

问题描述 投票:0回答:1

我正在尝试编写一个网页动画,用户可以选择单击和拖动或简单地使用鼠标滚轮滚动来查看垂直的图像堆栈。单击并拖动工作正常,但滚动输入无法按预期工作。当我尝试滚动图片时,输入似乎没有注册。当我先单击并拖动,然后滚动时,滚动功能就起作用了。

HTML:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="style.css">
    <title>CoolEffect</title>
</head>
<body>
    <div id = "image-track" data-mouse-down-at = "0" data-prev-percentage = "0">
        <img class="image" src="assets/photo-1542051841857-5f90071e7989.jpeg" draggable="false">
        <img class="image" src="assets/photo-1533050487297-09b450131914.jpeg" draggable="false">
        <img class="image" src="assets/photo-1564284369929-026ba231f89b.jpeg" draggable="false">
        <img class="image" src="assets/photo-1528360983277-13d401cdc186.jpeg" draggable="false">
        <img class="image" src="assets/photo-1492571350019-22de08371fd3.jpeg" draggable="false">
        <img class="image" src="assets/photo-1532884928231-ef40895eb654.jpeg" draggable="false">
        <img class="image" src="assets/photo-1540959733332-eab4deabeeaf.jpeg" draggable="false">
    </div>
    <script src="script.js"></script>
</body>
</html>

CSS

body{
    height: 100vh;
    width: 100vw;
    background-color: black;
    margin: 0rem;
    overflow: hidden;
}

#image-track > .image {
    width: 150vmin;
    height: 50vmin;
    object-fit: cover;
    object-position: 100% 0%;
}

#image-track {
    display: flex;
    flex-direction: column;
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
}

JavaScript

const track = document.getElementById("image-track");

window.onmousedown = e => {
    track.dataset.mouseDownAt = e.clientY;
}

window.onmouseup = () => {
    track.dataset.mouseDownAt = "0";
    track.dataset.prevPercentage = track.dataset.percentage;
}

window.onmousemove = e => {
    if(track.dataset.mouseDownAt === "0") return;

    const mouseDelta = parseFloat(track.dataset.mouseDownAt) - e.clientY,
    maxDelta = window.innerHeight;

    let percentage = (mouseDelta / maxDelta) * -100,
    nextPercentage = parseFloat(track.dataset.prevPercentage) + percentage;

    nextPercentage = Math.max(-100, Math.min(0, nextPercentage));

    track.dataset.percentage = nextPercentage;

    track.animate(
        {transform :`translate(-50%, ${nextPercentage}%)`}, 
        {duration: 1200, fill: "forwards"});

    for(const image of track.getElementsByClassName("image")){
        image.animate(
            {objectPosition : `50% ${nextPercentage + 100}%`}, 
            {duration: 1200, fill: "forwards"});
    }
} 

window.addEventListener("wheel", e => {

    e.preventDefault();
    
    const deltaY = e.deltaY;
    const maxDelta = window.innerHeight;
    
    let percentage = (deltaY / maxDelta) * -100,
        nextPercentage = parseFloat(track.dataset.percentage) + percentage;
    
    nextPercentage = Math.max(-100, Math.min(0, nextPercentage));
    
    track.dataset.percentage = nextPercentage;
    
    track.animate(
        { transform: `translate(-50%, ${nextPercentage}%)` },
        { duration: 1200, fill: "forwards" }
    );
    
    for (const image of track.getElementsByClassName("image")) {
        image.animate(
            { objectPosition: `50% ${nextPercentage + 100}%` },
            { duration: 1200, fill: "forwards" }
        );
    }
    scrollStartY = e.pageY;
});

我期望发生的是,无论之前的输入如何,用户都可以滚动或单击并拖动来查看图像。如果不先单击并拖动,用户将无法执行此操作。我首先认为问题在于页面的默认滚动行为,因此我添加了 e.preventDefault() 来否定这一点。然而这不是问题。关于可能导致该问题的原因有什么建议吗?

javascript html css input scroll
1个回答
0
投票

您仅在滚动时修改 track.dataset.percentage 值,但没有更新 track.dataset.prevPercentage 以反映当前状态。

let scrollStartY = 0;

window.addEventListener("wheel", e => {
    e.preventDefault();

    const deltaY = e.deltaY;
    const maxDelta = window.innerHeight;

    let percentage = (deltaY / maxDelta) * -100,
        nextPercentage = parseFloat(track.dataset.percentage) + percentage;

    nextPercentage = Math.max(-100, Math.min(0, nextPercentage));

    track.dataset.prevPercentage = track.dataset.percentage; // Update prevPercentage
    track.dataset.percentage = nextPercentage;

    track.animate(
        { transform: `translate(-50%, ${nextPercentage}%)` },
        { duration: 1200, fill: "forwards" }
    );

    for (const image of track.getElementsByClassName("image")) {
        image.animate(
            { objectPosition: `50% ${nextPercentage + 100}%` },
            { duration: 1200, fill: "forwards" }
        );
    }
});
© www.soinside.com 2019 - 2024. All rights reserved.