VUE2项目中CSS获取变量动态设置元素的高度,用伪元素展示多行超出省略并在行末带有“展开”按钮

UI需求:文字超过限定的行数,可点击“展开”“收起”,隐藏和显示文字内容。具体要求如下:

1.文章内容字数过多时默认展示三行,在第三行的末尾防止“展开”按钮,当点击展开时显示所有文章内容;
2.被展开的内容末尾有“收起”按钮,和最后一行内容在同一行中,如果最后一行内容过多,“收起”按钮可换到下一行,居右展示。
在这里插入图片描述
在这里插入图片描述

方法如下:

通过“用伪元素展示多行内容超出省略并在行末可点击展开”解决了此问题,直接上代码。

此方法处理起来虽然麻烦,但本人认为效果是最好的!

main.js

function refreshRem() {
    const designSize = 1440; // 设计图尺寸
    const html = document.documentElement;
    let wW = html.clientWidth; // 窗口宽度
    if (wW > 1440) {
      wW = 1440;
    }
    let rem = (wW * 14) / designSize;
    if (wW <= 800) {
      rem = (wW * 14) / 375;
    }
    document.documentElement.style.fontSize = rem + "px";

    // getComputedStyle能获取被系统放大后的字体
    let computedFontSize = window.getComputedStyle(document.getElementsByTagName("html")[0])['font-size'].replace(/px/gi, '');
    // 被放大的字体倍数
    let multiple = (Math.floor(computedFontSize / rem * 1000)/1000).toFixed(3)
    // 将浏览器的字体缩放比例存到window下
    window.multiple = multiple
}

(function (win) {
  let tid;
  win.addEventListener(
    "resize",
    function () {
      clearTimeout(tid);
      tid = setTimeout(refreshRem, 300);
    },
    false
  );
  win.addEventListener(
    "pageshow",
    function (e) {
      if (e.persisted) {
        clearTimeout(tid);
        tid = setTimeout(refreshRem, 300);
      }
    },
    false
  );
  refreshRem();
})(window);

A.vue

<template>
    <div class="spread">
        <div class="top-prove">为了证明下面的内容不会对我造成影响</div>

        <div v-for="(item,index) in list">
            <div :class="item.showTotal ? 'init-content' : 'detail-content'">
                <div
                :title="item.answer"
                :id="item._id"
                :style="{
                    '--multiple': multiple,
                    '--multiple-before': multipleBefore,
                    '--multiple-after': multipleAfter
                }"
                class="title-content">
                <span class="empty-content">{{ item.answer }}</span>
                    <div v-if="item.showButton" @click="showOrHidden(index)" class="unfold">
                        {{ item.buttonType ? "展开" : "收起" }}
                    </div>
                </div>
            </div>
        </div>
        
        <div class="bottom-prove">为了证明上面的内容不会对我造成影响</div>
    </div>
</template>

<script>
export default {
    name: 'Spread',
    data() {
        return {
            multiple:  (window.multiple * 72 / 14) + "rem",        //div元素的最大高度
            multipleBefore: (window.multiple * 48 / 14) + "rem",   //div元素的before伪元素显示2行内容的高度
            multipleAfter: (window.multiple * 72 / 14) + "rem",    //div元素的after伪元素显示3行内容的高度
            list: [
                {"_id":"c4d069c1-8413-4c47-91b8-ec1dc51692dc","answer":"떠나지 마 just stay\n\n不要离开 在此停留\n\n지금 이 시간을 멈춘 채\n\n此刻时间停滞\n\n너와 함께라면 난\n\n只要能和你在一起\n\nI could die in this moment\n\nForever young\n\nForever young\n\nForever young\n\nForever young\n\n너의 눈에 비친 나의 모습이\n\n你的眼眸中倒映出我的身影\n\n늘 처음 만난 그 날만 같길\n\n总是如初见那般炙热\n\n소리 없이 타오르는 불꽃같이\n\n伴随着悄无声息燃烧的火花\n\n마지막처럼 내 입 맞추길\n\n像最后一次那般亲吻我\n\n달빛 아래 내 마음은 설레\n\n皎洁的月光下 我心动不已\n\n은하수로 춤추러 갈래 let's go\n\n让我们到银河去跳舞吧\n\n지금 let go\n\n现在 let go오늘이 가도 후회 없게\n\n又是不留遗憾的一天\n\n시간이 우리 둘을 떼어 놓을 수 없게\n\n时间无法让我们分开\n\n순간이 영원할 수 있게\n\n瞬间即永恒\n\n넌 내 마음에 불을 질러줘\n\n你在我的心上纵火吧\n\n후회 없는 젊음이 타오르게\n\n让无悔的青春燃烧\n\n지금처럼 너와 함께라면 tonight\n\n只要能像此刻这样和你在一起 今晚\n\nI could die in this moment"}
            ]
        };
    },
    mounted() {
        this.init();
    },
    methods: {
        showOrHidden(i) {
            //展开、收起
            this.$set(this.list[i], "showTotal", !this.list[i].showTotal);
            this.$set(this.list[i], "buttonType", !this.list[i].buttonType);

            // if (this.list[i]["buttonType"]) {
            //     // 如果是展开状态,记录下滚动条位置
            //     this.list[i].scrollTop = document.body.scrollTop + document.documentElement.scrollTop;

            //     this.$set(this.list[i], "buttonType", false);
            // } else {
            //     // 如果是收起状态,滚动到收起的位置
            //     document.body.scrollTop = this.list[i].scrollTop;
            //     document.documentElement.scrollTop = this.list[i].scrollTop;

            //     this.$set(this.list[i], "buttonType", true);
            // }
        },
        init() {
            //异步请求到列表list
            this.$nextTick(() => {
                for (let i = 0; i < this.list.length; i++) {
                    const item = this.list[i];
                    const id = item._id;
                    const dom = document.getElementById(id);
                    
					//判断div标签内的内容是否超过元素的最大高度,若小于最大高度则展示全部文字,大于最大高度则可“展开/收起”
                    if (dom.scrollHeight > dom.offsetHeight) {  
                        // 显示展开收起按钮
                        this.$set(this.list[i], "showButton", true);
                        this.$set(this.list[i], "buttonType", true);
                        // 不是显示所有
                        this.$set(this.list[i], "showTotal", false);
                    } else {
                        // 不显示展开收起按钮
                        this.$set(this.list[i], "showButton", false);
                        this.$set(this.list[i], "buttonType", false);
                        // 显示所有
                        this.$set(this.list[i], "showTotal", true);
                    }
                }
            });
        },
    },
};
</script>

less.js

<style lang="less" scoped rel="stylesheet/less">
@s: 14rem;
.spread {
    .top-prove, .bottom-prove {
        min-height: (72 / @s);
        background-color: #ccc;
    }
    //文字不足三行展示全部的样式
    .init-content {
        font-size: ( 14 / @s);
        height: auto;
        overflow: hidden;
        color: #2B3439;
        margin-bottom: (12 / @s);
        opacity: 0.5;
        .title-content {
            max-height: (72 / @s);
            .empty-content {
                width: 100%;
                line-height: (24 / @s);
            }
        }
        .unfold {
            cursor: pointer;
            display: block;
            z-index: 11;
            float: right;
            color: #2B3439;
            text-decoration: underline;
        }
    }
    // 文字超过三行时的样式
    .detail-content {
        font-size: ( 14 / @s);
        color: #2B3439;
        position: relative;
        overflow: hidden;
        margin-bottom: (12 / @s);
        opacity: 0.5;
        .title-content {
            // max-height: (72 / @s);
            max-height: var(--multiple);    //动态设置元素的高度
            line-height: (24 / @s);
            word-wrap: break-word;
            /*强制打散字符*/
            word-break: break-all;
            background: #ffffff;
            /*同背景色*/
            color: #ffffff;
            overflow: hidden;
            -moz-user-select:none;
            -webkit-user-select:none;
            -ms-user-select:none;
            -khtml-user-select:none;
            user-select:none;
            &:after, &:before {// 这是展开前实际显示的内容
                content: attr(title);
                position: absolute;
                left: 0;
                top: 0;
                width: 100%;
                color: #2B3439;
            }
            // 把最后一行自身的上面2行遮住
            &:before {
                display: block;
                overflow: hidden;
                z-index: 1;
                // height: (48 / @s);
                height: var(--multiple-before);      //*显示2行的高度 */
                background: #ffffff;
            }
            &:after {
                display: -webkit-box;
                -webkit-box-orient: vertical;
                overflow: hidden;
                // height: (72 / @s);
                height: var(--multiple-after);       //*显示3行的高度 */
                /*截取行数*/
                -webkit-line-clamp: 3;
                text-overflow: ellipsis;
                -webkit-box-sizing: border-box;
                box-sizing: border-box;
                /*行首缩进字符数*/
                text-indent: -(112 / @s);
                /*尾部留空字符数*/
                padding-right: (56 / @s);
            }
            .unfold {
                cursor: pointer;
                z-index: 11;
                outline: 0;
                position: absolute;
                right: 0;
                bottom: 0;
                color: #2B3439;
                text-decoration: underline;
            }
        }
    }
}
</style>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值