React實(shí)現(xiàn)多標(biāo)簽在有限空間內(nèi)展示
場(chǎng)景
在業(yè)務(wù)中,需要在一個(gè)卡片組件中展示多個(gè)標(biāo)簽,標(biāo)簽組件高度相同,寬度和出現(xiàn)順序不同,要求標(biāo)簽只能在有限的空間內(nèi)展示(比如滿(mǎn)足放入兩行標(biāo)簽的空間),并在滿(mǎn)足最大展示數(shù)量的情況下,對(duì)超出部分進(jìn)行隱藏,然后通過(guò)鼠標(biāo) hover 的方式展示隱藏內(nèi)容
思路
標(biāo)簽的高度相同,空間內(nèi)可支持的標(biāo)簽行數(shù)固定,多標(biāo)簽的內(nèi)容可以轉(zhuǎn)化為一個(gè)數(shù)組數(shù)據(jù),所以可把問(wèn)題概括為:獲取在給定的行數(shù)內(nèi),按順序放入的不同寬度標(biāo)簽的最大數(shù)量,則余下的內(nèi)容為需要隱藏的標(biāo)簽內(nèi)容
有明確的輸入輸出,可以再進(jìn)一步轉(zhuǎn)化為一個(gè)算法問(wèn)題:給定一個(gè)數(shù)字?jǐn)?shù)組、限制的行數(shù)和行最大值,將數(shù)組中的數(shù)字依次放入行中并相加,相加的值不能超過(guò)行最大值,如果加入下一個(gè)數(shù)字后超出最大值,則該行不再計(jì)入該數(shù)字,并在下一行重新開(kāi)始放入計(jì)算,如果超出行數(shù),則停止,最后統(tǒng)計(jì)可以放入給定行中的最大數(shù)字?jǐn)?shù)量
const calculateLength = (rowNums: number[], rowCount: number, rowMaxValue: number) => { let count = 0; // 統(tǒng)計(jì)數(shù)字?jǐn)?shù)量 let currRow = 0; // 當(dāng)前行數(shù) let currSum = 0; // 當(dāng)前行的累加和 for (let i = 0; i < rowNums.length; i++) { // 當(dāng)前值大于最大值,停止 if (rowNums[i] > rowMaxValue) { break; } // 如果加入下一個(gè)數(shù)字后超出最大值,重新開(kāi)始計(jì)算 if (currSum + rowNums[i] > rowMaxValue) { currRow++; currSum = 0; } // 如果行數(shù)超過(guò)設(shè)定的行數(shù),停止統(tǒng)計(jì) if (currRow >= rowCount) { break; } // 更新當(dāng)前行的累加和 currSum += rowNums[i]; // 統(tǒng)計(jì)數(shù)字?jǐn)?shù)量 count++; } return count; };
項(xiàng)目中的實(shí)現(xiàn)
在明確思路后的,在項(xiàng)目中的實(shí)現(xiàn)只需要準(zhǔn)備好算法中的需要的參數(shù),再代入使用即可
需要獲取的內(nèi)容有:
- 標(biāo)簽寬度數(shù)組
- 行最大值
- 行數(shù):行數(shù)是基于設(shè)計(jì)稿限制的,可以直接使用常量定義
標(biāo)簽寬度數(shù)組、行最大值獲取
標(biāo)簽寬度數(shù)組的獲取似乎有點(diǎn)矛盾,既要隱藏超出的標(biāo)簽,但又需要標(biāo)簽渲染為實(shí)際的 Dom 后才可以獲取其寬度。這里直接采用比較粗暴的方式,使用絕對(duì)定位,脫離文檔流全量渲染標(biāo)簽內(nèi)容并隱藏,只用于獲取標(biāo)簽的寬度
<div> {renderTag()} <div ref={ref} style={{ positions: 'absolute', opacity: 0 }}> {renderAllTag()} </div> </div>
基于 ref 即可獲行最大值,即標(biāo)簽父級(jí) Dom 的寬度
const containerWidth = ref.current.clientWidth
在基于該 Dom 的 children 內(nèi)容,獲取標(biāo)簽的寬度數(shù)組
const tagChildren = ref.current.children; const itemWidthList = Array.from(tagsChildren).map(item => item.clientWidth)
最后帶入上述 calculateLength
方法,計(jì)算出實(shí)際需要渲染的最大數(shù)量,并對(duì)后端返回的標(biāo)簽數(shù)據(jù)進(jìn)行分割處理
最后
實(shí)現(xiàn)時(shí)還有一些需要注意的點(diǎn):
- 計(jì)算中,當(dāng)單個(gè)標(biāo)簽的寬度大于行最大寬度的時(shí)候,需要直接返回
- 計(jì)算出可以放入給定行中的最大數(shù)量后,還需要考慮給展示隱藏?cái)?shù)量的 Dom 留空間,可以在計(jì)算結(jié)果的基礎(chǔ)上,再減 1或減 2
以上就是React實(shí)現(xiàn)多標(biāo)簽在有限空間內(nèi)展示的詳細(xì)內(nèi)容,更多關(guān)于React多標(biāo)簽展示的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
React中useEffect與生命周期鉤子函數(shù)的對(duì)應(yīng)關(guān)系說(shuō)明
這篇文章主要介紹了React中useEffect與生命周期鉤子函數(shù)的對(duì)應(yīng)關(guān)系說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09一文詳解React中如何實(shí)現(xiàn)組件懶加載
懶加載是一種優(yōu)化技術(shù),旨在延遲加載不必要的資源,直到它們真正需要時(shí)再進(jìn)行加載,那么React的懶加載是如何實(shí)現(xiàn)的呢,下面小編就來(lái)和大家詳細(xì)講講吧2025-03-03詳解React-Router中Url參數(shù)改變頁(yè)面不刷新的解決辦法
這篇文章主要介紹了詳解React-Router中Url參數(shù)改變頁(yè)面不刷新的解決辦法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-05-05React Hook useState useEffect componentD
這篇文章主要介紹了React Hook useState useEffect componentDidMount componentDidUpdate componentWillUnmount問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03react render props模式實(shí)現(xiàn)組件復(fù)用示例
本文主要介紹了react render props模式實(shí)現(xiàn)組件復(fù)用示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07