17370845950

使用 MultiClamp 实现文本块的折叠与展开功能

本文详细介绍了如何利用 `multiclamp` 库在网页中实现文本内容的折叠与展开功能。通过初始化 `multiclamp` 实例对文本进行多行截断,并结合其 `reload` 方法,实现点击“阅读更多”按钮或文本块本身时,动态地将折叠文本完全展开,从而提升用户体验和页面布局的灵活性。

引言

在现代网页设计中,为了优化页面布局和提高内容的可读性,常常需要对较长的文本内容进行截断显示,仅展示部分内容,并通过“阅读更多”等交互元素提供展开完整文本的功能。MultiClamp 是一个轻量级的 JavaScript 库,它能帮助开发者轻松实现文本的多行截断,并提供了灵活的 API 来动态控制文本的折叠与展开状态。本教程将指导您如何使用 MultiClamp 实现这一常见的 UI 交互。

准备工作

首先,我们需要在项目中引入 MultiClamp 库和 jQuery(如果您的项目依赖 jQuery,虽然本教程的展开部分将使用原生 JavaScript)。您可以通过 CDN 引入这些库。




    
    
    MultiClamp 文本折叠与展开
    


    
        
            
                
                    
                        

标题 1

Lorem ipsum dolor sit amet
Morbi hendrerit justo non
Mauris et ligula efficitur
Suspendisse eget nulla lobortis
Proin vel quam ornare, commodo sem
Suspendisse luctus nisi nec
Nullam volutpat mi ut metus rutrum
Fusce vehicula ipsum in mauris
Suspendisse consequat leo 阅读更多

标题 2

Lorem ipsum dolor sit amet
Morbi hendrerit justo non
Mauris et ligula efficitur
Suspendisse eget nulla lobortis 阅读更多

标题 3

Lorem ipsum dolor sit amet
Morbi hendrerit justo non
Mauris et ligula efficitur
Suspendisse eget nulla lobortis
Proin vel quam ornare, commodo sem
Suspendisse luctus nisi nec
Nullam volutpat mi ut metus rutrum
Fusce vehicula ipsum in mauris 阅读更多

接下来是基本的 CSS 样式,用于布局和美化文本块:

/* style.css */
* {
  margin: 0;
  padding: 0;
}

.container {
  max-width: 480px;
  margin: 10px auto;
  padding: 0;
  width: 100%;
}

.container:after,
.container:before {
  display: table;
  content: " ";
}

.row {
  margin-bottom: 10px;
}

.row:after {
  content: '';
  display: block;
  height: 0;
  clear: both;
}

.col {
  display: inline;
  float: left;
  margin: 0 5px;
  width: 100%;
  max-width: 150px;
  text-align: left;
}

a {
  color: #000000;
  text-decoration: none;
}

.wrap {
  position: relative;
  min-height: 100%;
  padding: 10px 10px 10px;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  background-color: yellow;
}

h3 {
  margin-bottom: 10px;
}

.btn {
  margin-top: 10px;
  background-color: #000000;
  color: #ffffff;
  display: inline-block;
  padding: 5px 10px;
  cursor: pointer; /* 添加光标指示可点击 */
}

实现文本块的初始折叠

在页面加载时,我们需要使用 MultiClamp 对所有目标文本块(例如 .descr 类)进行初始折叠。这里我们将文本限制为 3 行。

在 script.js 中添加以下代码:

// script.js
document.querySelectorAll("#info .descr").forEach(el => {
    // 初始化 MultiClamp 实例,将文本限制为 3 行
    let instance = new MultiClamp(el, {
        ellipsis: '...', // 省略号样式
        clamp: 3         // 限制行数
    });

    // 将实例存储在元素的 dataset 中,以便后续访问
    el.dataset.multiClampInstance = instance;
});

上述代码遍历了所有 .descr 元素,并为每个元素创建了一个 MultiClamp 实例,将其内容截断为 3 行。

实现点击展开功能

要实现点击展开功能,我们需要为每个文本块及其“阅读更多”按钮添加点击事件监听器。当用户点击时,我们将调用 MultiClamp 实例的 reload() 方法,并设置一个非常大的 clamp 值来模拟完全展开,同时隐藏“阅读更多”按钮。

修改 script.js,添加事件监听逻辑:

// script.js
document.querySelectorAll("#info .descr").forEach(el => {
    // 初始化 MultiClamp 实例,将文本限制为 3 行
    let instance = new MultiClamp(el, {
        ellipsis: '...', // 省略号样式
        clamp: 3         // 限制行数
    });

    // 获取包含 .descr 和 .btn 的父级链接元素
    let parentLink = el.closest('a');
    let readMoreBtn = parentLink.querySelector('.btn');

    // 为父级链接元素添加点击事件监听器
    parentLink.addEventListener('click', e => {
        // 阻止链接的默认跳转行为
        e.preventDefault();

        // 展开文本:调用 reload 方法,设置一个非常大的 clamp 值
        // 这里的 40000 只是一个足够大的数字,确保文本能完全展开
        instance.reload({ clamp: 40000 });

        // 隐藏“阅读更多”按钮
        if (readMoreBtn) {
            readMoreBtn.style.display = 'none';
        }

        // 移除事件监听器,确保只展开一次
        // 如果需要再次折叠功能,则不能使用 { once: true },需要更复杂的逻辑
    }, { once: true }); // { once: true } 选项确保事件只触发一次
});

代码解析:

  1. el.closest('a'): 找到当前 .descr 元素最近的 祖先元素,因为点击区域是整个链接。
  2. e.preventDefault(): 阻止 标签的默认跳转行为,确保点击只触发展开逻辑。
  3. instance.reload({ clamp: 40000 }): 这是实现展开的关键。MultiClamp 的 reload() 方法允许您在运行时更改其选项。通过设置一个足够大的 clamp 值(例如 40000),可以有效地让文本显示其全部内容。
  4. readMoreBtn.style.display = 'none': 展开后,通常会隐藏“阅读更多”按钮,因为它已不再需要。
  5. { once: true }: 这是一个可选的事件监听器选项,表示该事件监听器在触发一次后会自动移除。这意味着一旦文本展开,再次点击将不再触发相同的展开逻辑。如果您需要实现展开/折叠的切换功能,则不应使用此选项,而需要更复杂的逻辑来切换 clamp 值和按钮文本。

完整代码示例

将上述 HTML、CSS 和 JavaScript 片段组合在一起,您将得到一个完整的可运行示例。

index.html




    
    
    MultiClamp 文本折叠与展开
    


    
        
            
                
                    
                        

标题 1

Lorem ipsum dolor sit amet
Morbi hendrerit justo non
Mauris et ligula efficitur
Suspendisse eget nulla lobortis
Proin vel quam ornare, commodo sem
Suspendisse luctus nisi nec
Nullam volutpat mi ut metus rutrum
Fusce vehicula ipsum in mauris
Suspendisse consequat leo 阅读更多

标题 2

Lorem ipsum dolor sit amet
Morbi hendrerit justo non
Mauris et ligula efficitur
Suspendisse eget nulla lobortis 阅读更多

标题 3

Lorem ipsum dolor sit amet
Morbi hendrerit justo non
Mauris et ligula efficitur
Suspendisse eget nulla lobortis
Proin vel quam ornare, commodo sem
Suspendisse luctus nisi nec
Nullam volutpat mi ut metus rutrum
Fusce vehicula ipsum in mauris 阅读更多

标题 4

Lorem ipsum dolor sit amet
Morbi hendrerit justo non
Mauris et ligula efficitur
Suspendisse eget nulla lobortis
Proin vel quam ornare, commodo sem 阅读更多

标题 5

Lorem ipsum dolor sit amet
Morbi hendrerit justo non
Mauris et ligula efficitur
Suspendisse eget nulla lobortis
Proin vel quam ornare, commodo sem
Suspendisse luctus nisi nec
Nullam volutpat mi ut metus rutrum
Fusce vehicula ipsum in mauris 阅读更多

标题 6

Lorem ipsum dolor sit amet
Morbi hendrerit justo non
Mauris et ligula efficitur 阅读更多

style.css

/* (与上述 CSS 代码相同) */
* {
  margin: 0;
  padding: 0;
}

.container {
  max-width: 480px;
  margin: 10px auto;
  padding: 0;
  width: 100%;
}

.container:after,
.container:before {
  display: table;
  content: " ";
}

.row {
  margin-bottom: 10px;
}

.row:after {
  content: '';
  display: block;
  height: 0;
  clear: both;
}

.col {
  display: inline;
  float: left;
  margin: 0 5px;
  width: 100%;
  max-width: 150px;
  text-align: left;
}

a {
  color: #000000;
  text-decoration: none;
}

.wrap {
  position: relative;
  min-height: 100%;
  padding: 10px 10px 10px;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  background-color: yellow;
}

h3 {
  margin-bottom: 10px;
}

.btn {
  margin-top: 10px;
  background-color: #000000;
  color: #ffffff;
  display: inline-block;
  padding: 5px 10px;
  cursor: pointer;
}

script.js

document.querySelectorAll("#info .descr").forEach(el => {
    let instance = new MultiClamp(el, {
        ellipsis: '...',
        clamp: 3
    });

    let parentLink = el.closest('a');
    let readMoreBtn = parentLink.querySelector('.btn');

    parentLink.addEventListener('click', e => {
        e.preventDefault();
        instance.reload({ clamp: 40000 }); // 使用一个足够大的值来展开
        if (readMoreBtn) {
            readMoreBtn.style.display = 'none'; // 隐藏按钮
        }
    }, { once: true });
});

注意事项

  • clamp 值选择: 在展开时,clamp 值设置为 40000 只是一个经验值,确保它远大于任何可能的文本行数。理论上,只要这个值足够大,文本就会完全展开。
  • 重复折叠/展开: 如果您需要实现点击按钮在“折叠”和“展开”之间切换的功能,则不能使用 { once: true } 选项。您需要维护一个状态(例如,一个布尔变量或一个 CSS 类)来跟踪当前文本是折叠还是展开状态,并根据状态在 instance.reload({ clamp: 3 }) 和 instance.reload({ clamp: 40000 }) 之间切换,同时更新按钮的文本和可见性。
  • useOriginalText 选项: MultiClamp 的 reload 方法还支持 useOriginalText: true 选项。如果文本内容在折叠后被修改了,并且您希望在展开时恢复到最初的完整文本,这个选项会很有用。在我们的例子中,MultiClamp 内部会保留原始文本,因此通常不需要显式设置此选项。
  • 性能: 对于页面上大量的文本块,每次实例化 MultiClamp 都会消耗一定的资源。但对于常见的几十个或几百个文本块,其性能影响通常可以忽略不计。

总结

通过 MultiClamp 库,我们可以非常方便地实现网页中文本块的折叠与展开功能。通过简单的初始化配置进行多行截断,并利用其 reload() 方法结合事件监听器实现动态展开,这不仅优化了页面的视觉效果,也提升了用户体验。这种模式在新闻列表、博客摘要、商品描述等场景中非常实用。