对于这个问题我一直处于不知道如何解决的阶段。思考过使用js解决,将视图固定,然后监听鼠标滚动事件,然后使用类似pid的方案来实现阻尼的效果。

当是移动端是则监听按下,然后在按下上监听移动...后面就不知道如何解决了。

现在观看https://www.bilibili.com/video/BV1QN411T7gW/ jiejoe视频得到了思路,但是没有看懂,遂手写一下再水篇文章(笑

首先我们搭建一下基础的框架

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>滑动阻尼</title>
</head>
<style>
    * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
    }

    .container {
        width: 100%;
    }

    img {
        width: 100%;
    }
</style>

<body>
    <!-- 首先我们创建一个基础的容器存放图片 -->
    <div class="container">
        <img src="pic.jpg" alt="">
        <img src="pic.jpg" alt="">
        <img src="pic.jpg" alt="">
        <img src="pic.jpg" alt="">
        <img src="pic.jpg" alt="">
        <img src="pic.jpg" alt="">
        <img src="pic.jpg" alt="">
    </div>
</body>

</html>

container容器存放图片,显示在页面当中,而我们再创建一个swipe称之为视图,用来显示浏览器能够看到的界面,宽100%搞为浏览器高度,并且设置为fixd不让他滚动,通过修改top定位来移动他

因为fixed脱离了文档流,没有内容能够撑起body,所以我们的滚动条会消失,无法滚动浏览器,所以我们需要为body设置高度,这样我们才能够滚动浏览器,同时监听浏览器的resize和load当触发两个事件之后我们重新设置body的高度。

再监听滚动事件修改swipe的top配合transition即可达到阻尼的效果

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>滑动阻尼</title>
</head>
<style>
    * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
    }

    img {
        width: 100%;
    }

    .container {
        width: 100%;
        position: relative;
    }

    .swipe {
        position: fixed;
        top: 0;
        transition: top 0.15s ease;
    }
</style>

<body>
    <!-- swipe是视图窗口,通过移动他来展示container的内容 -->
    <div class="swipe">
        <!-- container只是用来存放一堆图片,并且获取高度给body,即父级的父级元素的高度 -->
        <div class="container">
            <img src="pic.jpg" alt="">
            <img src="pic.jpg" alt="">
            <img src="pic.jpg" alt="">
            <img src="pic.jpg" alt="">
            <img src="pic.jpg" alt="">
            <img src="pic.jpg" alt="">
            <img src="pic.jpg" alt="">
        </div>
    </div>
</body>
<script>
    let container = document.querySelector(".container")
    let body = document.querySelector("body")
    let swipe = document.querySelector(".swipe")

    function resize() {
        body.style.height = container.offsetHeight + 'px'
    }
    function scroll() {
        swipe.style.top = `${-scrollY}px`
    }

    window.addEventListener("scroll", scroll)
    window.addEventListener("load", resize)
</script>

</html>

一个是让fixed视图动,还有一个是让container容器移动,效果都可以实现

这里存在一个小问题,当图片没有设置宽/高,而是100%自适应时offsetHeight获取到的终点位置会过高,我们有两种解决办法

1.设置图片的宽度/高度

2.监听图片加载当所有图片加载完成执行resize重新设置大小

这里我采用了第二种办法,遍历img标签为其设置监听事件再判断是否需要重新设置大小

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>滑动阻尼</title>
</head>
<style>
    * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
    }

    img {
        width: 100%;
    }

    .container {
        width: 100%;
        position: relative;
    }

    .swipe {
        position: fixed;
        top: 0;
        transition: top 0.15s ease;
    }
</style>

<body>
    <!-- swipe是视图窗口,通过移动他来展示container的内容 -->
    <div class="swipe">
        <!-- container只是用来存放一堆图片,并且获取高度给body,即父级的父级元素的高度 -->
        <div class="container">
            <img src="pic.jpg" alt="">
            <img src="pic.jpg" alt="">
            <img src="pic.jpg" alt="">
            <img src="pic.jpg" alt="">
            <img src="pic.jpg" alt="">
            <img src="pic.jpg" alt="">
            <img src="pic.jpg" alt="">
        </div>
    </div>
</body>
<script>
    let container = document.querySelector(".container")
    let body = document.querySelector("body")
    let swipe = document.querySelector(".swipe")

    function resize() {
        body.style.height = container.offsetHeight + 'px'
    }
    function scroll() {
        swipe.style.top = `${-scrollY}px`
    }

    let images = document.querySelectorAll('.container img');
    let imagesLoaded = 0;

    function checkImages() {
        imagesLoaded++;
        if (imagesLoaded === images.length) {
            console.log(container.offsetHeight);
            resize()
        }
    }

    images.forEach(img => {
        img.addEventListener('load', checkImages);
    });

    window.addEventListener("scroll", scroll)
    window.addEventListener("load", resize)
</script>

</html>