zoukankan      html  css  js  c++  java
  • 使用原生js + css 实现一个文字轮播效果(一)

    1、思路:

    因为offsetTop、scrollTop等不属于css属性,所以这些无法用css动画或过度来实现。首先想到的是使用position + top 定位结合 transition 来实现。

    2、效果:

    3、原生代码:

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script language="javascript" type="text/javascript">
           window.onload=function(){
            var boxContainer =  document.getElementById('boxContainer');
            var ulList = document.getElementById('ulList');
            var ulListLen = ulList.children.length;
            var speed = 3000;//移动速度,值越大速度越慢
            var timer = null;//定时器
            var liHeight = 30;//li列表的高度
                  function marquee() {
              console.log(ulList.offsetTop, ulList.style.top)
              if (ulList.offsetTop <= -(liHeight * (ulListLen - 1))){//判断复制的信息是否到达box的最左边
                ulList.style.top = 0;
                ulList.style.transition = 'none';
                marquee();
              }else {
                ulList.style.transition = 'all .5s ease-in-out';
                ulList.style.top = (ulList.offsetTop - liHeight) + 'px';
              }
            }
            timer = setInterval(marquee, speed);//设置定时器
           }
        </script>
        <style>
          #boxContainer{
            overflow:hidden;
            height:32px;
            width:300px;
            border:1px solid #000;
            position: relative;
          }
            .liItems{
                width: 300px;
            height: 30px;
            line-height: 30px;
            text-align: center;
            }
          #ulList{
            list-style-type: disc;
            margin-block: 0;
            margin-inline: 0;
            padding-inline: 0;
            position: absolute;
            top: 0;
            /* transition: all .5s ease-in-out; */
          }
        </style>
    </head>
    <body>
    <div  id="boxContainer">
      <ul id="ulList">
        <li class="liItems">人生在世须尽欢 莫使金樽空对月</li>
        <li class="liItems">我寄愁心与明月,随风直到夜郎西</li>
        <li class="liItems">不是花中偏爱菊,此花开尽更无花</li>
        <li class="liItems">辛苦遭逢起一经,干戈寥落四周星</li>
        <li class="liItems">山河破碎风飘絮,身世浮沉雨打萍。</li>
        <li class="liItems">惶恐滩头说惶恐,零丁洋里叹零丁。</li>
        <li class="liItems">人生自古谁无死?留取丹心照汗青。</li>
    
        <!-- 将第一条信息复制 -->
        <li class="liItems">人生在世须尽欢 莫使金樽空对月</li>
      </ul>
    </div>
    </body>
    </html>

    4、封装使用在react项目中:

    import React, { useEffect, useRef } from 'react';
    import { experimentalStyled } from '@material-ui/core';
    import moment from 'moment';
    import PropTypes from 'prop-types';
    
    moment.locale('zh-cn');
    
    const MainLayoutContent = experimentalStyled('div')({
      margin: '0 5px',
      overflow: 'hidden',
      height: '100%',
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
    });
    
    function WorldCarousel({
      dataList,
      liHeight,
      speed,
    }) {
      const boxContentRef = useRef();
      const ulRef = useRef();
      const timerRef = useRef();
    
      const marquee = () => {
        const ulListLen = ulRef.current.children.length;
        if (ulRef.current.offsetTop <= -(liHeight * (ulListLen - 1))) { // 判断复制的信息是否到达box的最左边
          ulRef.current.style.top = 0;
          ulRef.current.style.transition = 'none';
          marquee();
        } else {
          ulRef.current.style.transition = 'all .5s ease-in-out';
          ulRef.current.style.top = `${ulRef.current.offsetTop - liHeight}px`;
        }
      };
    
      const setEffectFunction = () => {
        timerRef.current = setInterval(marquee, speed * 1000);
      };
    
      const removeEffectFunction = () => {
        clearInterval(timerRef.current);
      };
    
      useEffect(() => {
        console.log({ boxContentRef });
        timerRef.current = setInterval(marquee, speed * 1000); // 设置定时器
        boxContentRef.current.onmouseenter = removeEffectFunction;
        boxContentRef.current.onmouseleave = setEffectFunction;
        return () => {
          clearInterval(timerRef.current);
        };
      }, []);
    
      const content = () => {
        dataList?.push(dataList[0]);
        return dataList.map((item, index) => (
          <li
            key={(index === (dataList.length - 1)) ? 'firstDataCope' : item.data}
            style={{
               '100%',
              height: liHeight,
              lineHeight: `${liHeight}px`,
              textAlign: 'center',
              fontSize: '18px',
              overflow: 'hidden',
              textOverflow: 'ellipsis',
              whiteSpace: 'nowrap'
            }}
          >
            <span>{ item.content }</span>
            &nbsp;&nbsp;
            <span>{ moment(item.data).fromNow() }</span>
          </li>
        ));
      };
    
      return (
        <MainLayoutContent>
          <div
            ref={boxContentRef}
            style={{
              overflow: 'hidden',
              height: `${liHeight}px`,
               '100%',
              border: 0,
              position: 'relative'
            }}
          >
            <ul
              ref={ulRef}
              style={{
                 '100%',
                listStyleType: 'disc',
                marginBlock: 0,
                marginInline: 0,
                paddingInline: 0,
                position: 'absolute',
                top: 0
              }}
            >
              { content() }
            </ul>
          </div>
        </MainLayoutContent>
      );
    }
    
    WorldCarousel.propTypes = {
      dataList: PropTypes.array, // 数据列表
      liHeight: PropTypes.number, // 移动速度,值越大速度越慢
      speed: PropTypes.number, // li列表的高度
    };
    
    WorldCarousel.defaultProps = {
      dataList: [],
      liHeight: 30,
      speed: 3,
    };
    
    export default WorldCarousel;

    5、使用:

    const dataList = [
      {
        data: 20200101,
        address: '杭州',
        content: '元旦抓娃娃开心啊',
      },
      {
        data: 20200202,
        address: '杭州',
        content: '二月二,炒大豆',
      },
      {
        data: 20200303,
        address: '杭州',
        content: '西湖美景,三月天哎',
      },
      {
        data: 20200404,
        address: '杭州',
        content: '愚人节快乐',
      },
      {
        data: 20200505,
        address: '杭州',
        content: '五月,我们来啦',
      },
      {
        data: 202006066,
        address: '杭州',
        content: '六月的雨,下个不停...',
      },
    ];
    
    <WorldCarousel dataList={dataList} liHeight={60} speed={3} />

     6、效果展示:

  • 相关阅读:
    C# SendKeys用法
    Winform的高DPI问题
    CefSharp在高DPI的屏幕上出现黑边(winform)
    CefSharp支持flash
    CeSharp支持MP4
    C#加密解密总览
    Eclipse 调试Bug之使用断点的七大技巧
    详解Eclipse断点
    怎样编写高质量的java代码
    Quartz任务调度基本使用
  • 原文地址:https://www.cnblogs.com/art-poet/p/14808224.html
Copyright © 2011-2022 走看看