如何用OOJS实现手风琴组件?解决点击单一项批量展开收起问题
解决单个元素展开/收起独立触发的问题
我来帮你搞定这个问题!你现在遇到的核心问题是所有.myDiv元素共享了同一个Height实例,而且点击事件绑定在了整个body上,导致触发时会同时操作所有元素。咱们一步步修正:
问题根源分析
- 你通过
var myDiv = $('.myDiv')选中了所有目标元素,并把这个集合传给了Height构造函数,所以this.element是一个包含所有.myDiv的jQuery集合,调用expand()/collapse()时会批量修改所有元素的样式。 - 点击事件绑定在
body上,每次点击都会触发同一个实例的toggle()方法,自然所有元素会一起展开或收起。
修正后的代码实现
重构Height类(确保单元素管理)
首先调整类的实现,让它专注处理单个DOM元素,同时规范getter/setter的命名:
class Height { constructor(el) { this.element = el; } // 获取当前元素的状态 get state(){ return $(this.element).data('state'); // 改用jQuery.data()管理状态更高效 } // 设置元素状态 set state(newState){ $(this.element).data('state', newState); } expand() { $(this.element).css('height', '200px'); this.state = 'open'; } collapse() { $(this.element).css('height', '50px'); this.state = 'close'; } toggle(){ if(this.state === 'open') { this.collapse(); } else { this.expand(); } } }
为每个元素创建独立实例并绑定点击事件
接下来遍历每个.myDiv,给每个元素单独创建Height实例,并把点击事件绑定到自身:
// 遍历所有.myDiv元素,逐个初始化并绑定事件 $('.myDiv').each(function() { // 为当前元素创建专属的Height实例 const itemInstance = new Height(this); // 点击当前元素时,触发自己的toggle方法 $(this).on('click', function() { itemInstance.toggle(); }); });
关键修改点说明
- 单个实例对应单个元素:通过
.each()遍历,确保每个.myDiv都有自己的Height实例,操作时只会影响当前元素。 - 事件绑定到元素自身:不再监听
body的点击,而是直接绑定到每个.myDiv上,精准触发目标元素的状态切换。 - 改用
jQuery.data()管理状态:相比直接操作data-state属性,data()方法会把状态存储在内存中,性能更好,也更符合jQuery的最佳实践。
这样修改后,点击任意一个.myDiv时,就只会展开或收起被点击的那一项啦!
内容的提问来源于stack exchange,提问作者WoodenChops
相关产品推荐
相关产品推荐

