自动向上滚动,轮播,无限滚动

js实现列表自动向上滚动

方案一、js控制dom的margin-top减小

注意:复制一份滚动内容,滚到最后的时候不会留白,然后让margin-top归零实现重复滚动

/**
 * javascript原生自动滚动
 * @param domId 需要实现这个效果的domId
 * @param height 行高
 * @param speed 滚动速度,默认34,约30帧
 * @param delay 间隔多久滚动一行
 */
auroRiseScrolling(domId, height, speed = 33, delay = 1000) {
	let dom = document.getElementById(domId);
	// 判断内容是否超过容器高度需要滚动
	if (dom.offsetHeight <= dom.parentElement.offsetHeight) return;
    let stop = false; // 暂停滚动
    let t;
    dom.style.marginTop = '0';
    dom.innerHTML += dom.innerHTML; // 复制一份滚动内容,
    //鼠标移入,停止滚动
    dom.onmouseover = () => { stop = true; };
    //鼠标移出,继续滚动
    dom.onmouseout = () => { stop = false; };

    setTimeout(start, delay); // delay(1s)以后start()开始滚动

    function start() {
        t = setInterval(scrolling, speed); // speed(0)时间内向上滚动1px
        // 未停止时候,需要marginTop-1px,下面scrolling()里面的if()才会未为true,才能滚动,反之则会执行elese,清除上一次的timer,就不会滚动了
        if (!stop) dom.style.marginTop = `${parseInt(dom.style.marginTop) - 1}px`;
    }

    function scrolling() {
        // 判断是否滚动了一行的高度,滚了一行之后,if内容为true
        if (parseInt(dom.style.marginTop) % height !== 0) {
            dom.style.marginTop = `${parseInt(dom.style.marginTop) - 1}px`; // margin-top -= 1px ,向上滚动1px
            // dom.scrollHeight元素内容高度,由于前面复制了一份内容,所有当滚动高度为它的一半时候,代表滚完了,此时将marginTop归零(因为后一半内容和前面一样,肉眼看不出变化,实际上瞬间回到了顶部)
            if (Math.abs(parseInt(dom.style.marginTop)) >= dom.scrollHeight / 2) dom.style.marginTop = '0';
        } else {
            // 一行滚动结束,开始准备新的一行滚动
            clearInterval(t);
            setTimeout(start, delay);
        }
    }
}

TEMPLATE

<template>
    <div class="auto-scroll-box">
        <ul id="autoScroll">
            <li v-for="num in 20"> {{num}} </li>
        </ul>
    </div>
</template>

STYLE

<style scoped>
    .auto-scroll-box {
        width: 200px;
        height: 400px;
        margin: 0 auto;
        overflow: hidden;
    }
	/* 行高 */
    .auto-scroll-box > ul > li {
        height: 2rem;
    }
	/* 偶数行加个背景颜色 */
    .auto-scroll-box > ul > li:nth-child(odd) {
        background-color: #42b983;
    }
</style>

** 这里有两个小坑 **

  1. 尽可能的加载偶数行,复制的第一题内容和原本的第一条内容就一个奇数行一个偶数行,可能导致样式不同,出现闪烁效果。
  2. 如果显示器刷新频率低于144hz,不建议滚动速度过快,会出现抖动现象
开箱即用的完整demo
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
        * { margin: 0; padding: 0; }
        li { list-style-type: none; }
        .auto-scroll-box { width: 200px; height: 200px; border: 2px dotted #ccc; margin: 2rem auto; overflow: hidden; }
        .auto-scroll-box>ul>li { height: 2rem; line-height: 2rem; }
        .auto-scroll-box>ul>li:nth-child(odd) { background-color: #42b983; }
    </style>
    <title>自动向上滚动</title>
</head>

<body>
    <div class="auto-scroll-box">
        <ul id="autoScroll">
            <li> 1 </li>
            <li> 2 </li>
            <li> 3 </li>
            <li> 4 </li>
            <li> 5 </li>
            <li> 6 </li>
            <li> 7 </li>
            <li> 8 </li>
            <li> 9 </li>
            <li> 10 </li>
        </ul>
    </div>

    <script>
        auroRiseScrolling('autoScroll', 32, 100, 0);
        function auroRiseScrolling(domId, height, speed = 0, delay = 1000) {
            let dom = document.getElementById(domId);
            if (dom.offsetHeight <= dom.parentElement.offsetHeight) return;
            let stop = false;
            let t;
            dom.style.marginTop = '0';
            dom.innerHTML += dom.innerHTML;
            dom.onmouseover = () => {
                stop = true;
            };
            dom.onmouseout = () => {
                stop = false;
            };
            setTimeout(start, delay);
            function start() {
                t = setInterval(scrolling, speed);
                if (!stop) dom.style.marginTop = `${parseInt(dom.style.marginTop) - 1}px`;
            }
            function scrolling() {
                if (parseInt(dom.style.marginTop) % height !== 0) {
                    dom.style.marginTop = `${parseInt(dom.style.marginTop) - 1}px`;
                    if (Math.abs(parseInt(dom.style.marginTop)) >= dom.scrollHeight / 2) dom.style.marginTop = '0';
                } else {
                    clearInterval(t);
                    setTimeout(start, delay);
                }
            }
        }
    </script>
</body>
</html>

方案二、动态生成animation

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值