css实现

在我们平时的业务开发中经常会用到文案超出只有收起,点击在展示全部文案;通常的使用时使用css来实现

display: -webkit-box;-webkit-box-orient: vertical;-webkit-line-clamp: 3;overflow: hidden;

效果如下:

使用css实现时只能做多行的省略,也没法根据文字去添加定制化的按钮去实现展开收起的功能,这个只是适合特定要求不是很高的场合下使用。

字符串截取

另一种方法是使用字符串截取的方案

_renderContent = item => {    const { content, id } = item;    if (content.length > 69) {        return (            <div>                <div ref={id} className="content">                    {content.slice(0, 69)}                </div>                <div                    className="content-btn"                    ref={id + 'btn'}                    onClick={() => {                        this.handleContent(item);                    }}>                    全文                </div>            </div>        );    } else {        return <div className="content">{content}</div>;    }};

展示效果:

弊端:

数字、中文字符和引文字符的宽度是不一样的,在使用字符串截取是很容易出现如上的偏差,并且每个手机的分辨率不一样,字符渲染的宽度像素也是不同的,这样也会导致误差;所以字符串截取也不是一种很好的方案。

最终实现方案

话不多说直接上代码:content组件

js代码:

import React from 'react';import cs from 'classnames';import './style.scss';export default class TextContainer extends React.Component {    constructor(props) {        super(props);        this.state = {            content: props.content,            showAll: false,            btnText: '全文',            needHidden: false //  文字超出4行 需要隐藏        };    }    /**     * @description: 处理content文案的点击展开收起     * @return: null     */    handleContent = e => {        e.stopPropagation();        let { showAll } = this.state;        this.setState({            showAll: !showAll        });    };    // 判断文本超出行数    isElementCollision = (ele, rowCount = 4, cssStyles, removeChild) => {        if (!ele) {            return false;        }        const clonedNode = ele.cloneNode(true);        // 给clone的dom增加样式        clonedNode.style.overflow = 'visible';        clonedNode.style.display = 'inline-block';        clonedNode.style.width = 'auto';        clonedNode.style.whiteSpace = 'nowrap';        clonedNode.style.visibility = 'hidden';        // 将传入的css字体样式赋值        if (cssStyles) {            Object.keys(cssStyles).forEach(item => {                clonedNode.style[item] = cssStyles[item];            });        }        // 给clone的dom增加id属性        let _time = new Date().getTime();        const containerID = 'collision_node_id_' + _time;        clonedNode.setAttribute('id', containerID);        let tmpNode = document.getElementById(containerID);        let newNode = clonedNode;        if (tmpNode) {            document.body.replaceChild(clonedNode, tmpNode);        } else {            newNode = document.body.appendChild(clonedNode);        }        // 新增的dom宽度与原dom的宽度*限制行数做对比        const differ = newNode.offsetWidth - ele.offsetWidth * rowCount + 40;        // console.log(differ, 'differ');        if (removeChild) {            document.body.removeChild(newNode);        }        return differ > 0;    };    componentDidMount = () => {        const cssStyles = { fontSize: '0.9375rem', fontWeight: '400', lineHeight: '1.5625rem' };        // console.log(this.isElementCollision(this.refs['content'], 4, cssStyles, true));        let needHidden = this.isElementCollision(this.refs['content'], 4, cssStyles, true);        this.setState({            needHidden        });    };    render() {        let { content, needHidden, showAll } = this.state;        let { headerText } = this.props;        return (            <div>                <div                    ref={'content'}                    className={cs('content', { 'hidden-text': !showAll && needHidden })}>                    {headerText ? headerText() : null}                    {content}                </div>                {needHidden && (                    <div                        className="content-btn"                        onClick={e => {                            this.handleContent(e);                        }}>                        {!showAll ? '全文' : '收起'}                    </div>                )}            </div>        );    }}

css代码:

$baseFontSize:32px !default;// pixels to rems@function pxToRem($px) {    @return $px / $baseFontSize * 1rem;}.content {    font-size: pxToRem(30px);    font-family: PingFangSC-Regular, PingFang SC;    font-weight: 400;    color: rgba(0, 0, 0, 1);    line-height: pxToRem(50px);}.hidden-text {    display: -webkit-box;    -webkit-line-clamp: 3;    /*! autoprefixer: off */    -webkit-box-orient: vertical;    /* autoprefixer: on */    overflow: hidden;}.content-btn {    font-size: pxToRem(28px);    font-family: PingFangSC-Regular, PingFang SC;    font-weight: 600;    color: rgba(162, 116, 56, 1);    line-height: pxToRem(48px);    margin-top: pxToRem(10px);}

引用:

import TextContainer from '@/textContainer';_renderContent = item => {    const { content, id } = item;    return <TextContainer content={content} />;};

效果:

总结

以上是本人在平时开发中使用的方式,希望对大家有所帮助,如果老铁们有更好的方案可留言展示一下。