摘要:很多時候,需要計算高度的元素都是動態(tài)生成的,我們無法在數(shù)據(jù)渲染前獲取到它的高度。獲取高度后頁面行數(shù)計算將在后面統(tǒng)一講解。優(yōu)點此方案通過直接在實際場景的頁面上渲染后進行高度計算,因此計算精準,不存在任何偏差。
背景
在開發(fā)IM的項目過程中,經(jīng)常會有出現(xiàn)一些需要計算DOM高度,然后超出若干行隱藏等需求。很多時候,需要計算高度的DOM元素都是動態(tài)生成的,我們無法在數(shù)據(jù)渲染前獲取到它的高度。
但是,如果我們需要獲取到這段在內(nèi)存中未渲染的動態(tài)文本,也能夠通過如下幾個方法。
技術(shù)方案根據(jù)前端的基本常識,在內(nèi)存中未渲染的DOM元素是無法獲取到高度的,因此我們有兩個方向來解決這個難題:
通過字數(shù)對行數(shù)進行估算
將元素渲染后進行高度測算
實現(xiàn)方案以下的實現(xiàn)方案將根據(jù)上面所選擇的技術(shù)方案來進行實現(xiàn)。
通過字數(shù)進行估算 方案此方案無需多言,就是通過字數(shù)和每一行能夠容下的字的個數(shù)進行估算等。在項目最開始時,我采用的就是這個方案。具體實現(xiàn)代碼太過簡單,因此也不在此添加了。
優(yōu)點此方案實現(xiàn)簡單,基本不需要任何成本,適用于只有等寬文字的情況下。
缺點這個方案缺點也比較明顯,基本無法用于純文本之外的任何情況。如果字體為非等寬字體或者存在 之類的換行符或者是 之類的制表符時,估算的準確度也會大大下降。
在DOM渲染后進行操作 方案顧名思義,此方案就是先不考慮DOM元素行數(shù)邏輯,直接將所有的DOM節(jié)點全部渲染到頁面中,渲染完成后再對進行后續(xù)邏輯判斷。獲取高度后頁面行數(shù)計算將在后面統(tǒng)一講解。
優(yōu)點此方案通過直接在實際場景的頁面上渲染后進行高度計算,因此計算精準,不存在任何偏差。同時,此方案實現(xiàn)起來也較為簡單,只需要將業(yè)務(wù)邏輯執(zhí)行時間后延,并不需要開發(fā)額外的代碼。
缺點該方案缺點也比較明顯,由于是先渲染后處理,因此頁面DOM元素會出現(xiàn)重繪和重排,導(dǎo)致頁面閃動,從而影響用戶的體驗。
鏡像計算 方案該方案的靈感來自于上一個方案。因為在實際的頁面中進行計算能夠保證頁面高度計算沒有任何誤差,因此我們需要一個實際的場景,讓瀏覽器來幫助我們進行高度計算。同時,我們又不能在具體的功能頁面中先渲染后計算,因此我們可以直接創(chuàng)建一個與實際頁面中一模一樣的容器來進行高度計算。這樣我們既能夠精確計算,又能夠不影響用戶體驗。
具體實現(xiàn)的代碼可以參考如下示例:
export default function getLines(element = "div", style = {}, html = "") { let node = document.createElement(element);//創(chuàng)建一個新容器 let length; each(style, (element, index)=>{ node.style[index] = element;//將傳入的style遍歷后賦值給新容器 }); node.innerHTML = html; document.body.appendChild(node);//需要將新容器掛載到DOM中,瀏覽器才會進行高度計算 let height = global.getComputedStyle(node).height; document.body.removeChild(node);//需要將鏡像DOM進行移除 if(height.indexOf("px")>0) { length = parseInt(height.split("px")[0]); }else { length = 0; } return length; }優(yōu)點
該方案基本上繼承了第二個方案的所有優(yōu)點——精確計算,無誤差,并且避免了出現(xiàn)頁面閃動的情況。
缺點此方案仍然存在一些問題,將新容器掛載到document元素上時,可能會引發(fā)DOM元素的重新渲染,極低概率會影響頁面布局。同時,屬性值等需要自己手動傳入,而不是利用現(xiàn)成的容器,比較費時費力。
方案再優(yōu)化 利用現(xiàn)有DOM容器使用cloneNode方法來對現(xiàn)有的容器進行clone,我們可以省去輸入樣式的麻煩,同時能夠精確保證兩個容器完全一致。
隱藏鏡像DOM在實踐過程中,在append以后立刻remove鏡像DOM節(jié)點,不會對頁面產(chǎn)生任何影響。如果擔(dān)心添加時會給頁面造成閃動效果,可以給鏡像DOM添加上position:fixed;visibility:hidden;z-index:-999;屬性,能夠讓鏡像DOM在append到頁面時,不會影響當(dāng)前頁面的任何布局。
為什么我們不使用display:none來實現(xiàn)上述效果呢?因為在使用了該屬性后,window.getComputedStyle獲取的高度將變?yōu)?b>auto。同理,如果元素的display屬性為inline時,也會出現(xiàn)類似的效果,因此我們需要將display指定為block或者inline-block。
理論上我們的容器都應(yīng)該為塊級元素,否則計算高度的意義也就不存在了。因此在容器clone時只需要留意即可,不需要重新指定。
兩個優(yōu)化點經(jīng)過實踐已經(jīng)證明可行,具體代碼就不附上了,如果有需要的可以給我留言~~
通過高度來計算行數(shù)目前,通過高度來計算行數(shù)并沒有什么比較好的方法,一般是通過line-height兩個屬性來進行計算。
如果line-height為倍數(shù)的話,則還需要font-size屬性來確定具體高度。
具體算法為:總高度 / 每一行高度 = 行數(shù)
而每一行高度則通過line-height或者line-height* font-size確定。
總結(jié)獲取動態(tài)元素的高度一直都是IM項目中的一個重要需求,自己在這個方面也踩了許多坑,因此寫了這一篇博客來進行記錄,同時其他人如果看到了也可以避免一些常見問題。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/49809.html
摘要:很多時候,需要計算高度的元素都是動態(tài)生成的,我們無法在數(shù)據(jù)渲染前獲取到它的高度。獲取高度后頁面行數(shù)計算將在后面統(tǒng)一講解。優(yōu)點此方案通過直接在實際場景的頁面上渲染后進行高度計算,因此計算精準,不存在任何偏差。 背景 在開發(fā)IM的項目過程中,經(jīng)常會有出現(xiàn)一些需要計算DOM高度,然后超出若干行隱藏等需求。很多時候,需要計算高度的DOM元素都是動態(tài)生成的,我們無法在數(shù)據(jù)渲染前獲取到它的高度。 ...
摘要:很多時候,需要計算高度的元素都是動態(tài)生成的,我們無法在數(shù)據(jù)渲染前獲取到它的高度。獲取高度后頁面行數(shù)計算將在后面統(tǒng)一講解。優(yōu)點此方案通過直接在實際場景的頁面上渲染后進行高度計算,因此計算精準,不存在任何偏差。 背景 在開發(fā)IM的項目過程中,經(jīng)常會有出現(xiàn)一些需要計算DOM高度,然后超出若干行隱藏等需求。很多時候,需要計算高度的DOM元素都是動態(tài)生成的,我們無法在數(shù)據(jù)渲染前獲取到它的高度。 ...
摘要:鼠標按下拖拽多選單元格這個是本唯一的亮點了個人認為。這樣做的結(jié)果是頁面非常卡,因為鼠標移動過程會多次觸發(fā)鼠標移動事件,會多次進行單元格元素循環(huán)遍歷。 網(wǎng)頁版模仿Excel 最近公司閑的dan疼,非要模仿Excel做一個網(wǎng)頁版的Excel,剛開始聽說要做這么一個東西的時候瞬間覺得公司領(lǐng)導(dǎo)高(sang)瞻(xin)遠(bing)矚(kuang),只能頭鐵的接下了,那就開始干。其實主要目的是...
摘要:鼠標按下拖拽多選單元格這個是本唯一的亮點了個人認為。這樣做的結(jié)果是頁面非常卡,因為鼠標移動過程會多次觸發(fā)鼠標移動事件,會多次進行單元格元素循環(huán)遍歷。 網(wǎng)頁版模仿Excel 最近公司閑的dan疼,非要模仿Excel做一個網(wǎng)頁版的Excel,剛開始聽說要做這么一個東西的時候瞬間覺得公司領(lǐng)導(dǎo)高(sang)瞻(xin)遠(bing)矚(kuang),只能頭鐵的接下了,那就開始干。其實主要目的是...
閱讀 1266·2021-11-24 09:39
閱讀 1515·2021-09-07 09:59
閱讀 3479·2019-08-30 15:54
閱讀 2474·2019-08-30 11:00
閱讀 2669·2019-08-29 15:06
閱讀 2159·2019-08-26 13:52
閱讀 427·2019-08-26 13:24
閱讀 2489·2019-08-26 12:20