You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现支持自定义截断长度及多元素的JS readMore类?

改进ReadMore类:支持自定义截断长度与多元素适配

针对你提出的需求,下面是修改后的ReadMore类实现,解决了固定配置和单元素限制的问题:

class ReadMore {
  // 构造函数接收自定义配置,设置默认参数兜底
  constructor(options = {}) {
    this.config = {
      containerSelector: '.readmore-container', // 每个折叠块的容器选择器
      contentSelector: '.readmore__content',     // 容器内的内容元素选择器
      toggleSelector: '.readmore__toggle',       // 容器内的切换按钮选择器
      truncateLength: 300,                       // 默认文本截断长度
      showMoreText: 'Show more',                 // 默认"展开"按钮文本
      showLessText: 'Show less'                  // 默认"收起"按钮文本
    };
    // 合并用户自定义配置与默认配置
    Object.assign(this.config, options);
    // 用WeakMap存储每个内容元素的原始HTML,避免内存泄漏
    this.originalContents = new WeakMap();
  }

  initiate() {
    this.setNodes();
    this.initTruncation();
    this.addEventListeners();
  }

  setNodes() {
    // 获取页面中所有折叠容器
    this.containers = document.querySelectorAll(this.config.containerSelector);
  }

  initTruncation() {
    this.containers.forEach(container => {
      const content = container.querySelector(this.config.contentSelector);
      const toggleBtn = container.querySelector(this.config.toggleSelector);
      if (!content || !toggleBtn) return;

      // 保存当前内容元素的原始HTML
      this.originalContents.set(content, content.innerHTML);
      // 初始化为截断状态
      content.innerHTML = `${this.originalContents.get(content).substring(0, this.config.truncateLength)}...`;
      toggleBtn.setAttribute('aria-checked', 'true');
      toggleBtn.textContent = this.config.showMoreText;
    });
  }

  addEventListeners() {
    this.containers.forEach(container => {
      const toggleBtn = container.querySelector(this.config.toggleSelector);
      const content = container.querySelector(this.config.contentSelector);
      if (!toggleBtn || !content) return;

      // 绑定点击事件,通过箭头函数确保this指向类实例
      toggleBtn.addEventListener('click', (event) => this.handleClick(event, content));
    });
  }

  handleClick(event, content) {
    const toggleBtn = event.currentTarget;
    const isTruncated = toggleBtn.getAttribute('aria-checked') === 'true';

    if (isTruncated) {
      // 展开:显示完整内容
      content.innerHTML = this.originalContents.get(content);
      toggleBtn.setAttribute('aria-checked', 'false');
      toggleBtn.textContent = this.config.showLessText;
    } else {
      // 收起:截断内容
      content.innerHTML = `${this.originalContents.get(content).substring(0, this.config.truncateLength)}...`;
      toggleBtn.setAttribute('aria-checked', 'true');
      toggleBtn.textContent = this.config.showMoreText;
    }
  }
}

// 示例1:使用默认配置,适配所有.readmore-container容器
// new ReadMore().initiate();

// 示例2:自定义配置
new ReadMore({
  truncateLength: 200, // 自定义截断长度为200字符
  showMoreText: '查看更多',
  showLessText: '收起'
}).initiate();

关键改动说明

  • 自定义配置支持:构造函数接收options参数,可覆盖默认的截断长度、按钮文本、元素选择器等
  • 多元素适配:通过容器选择器批量获取所有折叠块,每个容器独立处理状态,互不干扰
  • 修正截断逻辑:原代码中substring(200, end)的写法错误,改为从第0位开始截取到指定长度substring(0, truncateLength)
  • 安全存储原始内容:用WeakMap存储每个内容元素的原始HTML,当元素从DOM移除时会自动回收内存
  • 清晰的事件绑定:每个按钮单独绑定点击事件,通过参数传递对应内容元素,确保状态切换准确

配套HTML结构示例

要适配多元素,需要给每个折叠块套上容器:

<div class="readmore-container">
  <div class="readmore__content">这里是需要折叠的长文本内容,长度超过设定的截断值时会自动被截断...</div>
  <button class="readmore__toggle" aria-checked="true">Show more</button>
</div>

<div class="readmore-container">
  <div class="readmore__content">这是另一个需要折叠的文本内容,每个容器的状态独立维护...</div>
  <button class="readmore__toggle" aria-checked="true">Show more</button>
</div>

内容的提问来源于stack exchange,提问作者Ahmed Emad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 08:48:21