整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          js如何實(shí)現(xiàn)當(dāng)文本內(nèi)容過長時(shí),中間顯示省略號...,兩端正常展示

          一陣做需求時(shí),有個(gè)小功能實(shí)現(xiàn)起來廢了點(diǎn)腦細(xì)胞,覺得可以記錄一下。

          產(chǎn)品的具體訴求是:用戶點(diǎn)擊按鈕進(jìn)入詳情頁面,詳情頁內(nèi)的卡片標(biāo)題內(nèi)容過長時(shí),標(biāo)題的前后兩端正常展示,中間用省略號...表示,并且鼠標(biāo)懸浮后,展示全部內(nèi)容。

          關(guān)于鼠標(biāo)懸浮展示全部內(nèi)容的代碼就不放在這里了,本文主要寫關(guān)于實(shí)現(xiàn)中間省略號...的代碼。

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

          1. 獲取標(biāo)題盒子的真實(shí)寬度, 我這里用的是clientWidth;
          2. 獲取文本內(nèi)容所占的實(shí)際寬度;
          3. 根據(jù)文字的大小計(jì)算出每個(gè)文字所占的寬度;
          4. 判斷文本內(nèi)容的實(shí)際寬度是否超出了標(biāo)題盒子的寬度;
          5. 通過文字所占的寬度累加之和與標(biāo)題盒子的寬度做對比,計(jì)算出要截取位置的索引;
          6. 同理,文本尾部的內(nèi)容需要翻轉(zhuǎn)一下,然后計(jì)算索引,截取完之后再翻轉(zhuǎn)回來;

          代碼

          html代碼

          <div class="title" id="test">近日,銀行紛紛下調(diào)大額存單利率,但銀行定期存款仍被瘋搶。銀行理財(cái)經(jīng)理表示:有意向購買定期存款要盡快,不確定利率是否會再降。</div>
          


          css代碼: 設(shè)置文本不換行,同時(shí)設(shè)置overflow:hidden讓文本溢出盒子隱藏

          .title {
              width: 640px;
              height: 40px;
              line-height: 40px;
              font-size: 14px;
              color: #00b388;
              border: 1px solid #ddd;
              overflow: hidden;
              /* text-overflow: ellipsis; */
              white-space: nowrap;
              /* box-sizing: border-box; */
              padding: 0 10px;
          }
          


          javascript代碼:

          獲取標(biāo)題盒子的寬度時(shí)要注意,如果在css樣式代碼中設(shè)置了padding, 就需要獲取標(biāo)題盒子的左右padding值。 通過getComputedStyle屬性獲取到所有的css樣式屬性對應(yīng)的值, 由于獲取的padding值都是帶具體像素單位的,比如: px,可以用parseInt特殊處理一下。

          獲取盒子的寬度的代碼,我當(dāng)時(shí)開發(fā)時(shí)是用canvas計(jì)算的,但計(jì)算的效果不太理想,后來逛社區(qū),發(fā)現(xiàn)了嘉琪coder大佬分享的文章,我這里就直接把代碼搬過來用吧, 想了解的掘友可以直接滑到文章末尾查看。

          判斷文本內(nèi)容是否超出標(biāo)題盒子

           // 標(biāo)題盒子dom
          const dom = document.getElementById('test');
          
          // 獲取dom元素的padding值
          function getPadding(el) {
              const domCss = window.getComputedStyle(el, null);
              const pl = Number.parseInt(domCss.paddingLeft, 10) || 0;
              const pr = Number.parseInt(domCss.paddingRight, 10) || 0;
              console.log('padding-left:', pl, 'padding-right:', pr);
              return {
                  left: pl,
                  right: pr
              }
          }
          // 檢測dom元素的寬度,
          function checkLength(dom) {
               // 創(chuàng)建一個(gè) Range 對象
              const range = document.createRange();
              
              // 設(shè)置選中文本的起始和結(jié)束位置
              range.setStart(dom, 0),
              range.setEnd(dom, dom.childNodes.length);
              
              // 獲取元素在文檔中的位置和大小信息,這里直接獲取的元素的寬度
              let rangeWidth = range.getBoundingClientRect().width;
              
              // 獲取的寬度一般都會有多位小數(shù)點(diǎn),判斷如果小于0.001的就直接舍掉
              const offsetWidth = rangeWidth - Math.floor(rangeWidth);
              if (offsetWidth < 0.001) {
                  rangeWidth = Math.floor(rangeWidth);
              }
              
              // 獲取元素padding值
              const { left, right } = getPadding(dom);
              const paddingWidth = left + right;
              
              // status:文本內(nèi)容是否超出標(biāo)題盒子;
              // width: 標(biāo)題盒子真實(shí)能夠容納文本內(nèi)容的寬度
              return {
                  status: paddingWidth + rangeWidth > dom.clientWidth,
                  width: dom.clientWidth - paddingWidth
              };
          }
          


          通過charCodeAt返回指定位置的字符的Unicode編碼, 返回的值對應(yīng)ASCII碼表對應(yīng)的值,0-127包含了常用的英文、數(shù)字、符號等,這些都是占一個(gè)字節(jié)長度的字符,而大于127的為占兩個(gè)字節(jié)長度的字符。

          截取和計(jì)算文本長度

          js// 計(jì)算文本長度,當(dāng)長度之和大于等于dom元素的寬度后,返回當(dāng)前文字所在的索引,截取時(shí)會用到。
          function calcTextLength(text, width) {
              let realLength = 0;
              let index = 0;
              for (let i = 0; i < text.length; i++) {
                  charCode = text.charCodeAt(i);
                  if (charCode >= 0 && charCode <= 128) {
                      realLength += 1;
                  } else {
                      realLength += 2 * 14; // 14是字體大小
                  }
                  // 判斷長度,為true時(shí)終止循環(huán),記錄索引并返回
                  if (realLength >= width) {
                      index = i;
                      break;
                  }
              }
              return index;
          }
          
          // 設(shè)置文本內(nèi)容
          function setTextContent(text) {
              const { status, width } = checkLength(dom);
              let str = '';
              if (status) {
                  // 翻轉(zhuǎn)文本
                  let reverseStr = text.split('').reverse().join('');
                  
                  // 計(jì)算左右兩邊文本要截取的字符索引
                  const leftTextIndex = calcTextLength(text, width);
                  const rightTextIndex = calcTextLength(reverseStr, width);
                  
                  // 將右側(cè)字符先截取,后翻轉(zhuǎn)
                  reverseStr = reverseStr.substring(0, rightTextIndex);
                  reverseStr = reverseStr.split('').reverse().join('');
                  
                  // 字符拼接
                  str = `${text.substring(0, leftTextIndex)}...${reverseStr}`;
              } else {
                  str = text;
              }
              dom.innerHTML = str;
          }
          


          最終實(shí)現(xiàn)的效果如下:

          上面就是此功能的所有代碼了,如果想要在本地試驗(yàn)的話,可以在本地新建一個(gè)html文件,復(fù)制上面代碼就可以了。

          下面記錄下從社區(qū)內(nèi)學(xué)到的相關(guān)知識:

          1. js判斷文字被溢出隱藏的幾種方法;
          2. JS獲取字符串長度的幾種常用方法,漢字算兩個(gè)字節(jié);

          1、 js判斷文字被溢出隱藏的幾種方法

          1. Element-plus這個(gè)UI框架中的表格組件實(shí)現(xiàn)的方案。

          通過document.createRange和document.getBoundingClientRect()這兩個(gè)方法實(shí)現(xiàn)的。也就是我上面代碼中實(shí)現(xiàn)的checkLength方法。

          2. 創(chuàng)建一個(gè)隱藏的div模擬實(shí)際寬度

          通過創(chuàng)建一個(gè)不會在頁面顯示出來的dom元素,然后把文本內(nèi)容設(shè)置進(jìn)去,真實(shí)的文本長度與標(biāo)題盒子比較寬度,判斷是否被溢出隱藏了。

          function getDomDivWidth(dom) {
              const elementWidth = dom.clientWidth;
              const tempElement = document.createElement('div');
              const style = window.getComputedStyle(dom, null)
              const { left, right } = getPadding(dom); // 這里我寫的有點(diǎn)重復(fù)了,可以優(yōu)化
              tempElement.style.cssText = `
                  position: absolute;
                  top: -9999px;
                  left: -9999px;
                  white-space: nowrap;
                  padding-left:${style.paddingLeft};
                  padding-right:${style.paddingRight};
                  font-size: ${style.fontSize};
                  font-family: ${style.fontFamily};
                  font-weight: ${style.fontWeight};
                  letter-spacing: ${style.letterSpacing};
              `;
              tempElement.textContent = dom.textContent;
              document.body.appendChild(tempElement);
              const obj = {
                  status: tempElement.clientWidth + right + left > elementWidth,
                  width: elementWidth - left - right
              }
              document.body.removeChild(tempElement);
              return obj;
          }
          


          3. 創(chuàng)建一個(gè)block元素來包裹inline元素

          這種方法是在UI框架acro design vue中實(shí)現(xiàn)的。外層套一個(gè)塊級(block)元素,內(nèi)部是一個(gè)行內(nèi)(inline)元素。給外層元素設(shè)置溢出隱藏的樣式屬性,不對內(nèi)層元素做處理,這樣內(nèi)層元素的寬度是不變的。因此,通過獲取內(nèi)層元素的寬度和外層元素的寬度作比較,就可以判斷出文本是否被溢出隱藏了。

          // html代碼
          <div class="title" id="test">
              <span class="content">近日,銀行紛紛下調(diào)大額存單利率,但銀行定期存款仍被瘋搶。銀行理財(cái)經(jīng)理表示:有意向購買定期存款要盡快,不確定利率是否會再降。</span>
          </div>
          
          // 創(chuàng)建一個(gè)block元素來包裹inline元素
          const content = document.querySelector('.content');
          function getBlockDomWidth(dom) {
              const { left, right } = getPadding(dom);
              console.log(dom.clientWidth, content.clientWidth)
              const obj = { 
                  status: dom.clientWidth < content.clientWidth + left + right,
                  width: dom.clientWidth - left - right
              }
              return obj;
          }
          


          4. 使用canvas中的measureText方法和TextMetrics對象來獲取元素的寬度

          通過Canvas 2D渲染上下文(context)可以調(diào)用measureText方法,此方法會返回TextMetrics對象,該對象的width屬性值就是字符占據(jù)的寬度,由此也能獲取到文本的真實(shí)寬度,此方法有弊端,比如說兼容性,精確度等等。

          // 獲取文本長度
          function getTextWidth(text, font = 14) {
              const canvas = document.createElement("canvas");
              const context = canvas.getContext("2d")
              context.font = font
              const metrics = context.measureText(text);
              return metrics.width
          }
          


          2、JS獲取字符串長度的幾種常用方法

          1. 通過charCodeAt判斷字符編碼

          通過charCodeAt獲取指定位置字符的Unicode編碼,返回的值對應(yīng)ASCII碼表對應(yīng)的值,0-127包含了常用的英文、數(shù)字、符號等,這些都是占一個(gè)字節(jié)長度的字符,而大于127的為占兩個(gè)字節(jié)長度的字符。

          function calcTextLength(text) {
              let realLength = 0;
              for (let i = 0; i < text.length; i++) {
                  charCode = text.charCodeAt(i);
                  if (charCode >= 0 && charCode <= 128) {
                      realLength += 1;
                  } else {
                      realLength += 2;
                  }
              }
              return realLength;
          }
          


          2. 采取將雙字節(jié)字符替換成"aa"的做法,取長度

          function getTextWidth(text) {
              return text.replace(/[^\x00-\xff]/g,"aa").length;
          };
          



          作者:娜個(gè)小部呀
          鏈接:https://juejin.cn/post/7329967013923962895

          文分享自華為云社區(qū)《JavaScript 里三個(gè)點(diǎn) ... 的用法-云社區(qū)-華為云》,作者: Jerry Wang 。

          靜止參數(shù)

          使用 rest 參數(shù),我們可以將任意數(shù)量的參數(shù)收集到一個(gè)數(shù)組中,然后用它們做我們想做的事情。引入了其余參數(shù)以減少由參數(shù)引起的樣板代碼。

          function myFunc(a, b, ...args) {
          
          console.log(a); // 22
          
          console.log(b); // 98
          
          console.log(args); // [43, 3, 26]
          
          };
          
          myFunc(22, 98, 43, 3, 26);

          在 myFunc 的最后一個(gè)以 ...為前綴的參數(shù)中,這將導(dǎo)致所有剩余的參數(shù)都放在 javascript 數(shù)組中。

          rest 參數(shù)收集所有剩余的參數(shù),因此在最后一個(gè)參數(shù)之前添加 rest 參數(shù)是沒有意義的。其余參數(shù)必須是最后一個(gè)形參。

          rest 參數(shù)可以解構(gòu)(僅限數(shù)組),這意味著它們的數(shù)據(jù)可以解包為不同的變量。

          function myFunc(...[x, y, z]) {
          
          return x * y* z;
          
          }
          
          myFunc(1) // NaN
          
          myFunc(1, 2, 3) // 6
          
          myFunc(1, 2, 3, 4) // 6 (fourth parameter is not destructured)

          點(diǎn)差運(yùn)算符

          展開運(yùn)算符用于將可迭代對象(如數(shù)組)的元素?cái)U(kuò)展到可以容納多個(gè)元素的位置。

          function myFunc(x, y, ...params) { // used rest operator here
          
          console.log(x);
          
          console.log(y);
          
          console.log(params);
          
          }
          
          var inputs = ["a", "b", "c", "d", "e", "f"];
          
          myFunc(...inputs); // used spread operator here
          
          // "a"
          
          // "b"
          
          // ["c", "d", "e", "f"]

          一直有多種組合數(shù)組的方法,但是擴(kuò)展運(yùn)算符提供了一種用于組合數(shù)組的新方法:

          const featured = ['Deep Dish', 'Pepperoni', 'Hawaiian'];
          
          const specialty = ['Meatzza', 'Spicy Mama', 'Margherita'];
          
          const pizzas = [...featured, 'veg pizza', ...specialty];
          
          console.log(pizzas); // 'Deep Dish', 'Pepperoni', 'Hawaiian', 'veg pizza', 'Meatzza', 'Spicy Mama', 'Margherita'

          使用擴(kuò)展運(yùn)算符,現(xiàn)在可以使用比 Object.assign() 更短的語法進(jìn)行淺克隆(不包括原型)或合并對象。

          var obj1 = { foo: 'bar', x: 42 };
          
          var obj2 = { foo: 'baz', y: 13 };
          
          var clonedObj = { ...obj1 };
          
          // Object { foo: "bar", x: 42 }
          
          var mergedObj = { ...obj1, ...obj2 };
          
          // Object { foo: "baz", x: 42, y: 13 }

          總結(jié)

          當(dāng)我們在代碼中看到三個(gè)點(diǎn) (...) 時(shí),它要么是 rest 參數(shù),要么是展開運(yùn)算符。

          有一個(gè)簡單的方法來區(qū)分它們:

          • 當(dāng)三個(gè)點(diǎn) (...) 位于函數(shù)參數(shù)的末尾時(shí),它是“rest 參數(shù)”并將參數(shù)列表的其余部分收集到一個(gè)數(shù)組中。
          • 當(dāng)三個(gè)點(diǎn) (...) 出現(xiàn)在函數(shù)調(diào)用或類似函數(shù)中時(shí),它被稱為“擴(kuò)展運(yùn)算符”并將數(shù)組擴(kuò)展為 list.

          點(diǎn)擊下方關(guān)注,第一時(shí)間了解華為云新鮮技術(shù)~

          華為云博客_大數(shù)據(jù)博客_AI博客_云計(jì)算博客_開發(fā)者中心-華為云

          置文字超長用省略號顯示的css代碼如下:

          width:50px;overflow:hidden; white-space:nowrap; text-overflow:ellipsis;

          但如果前面使用偽代碼設(shè)置了圖片,由于這里使用了

          overflow:hidden;

          很有可能圖片就顯示不出來了,此時(shí)解決方式可以是添加padding-left

          padding-left: 20px

          設(shè)置的左padding的寬度稍微大于偽代碼中設(shè)置的圖片的寬度


          主站蜘蛛池模板: 丝袜美腿一区二区三区| 八戒久久精品一区二区三区| 尤物精品视频一区二区三区 | 日本一区中文字幕日本一二三区视频 | 国产精品亚洲一区二区麻豆| 亚洲一区综合在线播放| 一区二区三区四区视频| 色狠狠色狠狠综合一区| 精品一区二区三区水蜜桃| 国产高清在线精品一区小说 | 国偷自产Av一区二区三区吞精| 亚洲国产专区一区| 国产吧一区在线视频| 视频在线观看一区| 亚洲综合在线成人一区| 风流老熟女一区二区三区| 蜜桃传媒视频麻豆第一区| 无码人妻精品一区二区蜜桃网站| 性色AV一区二区三区无码| 国产精品无码AV一区二区三区| 女人18毛片a级毛片一区二区| 国产在线视频一区| 免费国产在线精品一区| 午夜一区二区在线观看| 亚洲性无码一区二区三区| 综合久久一区二区三区 | 国产成人无码aa精品一区| 中文字幕在线不卡一区二区| 亚洲av无码一区二区乱子伦as| 狠狠综合久久av一区二区| 精品不卡一区二区| 无码精品尤物一区二区三区| 国产AV一区二区三区无码野战 | 国产成人免费一区二区三区| 国产福利微拍精品一区二区| 中文字幕一区日韩精品| 一区国产传媒国产精品| 韩国福利影视一区二区三区| 久久精品一区二区三区AV| 国产麻豆精品一区二区三区| 亚洲综合无码一区二区|