如何实现支持自定义截断长度及多元素的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
相关产品推荐
相关产品推荐

