前端开发小技巧 - 【Vue / JS】- 实现 -查看更多 / 收起- 功能(文本太多,显示一定行数,行尾有 查看更多 按钮)

703 阅读4分钟

前言

  • 在许多网站都能看到 "查看更多",我在这里分享一下我实现该功能的思路和方法;

一、实现思路

1.1 文本较少的情况

  • 对于这种文本很多的情况,我们一般都是选择显示几行,其他的隐藏并且在最后一行显示省略号;
  • 但是这种情况无法查看详细的内容,如果我们已知并且确定总共要显示的内容不多,我们可以使用元素的alt属性进行提示;
  • 这块业务那边可能对样式不太满意,就需要我们增加一个元素,用来显示全部内容,设置相关样式再加上定位和hover实现显示隐藏;
  • 上述方式很简单,相信大家一两分钟就能搞定;

1.2 文本多的情况

1.2.1 需求

  • 有时候,文本非常多,就像一些能够发布文章的网站。他们是显示固定的行数,在最后一行的行尾有个“查看更多”按钮,点击之后就能够显示全部文本; image.png

1.2.2 基本实现及问题思考

  • 我刚开始实现的时候,是和文本元素平级增加一个div,如果全篇都是纯汉字并且没有标点符号什么的,显示的时候应该是没有什么问题的,但是这种文章是不存在,所以这种方式根本行不通;
  • 按照常规的文章,一篇文章中标点符号啊、英文字母、数字、特殊符号等等都是会出现的,这时候,就会发现,最后一行行尾的显示有问题,“查看更多”前面有时候显示的是半个字,看着就很诡异;
    image.png

1.2.3 解决问题

  • 有什么办法能够解决上述问题呢?
    • 我是后面将div的宽度增加,设置了一个渐变色(由透明渐变为纯白色并设置渐变区间),这样这个问题就解决了;
    • 如果想让“查看更多”另起一行显示,这块就不像前面那么麻烦了,我们只需判断什么时候显示“查看更多”按钮,什么时候隐藏即可;

1.3 “查看更多”按钮的显示隐藏

  • 我们可以根据scrollHeight查看整个文本(基于本例也就是.text的高度)所占据的高度(包括隐藏的);
  • 文本的line-height我们知道,就此我们可以算出整个文本显示了多少行;
  • 承载 文本的标签 和 “查看更多”的标签 的 父级(.text-content-area)的高度(根据offsetHeight可以得到)我们知道,根据行高我们可以算出这个父级能承载多少行的文本;
  • 如果 承载的文本行数 大与 或 等于 整个文本的行数,“查看更多”按钮就不用显示;
  • 如果 承载的文本行数 小于 整个文本的行数,就显示“查看更多按钮”;

二、原生JS使用

  • 代码演示(将鼠标放在右侧码上掘金的logo上可查看代码详情,阅读起来更方便):
  • 这种情况下,就是 父级承载文本的行数 === 总文本的行数,此时,查看更多按钮就显得没有意义了;
    • 具体看业务的要求吧,有时候人家强烈要求这种情况不显示的时候,我们也没办法,就只能照做了😂😂😂; image.png

三、Vue中使用

  • Vue中使用,页面结构和样式都是一样的,JS其实也是一样的😂😂😂(感觉有点废话了);
  • 我们在Vue中使用的时候,考虑的就是代码的复用性,如果这种功能很多的话,我们可以将 函数 挂载到 Vue 的 原型上 或者 使用 mixin进行全局混入 亦或者 封装成自定义指令进行使用
  • 下面就对这三种方式分别进行展示:

步骤:

  • 步骤一:首先我们可以将函数定义在 utils/index.js 中;
  • 步骤二、导入该函数并且开始挂载或混入
    • 目标文件:
      • main.js

3.1 挂载到Vue的原型上

import Vue from 'vue';
import App from './App.vue';
import isShowSeeMoreBtn from '@/src/utils';

// 挂载到 Vue 的原型上
Vue.prototype.$isShowSeeMoreBtn = isShowSeeMoreBtn;

export const vm = new Vue({
    // 其他配置项
    render: h =? h(App)
}).$mount('#app');

3.2 使用 mixin 进行全局混入

import Vue from 'vue';
import App from './App.vue';
import isShowSeeMoreBtn from '@/src/utils';

Vue.mixin({
    method: {
        isShowSeeMoreBtn
    }
})

export const vm = new Vue({
    // 其他配置项
    render: h =? h(App)
}).$mount('#app');

3.3 封装自定义指令

  • 这个过几天更新哈😁;