最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于React.js實(shí)現(xiàn)簡單的文字跑馬燈效果

 更新時(shí)間:2023年01月14日 14:58:42   作者:鄭丫頭  
剛好手上有一個(gè)要實(shí)現(xiàn)文字跑馬燈的react項(xiàng)目,然后ant-design上面沒有這個(gè)組件,于是只能自己手?jǐn)]一個(gè),文中的實(shí)現(xiàn)方法講解詳細(xì),希望對大家有所幫助

剛好手上有一個(gè)要實(shí)現(xiàn)文字跑馬燈的react項(xiàng)目,然后ant-design上面沒有這個(gè)組件,于是只能自己手?jǐn)]一個(gè)。

我想到的最簡單的方法,就是定位啦,定時(shí)移動(dòng)這個(gè)文字塊不就跑起來了。

需要注意的是,要判斷文字的寬度,當(dāng)文字超出屏幕的寬度的時(shí)候再動(dòng)起來,我用的是hook的寫法,要在銷毀頁面的時(shí)候清掉定時(shí)器。定時(shí)器要放在useRef里面。

const timer = useRef<any>(null);
const [left, setLeft] = useState(0);
const contentRef = useRef<any>(null);
useEffect(() => {
    // 當(dāng)監(jiān)聽到文字變化時(shí),一定要先清掉定時(shí)器,如果文字較短的話就不會再啟動(dòng)    
    if (timer.current) {      clearInterval(timer.current);    }    
    const contentDom = contentRef.current;    
    if (contentDom) {      
      const obj = contentDom.getBoundingClientRect();
      // 判斷文字框長度      
      if (obj.width > props.width) {        
         timer.current = setInterval(() => {
         // 注意state是負(fù)數(shù),?當(dāng)數(shù)字移動(dòng)到最后的時(shí)候,下一次從父元素的寬度開始,看起來就是一直在向左移動(dòng)
         // 文字框的寬度要時(shí)時(shí)獲取
         // setLeft要從回調(diào)里面獲取,不然不能時(shí)時(shí)更新          
         setLeft((state) =>-state >= contentDom.getBoundingClientRect().width ? props.width : state - 1,          );        }, 100);
      } else {        setLeft(0);      }    
    }  
}, [props.children]);
useEffect(() => {
          // 注銷時(shí),清空定時(shí)器    
          return () => {      
            if (timer.current) {        clearInterval(timer.current);      }    
          };  
}, []);
return (<div className={styles.noticeCompWrapper} style={{ width: props.width, ...props.style }}>      
          <div ref={contentRef} className={styles.noticeContent} style={{ left }}>        {props.children}      </div>    
        </div>  );

.noticeCompWrapper {  
    height: 40px;  
    line-height: 40px;  
    overflow: hidden;  
     position: relative;  
    .noticeContent {   
       white-space: nowrap;    
       position: absolute;  
    }
}

這移動(dòng)效果還可以吧,時(shí)間間隔一定要小,不然就會一卡一卡的

第一種很容易吧,其實(shí)最開始是想用純css來寫的,考慮到css沒法獲取自適應(yīng)寬度,咋判斷文字移動(dòng)到末尾了?但是我覺得,css肯定是可以辦到,于是我繼續(xù)探索...

animation走起,,,咱們假設(shè)外邊框長120px,文字長240px

@keyframes run {  
0% {    transform: translateX(0);  }  
50% {    transform: translateX(-240px);  }  
50% {    transform: translateX(120px);  }  
100% {    transform: translateX(-240px);  }
}

總感覺有啥不對,這個(gè)字咋往回跑,這感覺跑來跑去的。。。

平心靜氣~沒事沒事,不就是個(gè)小bug么~

仔細(xì)思考一下,這只要寫兩個(gè)動(dòng)畫就解決了,因?yàn)槠鋵?shí)除了第一次不同,后面都是從右邊進(jìn)入視角的有木有。

@keyframes run {   
from {    transform: translateX(0);  }  
to {    transform: translateX(-240px);  }
}
@keyframes loop {  
from {    transform: translateX(120px);  }  
to {    transform: translateX(-240px);  }
}

咱們用的時(shí)候,第一個(gè)走一遍就好了,循環(huán)后面那個(gè):

.textContent {    
white-space: nowrap;    
animation-name: run, loop;    
animation-duration: 5s;    
animation-iteration-count: 1, infinite;
animation-timing-function: linear;    
position: relative;  
}

look,是不是好多了~

接下來就是文字長度的問題了~咋們咋控制他要不要?jiǎng)影。窟€有移動(dòng)的時(shí)間和距離咋控制??

首先動(dòng)畫時(shí)間,less肯定是算不出來了,那我們就在js外面計(jì)算一下哈~方法和上面類似,要取元素的寬度。

const contentRef = useRef<any>(null);  
const [duration, setDuration] = useState('');  
useEffect(() => {    
  const dom = contentRef.current;    
  if (dom) {      
    const { width } = dom.getBoundingClientRect();      
    if (width > props.width) {
      // 我這邊取的速度是按一個(gè)字的大小        
      setDuration(width / 16 + 's');      
    } else {
       // 小于寬度的時(shí)候清掉時(shí)間        
       setDuration('');      
    }    
  } else {      setDuration('');    }  
}, [props.children]);  
return (<div style={{ width: props.width, ...props.style }} className={styles.wrapper}    >      
  <div   
    className={styles.textContent}       
    ref={contentRef}
    // 計(jì)算好動(dòng)畫時(shí)間傳過去        
    style={{ 
            animationDuration: duration,
             // 第二個(gè)動(dòng)畫等第一個(gè)執(zhí)行之后執(zhí)行
             animationDelay: duration? `0s, ${duration}` :'',              
        }}      
   >       
  {props.children}      
  </div>    
</div>  );

完整的樣式

// 設(shè)置父元素的寬度
@width: 120px;
.wrapper {  
  position: relative;  
  overflow: hidden;  
  width: @width;  
  height: 40px;  
  line-height: 40px;  
  .textContent {    
      white-space: nowrap;    
      animation-name: run, roop;    
      animation-iteration-count: 1, infinite;
      animation-timing-function: linear;    
      // 這個(gè)很重要,不然寬度就和父元素一樣    
      position: absolute;  
   }
}
@keyframes run {  
from {    transform: translateX(0);  }  
to {
    // 這個(gè)100% 是文字的     
    transform: translateX(-100%);  
   }
}
@keyframes roop {  
from {    transform: translateX(@width);  }  
to {    transform: translateX(-100%);  }
}

不錯(cuò)不錯(cuò),這樣就解決了時(shí)間和制動(dòng)的問題了~

不過...,這還不夠完美。NOT PERFACT!

這個(gè)父元素的寬度是不是寫死了,要是要使用的話只能手動(dòng)改@width,咱有木有辦法通過js傳過來?你知道怎么改更好么?

哈哈,咱們基本上已經(jīng)完成了這種簡單的從左向右移動(dòng)的文字跑馬燈(為自己鼓掌),接下來就是升級版的了,跑馬燈plus。實(shí)現(xiàn)一個(gè)向上滾動(dòng)的跑馬燈。

咱們在第一步的基礎(chǔ)上來做一個(gè)向上滾動(dòng)的跑馬燈plus。

我們加一個(gè)向上的按鈕,可以控制文字跑動(dòng)的方向,當(dāng)然向右向下同理~這里就不做了

 <>      
<div 
    className={styles.noticeCompWrapper} 
    style={{ width: props.width, ...props.style, marginBottom: 10 }}
>
        <div  
           ref={contentRef} 
           className={styles.noticeContent} 
           style={{ left, top,
           // 換行的邏輯一定要加上,上下移動(dòng)的需要換行            
           whiteSpace: direction == DirectionEnum.左 ? 'nowrap' : 'initial',   
           }}       
         >          
        {props.children}        
        </div>      
</div>      
<Space>        
<Button onClick={() => { setDirection(DirectionEnum.左); setTop(0); }}> 向左</Button>        
<Button onClick={() => { setDirection(DirectionEnum.上); setLeft(0); }}> 向上</Button>      
</Space> 
</>

判斷下移動(dòng)方向

useEffect(() => {    
  // 當(dāng)監(jiān)聽到文字變化時(shí),一定要先清掉定時(shí)器,如果文字較短的話就不會再啟動(dòng)    
  if (timer.current) {      clearInterval(timer.current);    }    
  const contentDom = contentRef.current;    
  if (contentDom) {      
    const obj = contentDom.getBoundingClientRect();      
    if (direction == DirectionEnum.左) {
        // 同上...      
    } else if (direction == DirectionEnum.上) {
       // 向上        
      if (obj.height > 40) {          
        timer.current = setInterval(() => {            
          setTop(state =>-state >= contentDom.getBoundingClientRect().height ? 40 : state - 1);          
        }, 30);       
      }      
    } else {        
      setLeft(0);        
      setTop(0);      
    }    
  }  
}, [props.children, direction]);

看一下成果:

這種單行滾動(dòng)的效果,能不能實(shí)現(xiàn)一下?就是滾動(dòng)一行停留一段時(shí)間再繼續(xù)滾動(dòng)

這個(gè)也比較簡單,我用我上面的方法在引申一下,你們也可以用其他方法,animatioin也可以。

我在定時(shí)器里面在加一個(gè)延時(shí)timeout

timer.current = setInterval(() => {            
   setTop(state => {
     // 當(dāng)行數(shù)是40的整倍數(shù)的時(shí)候延遲執(zhí)行移動(dòng)              
     if ((state - 1) % 40 == 0) {                
       setTimeout(() => {                  
         setTop(state1 =>  -state1 >= contentDom.getBoundingClientRect().height ? 40 : state1 - 1);                
       }, 500);                
       return state;              
     } else {               
       return -state >= contentDom.getBoundingClientRect().height? 40 : state - 1;
     }            
   });          
}, 30);

效果:

以上就是基于React.js實(shí)現(xiàn)簡單的文字跑馬燈效果的詳細(xì)內(nèi)容,更多關(guān)于React文字跑馬燈的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • react?umi?刷新或關(guān)閉瀏覽器時(shí)清除localStorage方式

    react?umi?刷新或關(guān)閉瀏覽器時(shí)清除localStorage方式

    這篇文章主要介紹了react?umi?刷新或關(guān)閉瀏覽器時(shí)清除localStorage方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • react中antd文本框限制輸入中文方式

    react中antd文本框限制輸入中文方式

    這篇文章主要介紹了react中antd文本框限制輸入中文方式詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-06-06
  • React中memo useCallback useMemo方法作用及使用場景

    React中memo useCallback useMemo方法作用及使用場景

    這篇文章主要為大家介紹了React中三個(gè)hooks方法memo useCallback useMemo的作用及使用場景示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2023-03-03
  • 詳解如何用webpack4從零開始構(gòu)建react開發(fā)環(huán)境

    詳解如何用webpack4從零開始構(gòu)建react開發(fā)環(huán)境

    這篇文章主要介紹了詳解如何用webpack4從零開始構(gòu)建react開發(fā)環(huán)境,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-01-01
  • React實(shí)現(xiàn)反向代理和修改打包后的目錄

    React實(shí)現(xiàn)反向代理和修改打包后的目錄

    這篇文章主要介紹了React實(shí)現(xiàn)反向代理和修改打包后的目錄方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • react-router-dom 嵌套路由的實(shí)現(xiàn)

    react-router-dom 嵌套路由的實(shí)現(xiàn)

    這篇文章主要介紹了react-router-dom 嵌套路由的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • React如何接收excel文件下載導(dǎo)出功能封裝

    React如何接收excel文件下載導(dǎo)出功能封裝

    這篇文章主要介紹了React如何接收excel文件下載導(dǎo)出功能封裝,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • react解析html字符串方法實(shí)現(xiàn)

    react解析html字符串方法實(shí)現(xiàn)

    在使用reactjs庫的時(shí)候,會遇到將一段html的字符串,然后要將它插入頁面中以html的形式展現(xiàn),本文主要介紹了react解析html字符串方法實(shí)現(xiàn),感興趣的可以了解一下
    2023-12-12
  • react實(shí)現(xiàn)數(shù)據(jù)監(jiān)聽方式

    react實(shí)現(xiàn)數(shù)據(jù)監(jiān)聽方式

    這篇文章主要介紹了react實(shí)現(xiàn)數(shù)據(jù)監(jiān)聽方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • 最新版React?Native環(huán)境搭建(親測)

    最新版React?Native環(huán)境搭建(親測)

    這篇文章主要介紹了最新版React?Native環(huán)境搭建,React Native的運(yùn)行需要依賴原生Android和iOS環(huán)境,因此需要分別安裝原生Android和iOS的開發(fā)環(huán)境,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-08-08

最新評論

上饶市| 武宁县| 乐清市| 股票| 友谊县| 盘山县| 措勤县| 永城市| 三门峡市| 密山市| 南靖县| 双流县| 庄河市| 浮山县| 平山县| 兰溪市| 乾安县| 临汾市| 南涧| 深州市| 噶尔县| 沙坪坝区| 永嘉县| 富阳市| 桃园县| 衡山县| 襄垣县| 曲水县| 酒泉市| 临夏县| 尼玛县| 嘉荫县| 乡宁县| 贺州市| 沾化县| 玉山县| 芜湖县| 天峨县| 宣武区| 喀什市| 会泽县|