计算动态字符串宽度,多行实现展开收起

原创
2017/06/22 14:02
阅读数 1.3K

计算动态字符串宽度,多行实现展开收起

思路: 创建span元素,添加到页面隐藏,将字符串添加到span中,获取span宽度, 与父容器宽度比对,超过行数,截取字符串(可设置自定义属性,存储原始字符串)

  • 知识点

  • getComputedStyle 计算属性

  • offsetWidth 元素相对父元素的偏移宽度

  • [程序员福利广告]

    • 外卖红包群 +微信 1165763207 发送[ 外卖 ] 自动获取入群邀请
  • codepen在线效果预览

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>计算动态字符串宽带,多行实现展开收起</title>
    <style>
        * {
            padding: 0;
            margin: 0;
        }
        #box {
            width: 300px;
            margin: 0 auto;
            font-size: 14px;
            line-height: 16px;
            border: 1px solid red;
            word-break: break-all; /* 打断所有单词 */
        }
    </style>
</head>

<body>
        <div id="box"></div>
    <script>
        // 获取容器的宽度
        var box =document.querySelector('#box');
        var styles = window.getComputedStyle(box, null);
        var wd = parseInt(styles.width);
        /**
        * 计算字符占用的宽度
        * str 字符串
        * strFontSize 字符串字体大小
        * wd 文本父容器宽度
        * lineNum 超过几行隐藏
        */
        function calcStringPixelsCount(data) {
            var str = data.str;
            var strFontSize = data.strFontSize || '16px';
            var wd = data.wd || 200;
            var lineNum = data.lineNum || 2;
            // 字符串字符个数
            var stringCharsCount = str.length;
            // 字符串像素个数
            var stringPixelsCount = 0;
            // 控制截取字符串长度
            var flag = true; 
            // 截取后的字符串
            var subStr = '';
            // JS 创建HTML元素:span
            var elementPixelsLengthRuler = document.createElement("span");
            elementPixelsLengthRuler.style.fontSize = strFontSize; // 设置span的fontsize
            elementPixelsLengthRuler.style.visibility = "hidden"; // 设置span不可见
            elementPixelsLengthRuler.style.display = "inline-block";
            elementPixelsLengthRuler.style.wordBreak = "break-all !important"; // 打断单词

            // 添加span
            document.body.appendChild(elementPixelsLengthRuler);
            // 计算字符所占宽度
            for (var i = 0; i < stringCharsCount; i++) {
                // 判断字符是否为空格,如果是用&nbsp;替代,原因如下:
                // 1)span计算单个空格字符( ),其像素长度为0
                // 2)空格字符在字符串的开头或者结尾,计算时会忽略字符串
                if (str[i] === " ") {
                    elementPixelsLengthRuler.innerHTML = "&nbsp;";
                } else {
                    elementPixelsLengthRuler.innerHTML = str[i];
                }
                stringPixelsCount += elementPixelsLengthRuler.offsetWidth;
                // 截取特定长度的字符串
                if ((stringPixelsCount > lineNum * wd) && flag) {
                    flag = false;
                    subStr = str.substring(0, i);
                    console.log(subStr);
                }
            }
            console.log(stringPixelsCount);
            if (stringPixelsCount / wd > lineNum) {
                return subStr + '...';
            }
            return false;
        }
        // 此处模拟从后台动态获取不确定字数的字符串
        var t =
            '低价省钱购 http://djsqg.cn 天猫优惠券 外卖红包群 +微信 1165763207 发送[ 外卖 ] 自动获取入群邀请 农产品价格大起大落,损害的不只是生产者的利益,更会影响消费者的日常生活。因此,需进一步提高信息预警准确度,构建全产业链上各种农产品供求预警系统。并加快农业生产结构的调整,尽快改变大而不强、低端同质竞争的现状。这样才能让生产者有赚头,让消费者得实惠——';
        var t1 = calcStringPixelsCount({
            str: t,
            strFontSize: '16px',
            wd: wd,
            lineNum: 3
        });
        box.innerHTML = t1 ? '<span class="txt">' + t1 + '</span><a id="more" href="javascript:void(0);">展开</a>' : '<span class="txt">' + t + '</span>';

        var more = document.querySelector('#more');
        var txt = document.querySelector('.txt');
        more && more.addEventListener('click', function () {
            if (more.innerText === '展开') {
                txt.innerText = t;
                more.innerText = '收起';
            } else {
                txt.innerText = t1;
                more.innerText = '展开';
            }
        });
    </script>
</body>

</html>
展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部