根据Clamps.js,添加,全文收起的操作

使用案例:
1、 单行省略

$clamp(myHeader,{clamp:1})

2、多行省略

$clamp(myHeader,{clamp:3})

3、根据有效的高度自动省略

$clamp(myparagraph,{clamp:‘auto’})

4、基于固定元素高度的省略

$clamp(myparagraph,{clamp:‘35px’})

$clamp 是 Clamp.js 中最为主要的方法,她有两个参数。第一个参数代表需要限制显示的元素,第二个参数是相关选项的JSON对象 。

选项
1、clamp(数字|字符串|’auto’)。这个选项控制何时何地去限制文本元素。第一,当选项为数字的时候,则代表应该被显示的行数。第二,你可以使用代表 CSS的值(px,em)字符串来控制元素显示的高度。最后,你可以使用’auto’字符串。’auto’将会尝试铺满有效的空白区域并且自动的限制元素使其自适应。最后一个参数应该在元素为股东高度的时候被使用。

2、useNativeClamp(Boolean) 是否使用原生的 -webkit-line-clamp 属性在 支持的浏览器中。 默认是true 。如果你使用的是 Webkit 内核的浏览器,但是在某些情况下,显示不正常。你可以把这个值设置为false,使用基于js的实现方式

3、truncationChar (String)。在HTML元素截断之后显示的字符串,默认是省略号(…)。同时支持 字符串和HTML标签。

4、 在 “truncationChar” 之前显示的 HTML 字符串。同时支持 字符串和HTML标签。

5、splitOnChars(Array) 。Determines what characters to use to chunk an element into smaller pieces. Version 0.1 of Clamp.js would always remove each individual character to check for fit. With v0.2, you now have an option to pass a list of characters it can use. For example, it you pass an array of [‘.’, ‘,’, ’ ‘] then it will first remove sentences, then remove comma-phrases, and remove words, and finally remove individual characters to try and find the correct height. This will lead to increased performance and less looping when removing larger pieces of text (such as in paragraphs). The default is set to remove sentences (periods), hypens, en-dashes, em-dashes, and finally words (spaces). Removing by character is always enabled as the last attempt no matter what is submitted in the array.

6、animate (Boolean).当设置为true的时候动态的移除多余的字符,直到合适的省略效果。

7、toggle(String) .当设置文字时, // 是否展开收起

8、hideClampText (String) .当设置文字时,点击显示收起超出部分文字

9、truncationHTML,省略文字,可以添加html

使用

            $clamp(pLists[1], {
                clamp: 5,
                toggle: true, // 是否展开收起
                useNativeClamp: false,
                //   truncationChar: '',
                truncationHTML: '展开<i class="iconfont icon-down-hollow"></i>',
                //   hideClampText: 'shou<i class="iconfont icon-zhankai"></i>',
            });
            //根据高度自适应
            $clamp(pLists[2], {
                clamp: 'auto',
            });

代码块

/*!
 * clamp.js 0.1.1
 * Copyright 2020-11-04,
 */

(function () {
    /**
     * Clamps a text node.
     * @param {HTMLElement} element. Element containing the text node to clamp.
     * @param {Object} options. Options to pass to the clamper.
     * Uncaught TypeError: Cannot read property 'webkitLineClamp' of undefined clamp.min.js:11 需要添加配置 useNativeClamp: false
     */

    function clamp(element, options) {
        options = options || {};
        options.moreText = options.moreText || false;
        options.hideClampText = options.hideClampText || '收起';

        if (options.moreText) {
            var oldText = element.innerHTML,
                hideClampText = options.hideClampText;
            var newsContainerHide = document.createElement('span');
            newsContainerHide.innerHTML = hideClampText;
            newsContainerHide.className = 'hideClampMoreText';
            newsContainerHide.onclick = function (e) {
                element.innerHTML = oldText;
                options.moreText = false;
                clamp(element, options);
            };
            element.appendChild(newsContainerHide);
            return {
                original: oldText,
                clamped: oldText,
            };
        }
        var self = this,
            win = window,
            opt = {
                clamp: options.clamp || 2,
                useNativeClamp:
                    typeof options.useNativeClamp != 'undefined'
                        ? options.useNativeClamp
                        : true,
                splitOnChars: options.splitOnChars || ['.', '-', '–', '—', ' '], //Split on sentences (periods), hypens, en-dashes, em-dashes, and words (spaces).
                animate: options.animate || false,
                truncationChar: options.truncationChar || '…',
                truncationHTML: options.truncationHTML,
                toggle: options.toggle || false,
            },
            sty = element.style,
            originalText = element.innerHTML,
            supportsNativeClamp =
                typeof element.style.webkitLineClamp != 'undefined',
            clampValue = opt.clamp,
            isCSSValue =
                clampValue.indexOf &&
                (clampValue.indexOf('px') > -1 ||
                    clampValue.indexOf('em') > -1),
            truncationHTMLContainer;

        if (opt.truncationHTML) {
            var newsContainer = document.createElement('span');
            newsContainer.innerHTML = opt.truncationHTML;
            newsContainer.className = 'clampMoreText';
            newsContainer.style.color = 'red';
            truncationHTMLContainer = document.createElement('span');
            truncationHTMLContainer.appendChild(newsContainer);
        }
        // UTILITY FUNCTIONS __________________________________________________________

        /**
         * Return the current style for an element.
         * @param {HTMLElement} elem The element to compute.
         * @param {string} prop The style property.
         * @returns {number}
         */
        function computeStyle(elem, prop) {
            if (!win.getComputedStyle) {
                win.getComputedStyle = function (el, pseudo) {
                    this.el = el;
                    this.getPropertyValue = function (prop) {
                        var re = /(\-([a-z]){1})/g;
                        if (prop == 'float') prop = 'styleFloat';
                        if (re.test(prop)) {
                            prop = prop.replace(re, function () {
                                return arguments[2].toUpperCase();
                            });
                        }
                        return el.currentStyle && el.currentStyle[prop]
                            ? el.currentStyle[prop]
                            : null;
                    };
                    return this;
                };
            }

            return win.getComputedStyle(elem, null).getPropertyValue(prop);
        }

        /**
         * Returns the maximum number of lines of text that should be rendered based
         * on the current height of the element and the line-height of the text.
         */
        function getMaxLines(height) {
            var availHeight = height || element.clientHeight,
                lineHeight = getLineHeight(element);

            return Math.max(Math.floor(availHeight / lineHeight), 0);
        }

        /**
         * Returns the maximum height a given element should have based on the line-
         * height of the text and the given clamp value.
         */
        function getMaxHeight(clmp) {
            var lineHeight = getLineHeight(element);
            return lineHeight * clmp;
        }

        /**
         * Returns the line-height of an element as an integer.
         */
        function getLineHeight(elem) {
            var lh = computeStyle(elem, 'line-height');
            if (lh == 'normal') {
                // Normal line heights vary from browser to browser. The spec recommends
                // a value between 1.0 and 1.2 of the font size. Using 1.1 to split the diff.
                lh = parseInt(computeStyle(elem, 'font-size')) * 1.2;
            }
            return parseInt(lh);
        }

        // MEAT AND POTATOES (MMMM, POTATOES...) ______________________________________
        var splitOnChars = opt.splitOnChars.slice(0),
            splitChar = splitOnChars[0],
            chunks,
            lastChunk;

        /**
         * Gets an element's last child. That may be another node or a node's contents.
         */
        function getLastChild(elem) {
            //Current element has children, need to go deeper and get last child as a text node
            if (elem.lastChild.children && elem.lastChild.children.length > 0) {
                return getLastChild(
                    Array.prototype.slice.call(elem.children).pop()
                );
            }
            //This is the absolute last child, a text node, but something's wrong with it. Remove it and keep trying
            else if (
                !elem.lastChild ||
                !elem.lastChild.nodeValue ||
                elem.lastChild.nodeValue == '' ||
                elem.lastChild.nodeValue == opt.truncationChar
            ) {
                elem.lastChild.parentNode.removeChild(elem.lastChild);
                return getLastChild(element);
            }
            //This is the last child we want, return it
            else {
                return elem.lastChild;
            }
        }

        /**
         * Removes one character at a time from the text until its width or
         * height is beneath the passed-in max param.
         */
        function truncate(target, maxHeight) {
            if (!maxHeight) {
                return;
            }

            /**
             * Resets global variables.
             */
            function reset() {
                splitOnChars = opt.splitOnChars.slice(0);
                splitChar = splitOnChars[0];
                chunks = null;
                lastChunk = null;
            }
            var nodeValue = target.nodeValue.replace(opt.truncationChar, '');

            // console.log(nodeValue);

            //Grab the next chunks
            if (!chunks) {
                //If there are more characters to try, grab the next one
                if (splitOnChars.length > 0) {
                    splitChar = splitOnChars.shift();
                }
                //No characters to chunk by. Go character-by-character
                else {
                    splitChar = '';
                }

                chunks = nodeValue.split(splitChar);
            }

            //If there are chunks left to remove, remove the last one and see if
            // the nodeValue fits.
            if (chunks.length > 1) {
                // console.log('chunks', chunks);
                lastChunk = chunks.pop();
                // console.log('lastChunk', lastChunk);
                applyEllipsis(target, chunks.join(splitChar));
            }
            //No more chunks can be removed using this character
            else {
                chunks = null;
            }
            //Insert the custom HTML before the truncation character
            if (truncationHTMLContainer) {
                if (!target.nodeValue) return;

                element.innerHTML =
                    target.nodeValue +
                    ' ' +
                    opt.truncationChar +
                    truncationHTMLContainer.innerHTML;
            }

            //Search produced valid chunks
            if (chunks) {
                //It fits
                if (element.clientHeight <= maxHeight) {
                    //There's still more characters to try splitting on, not quite done yet
                    if (splitOnChars.length >= 0 && splitChar != '') {
                        applyEllipsis(
                            target,
                            chunks.join(splitChar) + splitChar + lastChunk
                        );
                        chunks = null;
                    }
                    //Finished!
                    else {
                        return element.innerHTML;
                    }
                }
            }
            //No valid chunks produced
            else {
                //No valid chunks even when splitting by letter, time to move
                //on to the next node
                if (splitChar == '') {
                    applyEllipsis(target, '');
                    target = getLastChild(element);

                    reset();
                }
            }

            //If you get here it means still too big, let's keep truncating
            if (opt.animate) {
                setTimeout(
                    function () {
                        truncate(target, maxHeight);
                    },
                    opt.animate === true ? 10 : opt.animate
                );
            } else {
                return truncate(target, maxHeight);
            }
        }

        function applyEllipsis(elem, str) {
            elem.nodeValue = str + opt.truncationChar;
        }

        // CONSTRUCTOR ________________________________________________________________

        if (clampValue == 'auto') {
            clampValue = getMaxLines();
        } else if (isCSSValue) {
            clampValue = getMaxLines(parseInt(clampValue));
        }

        var clampedText;
        if (supportsNativeClamp && opt.useNativeClamp) {
            sty.overflow = 'hidden';
            sty.textOverflow = 'ellipsis';
            sty.webkitBoxOrient = 'vertical';
            sty.display = '-webkit-box';
            sty.webkitLineClamp = clampValue;

            if (isCSSValue) {
                sty.height = opt.clamp + 'px';
            }
        } else {
            var height = getMaxHeight(clampValue);
            if (height <= element.clientHeight) {
                clampedText = truncate(getLastChild(element), height);
            }
        }

        if (opt.toggle) {
            if (element.querySelector('.clampMoreText')) {
                element.querySelector('.clampMoreText').onclick = function (e) {
                    element.innerHTML = originalText;
                    var newoptions = JSON.parse(JSON.stringify(options));
                    newoptions.moreText = true;
                    clamp(element, newoptions);
                };
            }
        }

        return {
            original: originalText,
            clamped: clampedText,
        };
    }

    window.$clamp = clamp;
})();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值