一種通過js確定元素真實空間size的方式

我們在前端排版的時候,有時候會面臨元素寬度超出容器的問題,當然,一般我們用css的溢出省略,可以做到排版上穩妥:

overflow: hidden;ntext-overflow:ellipsis;nwhite-space: nowrap;n

但是,有時需要提前知道元素的所佔的實際寬度,並且據此分配容器寬度,這個時候我們需要詳細知道這個元素佔據多寬,這個時候我首先想,直接data.length * fontWidth 這樣不就完了么,簡單方便。

但實際上,有的時候我們僅僅通過這樣沒辦法得出有效的結論。比如說:

由於我們現在採用utf8編碼,上面的兩種字元雖然都佔據一個長度,但是實際空間寬度肯定是不同的。

於是我又想出了根據編碼來確定寬度:一個中文字佔兩個寬度,一個英文或者數字佔據一個寬度:

function sizeof(str, charset){n let total = 0,charCode,i,len;n charset = charset ? charset.toLowerCase() : ;n if(charset === utf-16 || charset === utf16){n for(i = 0, len = str.length; i < len; i++){n charCode = str.charCodeAt(i);n if(charCode <= 0xffff){n total += 1;n }else{n total += 2;n }n }n }else{n for(i = 0, len = str.length; i < len; i++){n charCode = str.charCodeAt(i);n if(charCode <= 0x007f) {n total += 1;n }else if(charCode <= 0x07ff){n total += 1;n }else if(charCode <= 0xffff){n total += 2;n }else{n total += 2;n }n }n }n return total;n}n//這段代碼靈感來自Alloyteam,其實有另外的應用場景n

通過以上代碼算出size,然後再乘以每一個字的寬度,這樣比上面更加精確了。

然而不久...我又發現了問題:

以上兩個英文字元,雖然都是one size的,但是寬度卻仍然不相同。

於是,我又創造了以下方法:

function spacesizeof(str,config){nn let testSpan = document.createElement(span);n testSpan.style.visibility = 0;n testSpan.style.margin = 0;n testSpan.style.padding= 0;n testSpan.style.fontSize = config && config.fontSize || 28px;n testSpan.innerHTML=str;nn if(config && typeof(config) === object) {n let allConfigs = Object.keys(config);n for (let item of allConfigs) {n testSpan.style[item] = allConfigs[item];n }n }nn document.body.appendChild(testSpan);n let width = testSpan.offsetWidth;n document.body.removeChild(testSpan);n return width;n}n

這個方法通過創建一個虛擬span的方法,來真實地獲取所佔據空間的大小,並且可以通過設置css樣式影響,來獲取實際中的所佔寬度。

至此,我們可以通過js來快速而準確地獲取一個元素實際佔據的寬度。

推薦閱讀:

前端要切圖嗎?切圖是錯誤的流程、是浪費生命嗎?
我還是想談談JS裡面的閉包
請問學習前端最有效的辦法是什麼?
是什麼讓你在前端行業堅持下去,或者什麼讓你發現你是真的熱愛它?
我的狀態管理方案(仿 redux )

TAG:CSS | 前端开发 | 页面设计 |