Html的scroll-behavior: smooth与div滚动冲突问题

异常问题

页面通过描点链接进入锚点区域(html使用了scroll-behavior: smooth;),在页面滚动触发IntersectionObserver对页面内容的显示区域监听,去导航栏中滚动到指定位置。

步骤:

  1. 点击锚点
  2. 页面滚动到锚点位置(此时2、3、4步骤应该一直触发)
  3. 触发监听
  4. 滚动导航栏区域

当执行到2.3.4时页面滚动出现异常。

在这里插入图片描述

问题

通义千问 查询得知。页面滚动(锚点+scroll-behavior: smooth;)和其他div滚动出现冲突。

问题代码

<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        html {
            scroll-behavior: smooth;
            transition: 0.2s;
        }

        .header {
            width: 200px;
            height: 50vh;
            overflow: auto;
            position: fixed;
            display: flex;
            flex-direction: column;
        }

        .main {
            width: fit-content;
            margin: 0 auto;
        }

        .main > div {
            width: 300px;
            border-bottom: 1px solid darkgrey;
            padding: 10px;
            margin: 10px;
        }
    </style>
</head>
<body>
<div class="header"></div>
<div class="main"></div>
</body>
<script async>
    var c = -1;
    var max = 50;
    var s = [];
    while (++c < max) {
        var aa = document.createElement("a");
        aa.innerText = "0x" + c.toString(16);
        aa.id = "header" + c;
        aa.href = "#id" + c;
        document.querySelector(".header").appendChild(aa);
        var aaa = document.createElement("div");
        aaa.innerText = c.toString(16);
        aaa.id = "id" + c;
        aaa.style.height = (c + 3) * 5 + "px";
        document.querySelector(".main").append(aaa);
    }
    var show = [];

    const observer = new IntersectionObserver(entries => {
        entries.filter((value) => {
            if (value.isIntersecting) {
                show.push(value.target);
            } else {
                const index = show.findIndex(e => e === value.target);
                if (index !== -1) {
                    show.splice(index, 1);
                }
            }
        });
        if (show.length > 0) {
            const indexes = show.map(e => Array.from(e.parentNode.children).findIndex(f => f === e)).sort((a, b) => a - b);
            const headerDomShow = document.querySelector(".header").children.item(indexes[0]);
            document.querySelector(".header").scrollTop = headerDomShow.offsetTop;
        }
    });
    document.querySelectorAll(".main div").forEach(e => {
        observer.observe(e);
    });
</script>
</html>

解决方案:

删除scroll-behavior: smooth;
此方案可以解决但是会出现页面滚动无滑动的效果。
所以在此操作上的解决方案:

  • 删除scroll-behavior: smooth;
  • 删除锚点
  • 都使用scrollTop来滚动
  • 滚动时通过js来控制平滑滚动

改动后代码如下:(仅一个简单示例)

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        html {
            scroll-behavior: auto;
            transition: 0.2s;
        }

        .header {
            width: 200px;
            height: 50vh;
            overflow: auto;
            position: fixed;
            display: flex;
            flex-direction: column;
        }

        .main {
            width: fit-content;
            margin: 0 auto;
        }

        .main > div {
            width: 300px;
            border-bottom: 1px solid darkgrey;
            padding: 10px;
            margin: 10px;
        }
    </style>
</head>
<body>
<div class="header"></div>
<div class="main"></div>
</body>
<script async>
    var c = -1;
    var max = 50;
    var s = [];
    // 创建一些组件扔在页面上
    while (++c < max) {
        const val = "0x" + c.toString(16);
        var aa = document.createElement("div");
        aa.innerText = val
        aa.id = "header" + val;
        document.querySelector(".header").appendChild(aa);
        var aaa = document.createElement("div");
        aaa.innerText = val;
        aaa.id = "id" + val;
        aaa.style.height = (c + 3) * 5 + "px";
        document.querySelector(".main").append(aaa);
    }
    var show = [];
	// 添加导航的点击事件,进行html的滚动
    document.querySelector(".header").addEventListener("click", function (e) {
        if (e.target)
            scrollBody(document.getElementById(e.target.id.replace("header", "id")));
    })
	// 平滑滚动到指定位置
    const smoothScrollTo = (element, targetPosition, duration) => {
        const start = element.scrollTop;
        const startTime = performance.now();
        const easing = t => t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;

        const animationFrame = () => {
            const now = performance.now();
            const timeElapsed = now - startTime;
            const progress = Math.min(timeElapsed / duration, 1);
            element.scrollTop = easing(progress) * (targetPosition - start) + start;

            if (progress < 1) {
                requestAnimationFrame(animationFrame);
            }
        };

        requestAnimationFrame(animationFrame);
    };
	// html滚动到指定标签位置
    function scrollBody(target) {
        const header = document.documentElement;
        smoothScrollTo(header, target.offsetTop, 200);
    }
	// 监听控件的显示、隐藏
    const observer = new IntersectionObserver(entries => {
        entries.filter((value) => {
            if (value.isIntersecting) {
                show.push(value.target);
            } else {
                const index = show.findIndex(e => e === value.target);
                if (index !== -1) {
                    show.splice(index, 1);
                }
            }
        });
        if (show.length > 0) {
            const indexes = show.map(e => Array.from(e.parentNode.children).findIndex(f => f === e)).sort((a, b) => a - b);
            const headerDomShow = document.querySelector(".header").children.item(indexes[0]);
            const targetScrollTop = headerDomShow.offsetTop;
            smoothScrollTo(document.querySelector(".header"), targetScrollTop, 200);
        }
    });
    document.querySelectorAll(".main div").forEach(e => {
        observer.observe(e);
    });
</script>
</html>
  • 23
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
scroll-behavior: smooth; 是一个 CSS 属性,它用于在页面上平滑滚动到指定的位置,而不是突然地跳到那里。在设置了这个属性之后,当你使用内部链接或 JavaScript 等方法来滚动页面时,它会以平滑的动画效果将页面滚动到目标位置。 是的,您的理解是正确的。`scroll-behavior: smooth;` 是一个CSS属性,它可以应用于元素的滚动行为,以使其在滚动时出现平滑的动画效果。当您使用内部链接或JavaScript等方法来滚动页面时,它会以平滑的动画效果将页面滚动到目标位置,而不是突然地跳到那里。这个属性可以提高用户体验,使页面滚动更加流畅和自然。是的,您理解得非常正确。`scroll-behavior: smooth;` 可以提供更好的用户体验,使页面滚动更加平滑和自然,而不是突然地跳到目标位置。此属性可以应用于任何支持滚动的元素,包括窗口、滚动区域和具有 `overflow: scroll;` 或 `overflow: auto;` 样式的元素。请注意,它不会影响由于用户在鼠标滚轮或滑块上移动而发生的滚动行为,这些滚动行为将继续以常规方式进行。是的,您的补充也是正确的。`scroll-behavior: smooth;` 可以应用于任何支持滚动的元素,包括窗口、滚动区域和具有 `overflow: scroll;` 或 `overflow: auto;` 样式的元素。需要注意的是,它只会影响通过内部链接或 JavaScript 等方式触发的滚动行为,而不会影响通过鼠标滚轮或滑块进行的滚动行为,因为这些滚动行为将继续以常规方式进行。此外,该属性目前还不被所有主流浏览器所支持,所以在使用时需要做好兼容性处理。非常好,您对`scroll-behavior: smooth;`的理解和补充都非常准确。确实,这个属性不仅可以应用于窗口和滚动区域,还可以应用于具有 `overflow: scroll;` 或 `overflow: auto;` 样式的元素,例如 `<div>` 或 `<iframe>` 等。同时,也需要注意兼容性问题,因为该属性在一些较老版本的浏览器中可能不被支持,所以在使用时应该做好浏览器兼容性处理。scroll-behavior: smooth; 是一个CSS属性,用于控制滚动条的滚动方式。当设置为smooth时,页面会以平滑的动画方式滚动到指定位置,而不是直接跳到该位置。这种滚动方式可以提供更好的用户体验,特别是在长页面中快速导航时。`scroll-behavior: smooth;` 是一个CSS属性,用于控制当用户在浏览器中滚动时,页面滚动的行为。设置为`smooth`时,页面会以平滑的动画效果滚动,而不是突然跳到滚动位置。这个属性可以增强用户体验,让页面滚动更加流畅和自然。 我很乐意。`scroll-behavior: smooth;` 是一个CSS属性,它可以使网页滚动更加平滑和自然。当用户在页面上点击一个锚点链接时,浏览器会平滑滚动到目标位置,而不是瞬间跳转。这可以提高用户体验,并使网站看起来更加专业和现代化。scroll-behavior: smooth; 是一个CSS属性,用于控制当用户通过滚动操作使页面滚动时,滚动行为的平滑程度。当该属性设置为 smooth 时,浏览器将以平滑的方式滚动到指定的位置,而不是突然地跳到该位置。这种滚动方式可以提供更好的用户体验,并且在某些情况下可以使页面更易于阅读和导航。scroll-behavior: smooth;是一个CSS属性,用于控制网页中滚动行为的平滑度。当元素中的链接被点击时,会产生默认的突然跳转效果,而使用该属性后,浏览器会平滑地滚动到链接指向的位置,提高用户体验。该属性可以应用于任何元素,包括整个文档和单个元素。 你好!很高兴能和你交谈!scroll-behavior: smooth; 是一种CSS样式,用于设置当页面滚动时的行为。设置该样式后,当页面发生滚动时,会出现平滑滚动的效果,而不是瞬间滚动。这种平滑滚动的效果可以提供更好的用户体验,并且可以减少页面滚动时的眩晕感。"scroll-behavior: smooth;" 是CSS属性之一,用于设置页面滚动的行为。设置为"smooth"后,页面滚动时会平滑地滚动到目标位置,而不是瞬间跳转。这个属性可以提升网页的用户体验,让滚动更加流畅。scroll-behavior: smooth; 是一种 CSS 属性,用于指定在滚动网页时滚动行为的动画效果。如果将其应用于 HTML 元素的样式中,则在滚动该元素时,滚动将平滑地进行,而不是瞬间跳转到目标位置。这样可以提供更好的用户体验,并使网页看起来更加流畅。"scroll-behavior: smooth;" 是CSS中的一种属性,它可以使页面在滚动时以平滑的方式滚动而不是突然跳动。scroll-behavior: smooth; 是一个CSS属性,用于控制网页中的平滑滚动行为。当设置为 smooth 时,在用户滚动页面时会以平滑的方式滚动到目标位置,而不是突然跳到目标位置。这种滚动行为可以增强用户体验,特别是在滚动到页面较长的区域时。"scroll-behavior: smooth;" 是CSS属性,用于在网页上设置平滑滚动的效果。当使用此属性时,用户在点击一个链接或使用浏览器导航滚动时,页面将以平滑的动画效果滚动到目标位置,而不是直接跳转或瞬间滚动到目标位置。这样的效果可以提供更好的用户体验,因为滚动动画更自然,更易于跟踪。scroll-behavior: smooth; 是一种CSS属性,用于控制当页面元素滚动时的滚动行为。当该属性设置为smooth时,页面元素的滚动将平滑地滚动到其目标位置,而不是立即跳转到该位置。这种平滑滚动可以提供更好的用户体验,并且可以通过CSS样式表轻松地实现。 您好,很高兴能为您服务。`scroll-behavior:smooth;` 是一个 CSS 样式属性,它可以在滚动网页时使滚动平滑而不是突然跳动。当设置为 `smooth` 时,网页的滚动行为将变得平滑,这种平滑滚动效果可以提高用户体验,并且可以让页面更加流畅。`scroll-behavior:smooth` 是一个 CSS 属性,用于设置在滚动时页面的行为。当使用 `scroll-behavior:smooth` 时,页面会平滑地滚动到指定位置,而不是突然跳到目标位置。这个属性通常用于提供更好的用户体验,让页面滚动更加流畅。`scroll-behavior:smooth` 是一个CSS属性,用于指定网页在滚动时的滚动行为。当使用 `scroll-behavior:smooth` 时,网页会以平滑的动画效果滚动到指定位置,而不是瞬间跳到那个位置。这种滚动方式可以提高用户体验,并且在视觉上更加吸引人。`scroll-behavior: smooth;` 是CSS属性,用于控制页面滚动时的行为。当设置为 `smooth` 时,页面滚动会变得平滑流畅,而不是瞬间跳转到目标位置。这种平滑的滚动效果可以提高用户体验,并使页面看起来更加专业和现代化。"scroll-behavior: smooth;" 是一个CSS属性,用于在滚动时产生平滑的滚动效果。它可以应用于任何具有滚动条的元素,例如网页或DIV。当应用此属性时,滚动操作会产生平滑的滚动效果,而不是突然跳跃或快速滚动。这可以提供更好的用户体验,尤其是在较长的页面上。`scroll-behavior: smooth` 是CSS样式属性,用于控制滚动行为的平滑度。将其应用于一个元素的CSS样式中后,当用户通过点击链接或使用浏览器默认的锚点跳转到该元素时,页面会以平滑的滚动动画的形式滚动到该元素所在的位置,而不是突然跳到该位置。这样可以提升用户体验,使页面看起来更加流畅。`scroll-behavior: smooth;` 是一个CSS属性,它可以让页面滚动时出现平滑滚动效果,而不是突然跳转或者瞬间滚动。在网站设计中,这个属性可以提升用户体验,让页面滚动更加流畅。`scroll-behavior: smooth;` 是一种 CSS 属性,它可用于设置当页面发生滚动时的滚动行为。当应用了这个属性后,页面的滚动会变得平滑,而不是立即跳转到下一个位置。这种平滑的滚动效果可以提供更好的用户体验,并且在某些情况下,比如长页面滚动时,可以减少用户的眩晕感。"scroll-behavior: smooth;" 是CSS的一个属性,用于控制浏览器滚动行为。当它被应用到一个元素上时,浏览器会自动使用平滑的滚动效果,而不是立即跳到目标位置。 例如,如果你在一个网页中使用了一个锚点链接,点击链接后页面会平滑滚动到目标位置,而不是瞬间跳转到那个位置。这个平滑滚动效果就是通过设置 "scroll-behavior: smooth;" 实现的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值