使用原生js + css 实现一个文字轮播效果(一)

2021-05-28 03:00

阅读:398

标签:color   container   round   react   style   实现   leave   get   列表   

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 20px‘,
  overflow: ‘hidden‘,
  height: ‘100%‘,
  display: ‘flex‘,
  alignItems: ‘center‘,
  justifyContent: ‘center‘,
});

function WorldCarousel({
  dataList,
  liHeight,
  speed,
  liWidth
}) {
  const boxContentRef = useRef();
  const ulRef = useRef();
  const timerRef = useRef();

  const marquee = () => {
    const ulListLen = ulRef.current.children.length;
    if (ulRef.current.offsetTop // 判断复制的信息是否到达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(() => {
    timerRef.current = setInterval(marquee, speed * 1000); // 设置定时器
    boxContentRef.current.addEventListener(‘mouseenter‘, removeEffectFunction);
    boxContentRef.current.addEventListener(‘mouseleave‘, setEffectFunction);
    return () => {
      clearInterval(timerRef.current);
      boxContentRef.current.removeEventListener(‘mouseleave‘, setEffectFunction);
      boxContentRef.current.removeEventListener(‘mouseenter‘, removeEffectFunction);
    };
  }, []);

  const content = () => {
    dataList?.push(dataList[0]);
    return dataList.map((item, index) => (
      li
        key={(index === (dataList.length - 1)) ? ‘firstDataCope‘ : item.data}
        style={{
          width: liWidth,
          height: liHeight,
          lineHeight: `${liHeight}px`,
          textAlign: ‘center‘,
          fontSize: ‘18px‘,
        }}
      >
        { item.content }
          
        { moment(item.data, ‘YYYYMMDD‘).fromNow() }
      
    ));
  };

  return (
    div
        ref={boxContentRef}
        style={{
          overflow: ‘hidden‘,
          height: `${liHeight}px`,
          width: liWidth,
          border: 0,
          position: ‘relative‘
        }}
      >
        ul
          ref={ulRef}
          style={{
            listStyleType: ‘disc‘,
            marginBlock: 0,
            marginInline: 0,
            paddingInline: 0,
            position: ‘absolute‘,
            top: 0
          }}
        >
          { content() }
        
      
); } WorldCarousel.propTypes = { dataList: PropTypes.array, // 数据列表 liHeight: PropTypes.number, // 移动速度,值越大速度越慢 liWidth: PropTypes.number, // 宽度 speed: PropTypes.number, // li列表的高度 }; WorldCarousel.defaultProps = { dataList: [], liHeight: 30, liWidth: 300, 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: ‘六月的雨,下个不停...‘,
  },
];

 6、效果展示:

技术图片

 

使用原生js + css 实现一个文字轮播效果(一)

标签:color   container   round   react   style   实现   leave   get   列表   

原文地址:https://www.cnblogs.com/art-poet/p/14808224.html


评论


亲,登录后才可以留言!