解决jQuery/Javascript中Read More/Read Less点击全展开问题
多容器Read More/Read Less功能修复方案
问题描述
开发Read More/Read Less功能时,存在多个文本容器的场景下,点击任意一个按钮会导致所有容器同时展开/收起,需求是仅操作当前点击对应的容器。
原代码
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <main> <p class="slide-read-more">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum </p> <div class="slide-read-more-button read-more-button">Read More</div> <div class="slide-read-more-button">Read Less</div> <p class="slide-read-more">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum </p> <div class="slide-read-more-button read-more-button">Read More</div> <div class="slide-read-more-button">Read Less</div> </main>
CSS
main{ max-width: 600px; width: 100%; margin: 0 auto; } .slide-read-more{ overflow:hidden; } .slide-read-more-button{ cursor: pointer; text-align: right; margin-top: 8px; color: #488A8A; display: none; }
JavaScript
$(document).ready(function(){ // resize the slide-read-more Div var box = $(".slide-read-more"); var minimumHeight = 200; // max height in pixels var initialHeight = box.innerHeight(); // reduce the text if it's longer than 200px if (initialHeight > minimumHeight) { box.css('height', minimumHeight); $(".read-more-button").show(); } SliderReadMore(); function SliderReadMore() { $(".slide-read-more-button").on('click', function () { // get current height var currentHeight = box.innerHeight(); // get height with auto applied var autoHeight = box.css('height', 'auto').innerHeight(); // reset height and revert to original if current and auto are equal var newHeight = (currentHeight | 0) === (autoHeight | 0) ? minimumHeight : autoHeight; box.css('height', currentHeight).animate({ height: (newHeight) }) $('html, body').animate({ scrollTop: box.offset().top }); $(".slide-read-more-button").toggle(); }); } });
问题根源
原代码中使用全局变量box选中了所有.slide-read-more元素,初始化时统一设置所有容器高度,点击事件中也操作所有容器,导致点击单个按钮时所有容器同时变化。
修复方案
修改JS代码,针对每个容器单独处理,点击事件中仅操作当前按钮对应的容器:
修改后的JavaScript
$(document).ready(function(){ const minimumHeight = 200; // 折叠状态高度 // 遍历每个文本容器,单独初始化 $(".slide-read-more").each(function() { const $box = $(this); const initialHeight = $box.innerHeight(); if (initialHeight > minimumHeight) { $box.css('height', minimumHeight); // 显示当前容器对应的Read More按钮 $box.nextAll(".slide-read-more-button").first().show(); } }); // 绑定点击事件 $(".slide-read-more-button").on('click', function () { const $btn = $(this); // 找到当前按钮对应的文本容器 const $box = $btn.prevAll(".slide-read-more").first(); const currentHeight = $box.innerHeight(); // 获取容器自动高度 const autoHeight = $box.css('height', 'auto').innerHeight(); $box.css('height', currentHeight); // 计算目标高度 const newHeight = (currentHeight | 0) === (autoHeight | 0) ? minimumHeight : autoHeight; // 仅动画当前容器 $box.animate({ height: newHeight }); // 滚动到当前容器顶部 $('html, body').animate({ scrollTop: $box.offset().top }); // 仅切换当前按钮组的显示状态 $btn.siblings(".slide-read-more-button").addBack().toggle(); }); });
关键改动说明
- 初始化阶段:使用
.each()遍历每个文本容器,单独判断高度并设置,同时仅显示当前容器对应的Read More按钮,避免全局操作。 - 点击事件处理:
- 通过
$(this)获取当前点击的按钮,再通过prevAll(".slide-read-more").first()找到对应的文本容器,确保仅操作当前容器。 - 使用
siblings().addBack().toggle()仅切换当前按钮组(Read More/Read Less)的显示状态,而非所有按钮。
- 通过
- 移除全局变量:不再使用全局的
box变量,改为针对每个容器的局部变量,避免批量操作所有元素。
内容的提问来源于stack exchange,提问作者radman
相关产品推荐
相关产品推荐

