欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

使用React+ts實(shí)現(xiàn)無縫滾動的走馬燈詳細(xì)過程

 更新時(shí)間:2023年08月17日 10:08:50   作者:林不羈  
這篇文章主要給大家介紹了關(guān)于使用React+ts實(shí)現(xiàn)無縫滾動的走馬燈詳細(xì)過程,文中給出了詳細(xì)的代碼示例以及圖文教程,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

一、走馬燈的作用

走馬燈是一種常見的網(wǎng)頁交互組件,可以展示多張圖片或者內(nèi)容,通過自動播放或者手動切換的方式,讓用戶能夠方便地瀏覽多張圖片或者內(nèi)容。本次實(shí)現(xiàn)的不是輪播圖而是像傳送帶一樣的無限滾動的形式。

二、需求梳理

走馬燈可設(shè)置一下屬性:

  • 滾動速度
  • 滾動方向
  • 一屏要顯示項(xiàng)的個(gè)數(shù)
  • 容器的寬度
  • 要展示的數(shù)據(jù)
  • 自定義展示項(xiàng)

1691745987770-30b3877e-d08e-433d-b670-b37ad66bc069.gif

三、實(shí)現(xiàn)思路

3.1 首先確定一下我們的dom元素

wrap>list>item*n

  • 最外層wrap用于限制顯示區(qū)域的寬度,超過寬度就隱藏。
  • list 用于滾動顯示數(shù)據(jù),所以我們的動畫加在這個(gè)元素上。
  • item 用于放置展示項(xiàng)。

3.2 實(shí)現(xiàn)無限滾動的動畫

我們用keyframes關(guān)鍵幀動畫來做。但是要滾動多少距離才能實(shí)現(xiàn)無限滾動呢?

1.計(jì)算動畫滾動距離

1691747412524-776d33fb-2379-404a-846d-bf82d6b5b59c.jpeg

從上面的圖中我們可以看到當(dāng)list的寬度<wrap的寬度(containerWidth)時(shí),會出現(xiàn)滾動后出現(xiàn)空白的情況。那么第二張圖,list的寬度>=wrap的兩倍,就能在向左滾動完list的一半后,不會出現(xiàn)空白,而且為了給人一種無限滾動的效果,list的前后兩部分?jǐn)?shù)據(jù)要保持一致。所以滾動的距離 = 展示數(shù)據(jù)的個(gè)數(shù) * 每項(xiàng)的寬度,而為了無限滾動效果,我們還需要對原始數(shù)據(jù)進(jìn)行處理。分為以下幾種情況:

  • 數(shù)據(jù)個(gè)數(shù)>= 一屏展示個(gè)數(shù)(showNum)

此時(shí)重復(fù)兩次原始數(shù)據(jù)就能得到滾動數(shù)據(jù)

  • 數(shù)據(jù)個(gè)數(shù)< 一屏展示個(gè)數(shù)

首先我們要保證沒有空白,那要如何填充呢?只填充到=showNum,行不行呢?我們可以看一下:比如說原始數(shù)據(jù)為[1,2,3],填充完再進(jìn)行重復(fù)則為 [1,2,3,1,1,2,3,1],這樣會出現(xiàn)1這一項(xiàng)連續(xù)出現(xiàn)了。所以最好的方式是直接填充原始數(shù)據(jù)直到>=showNum,所以最終我們得到的滾動數(shù)據(jù)是[1,2,3,1,2,3 ,1,2,3,1,2,3]

2.插入動畫

因?yàn)槲覀兊膭赢嬍歉鶕?jù)傳入的變量得來的,所以不能直接寫在樣式文件里,我們通過在useEffect里插入樣式表對象的方式來實(shí)現(xiàn)。

四、完整代碼

組件代碼

import { ReactElement, useEffect } from "react";
import * as React from "react";
import "./index.less";
import { ItemProps } from "./demo";
interface Props {
  Item: (item: ItemProps) => ReactElement;
  showNum: number;
  speed: number;
  containerWidth: number;
  data: Array<any>;
  hoverStop?: boolean;
  direction?: "left" | "right";
}
const fillArray = (arr: any[], length: number): any[] => {
  const result: any[] = [];
  while (result.length < length) {
    result.push(...arr);
  }
  return result.concat(result);
};
function AutoplayCarousel({
  Item,
  showNum,
  speed,
  containerWidth,
  data,
  hoverStop = false,
  direction = "left"
}: Props) {
  const showData = fillArray(data, showNum);
  const length = showData.length;
  const itemWidth = containerWidth / showNum;
  useEffect(() => {
    // 創(chuàng)建一個(gè)新的樣式表對象
    const style = document.createElement("style");
    // 定義樣式表的內(nèi)容
    let start = "0";
    let end = `-${(itemWidth * length) / 2}`;
    if (direction === "right") {
      start = end;
      end = "0";
    }
    style.innerText = `
      @keyframes templates-partner-moving {
        0% {
           transform: translateX(${start}px);
        }
        100% {
          transform: translateX(${end}px);
        }
      }
    `;
    if (hoverStop) {
      style.innerText += `.list:hover {
      /*鼠標(biāo)經(jīng)過后,動畫暫停*/
      animation-play-state: paused !important;
    }`;
    }
    // 將樣式表插入到文檔頭部
    document.head.appendChild(style);
    // 組件卸載時(shí)清除樣式表
    return () => document.head.removeChild(style) as any;
  }, []);
  return (
    <div style={{ width: `${containerWidth}px` }} className="wrap">
      <div
        className="list"
        style={{
          width: `${itemWidth * length}px`,
          animation: `templates-partner-moving ${
            (length / showNum / 2) * speed
          }s infinite linear`
        }}
      >
        {showData.map((item) => (
          <div style={{ width: `${itemWidth}px` }}>
            <Item {...item} />
          </div>
        ))}
      </div>
    </div>
  );
}
export default AutoplayCarousel;

demo代碼

import React from "react";
import AutoplayCarousel from "./index";
const data = new Array(5).fill(0).map((item, index) => {
  return { num: index };
});
console.log("data", data);
export interface ItemProps {
  num: number;
}
const itemStyle = {
  border: "1px solid #ccc",
  background: "#fff",
  height: "50px",
  color: "red",
  marginRight: "15px"
};
function Demo() {
  const Item = (item: ItemProps) => {
    return <div style={itemStyle}>{item.num}</div>;
  };
  return (
    <AutoplayCarousel
      Item={Item}
      containerWidth={500}
      showNum={5}
      speed={8}
      data={data}
    />
  );
}
export default Demo;

樣式代碼

* {
	margin: 0;
	padding: 0;
}
.wrap {
	overflow: hidden;
	.list {
		position: relative;
		top: 0px;
		left: 0px;
		height: 100%;
		display: flex;
	}
}

總結(jié) 

到此這篇關(guān)于使用React+ts實(shí)現(xiàn)無縫滾動的走馬燈的文章就介紹到這了,更多相關(guān)React+ts實(shí)現(xiàn)無縫滾動走馬燈內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 在React項(xiàng)目中使用iframe嵌入一個(gè)網(wǎng)站的步驟

    在React項(xiàng)目中使用iframe嵌入一個(gè)網(wǎng)站的步驟

    本文介紹了如何在React項(xiàng)目中通過iframe嵌入百度網(wǎng)站的步驟,首先創(chuàng)建一個(gè)Baidu.js組件,并在該組件中設(shè)置iframe來加載百度,然后在App.js中引入并使用Baidu組件,還討論了因安全策略可能無法加載某些網(wǎng)站的問題,需要的朋友可以參考下
    2024-09-09
  • React子組件調(diào)用父組件方法獲取的數(shù)據(jù)不是最新值的解決方法

    React子組件調(diào)用父組件方法獲取的數(shù)據(jù)不是最新值的解決方法

    這篇文章主要介紹了React子組件調(diào)用父組件方法獲取的數(shù)據(jù)不是最新值的解決方法,文中通過代碼示例介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-09-09
  • react使用.env文件管理全局變量的方法

    react使用.env文件管理全局變量的方法

    本文主要介紹了react使用.env文件管理全局變量的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • react中的DOM操作實(shí)現(xiàn)

    react中的DOM操作實(shí)現(xiàn)

    某些情況下需要在典型數(shù)據(jù)流外強(qiáng)制修改子代。要修改的子代可以是 React 組件實(shí)例,也可以是 DOM 元素。這時(shí)就要用到refs來操作DOM,本文詳細(xì)的介紹一下使用,感興趣的可以了解一下
    2021-06-06
  • JavaScript的React框架中的JSX語法學(xué)習(xí)入門教程

    JavaScript的React框架中的JSX語法學(xué)習(xí)入門教程

    這篇文章主要介紹了JavaScript的React框架中的JSX語法學(xué)習(xí)入門教程,React是由Facebook開發(fā)并開源的高人氣js框架,需要的朋友可以參考下
    2016-03-03
  • 六分鐘帶你快速學(xué)會react中的useMemo

    六分鐘帶你快速學(xué)會react中的useMemo

    簡單說React.memo()是通過校驗(yàn)props中的數(shù)據(jù)是否改變的來決定組件是否需要重新渲染的一種緩存技術(shù),下面這篇文章主要給大家介紹了關(guān)于如何快速學(xué)會react中useMemo的相關(guān)資料,需要的朋友可以參考下
    2022-12-12
  • 解決React報(bào)錯(cuò)Rendered more hooks than during the previous render

    解決React報(bào)錯(cuò)Rendered more hooks than during

    這篇文章主要為大家介紹了React報(bào)錯(cuò)Rendered more hooks than during the previous render解決方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • React超詳細(xì)講述Fiber的使用

    React超詳細(xì)講述Fiber的使用

    在fiber出現(xiàn)之前,react的架構(gòu)體系只有協(xié)調(diào)器reconciler和渲染器render。當(dāng)前有新的update時(shí),react會遞歸所有的vdom節(jié)點(diǎn),如果dom節(jié)點(diǎn)過多,會導(dǎo)致其他事件影響滯后,造成卡頓。即之前的react版本無法中斷工作過程,一旦遞歸開始無法停留下來
    2023-02-02
  • 簡析React Native startReactApplication 方法

    簡析React Native startReactApplication 方法

    這篇文章主要介紹了React Native startReactApplication 方法簡析,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-09-09
  • 使用VScode 插件debugger for chrome 調(diào)試react源碼的方法

    使用VScode 插件debugger for chrome 調(diào)試react源碼的方法

    這篇文章主要介紹了使用VScode 插件debugger for chrome 調(diào)試react源碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09

最新評論