jQuery通过filter筛选元素后如何对匹配结果执行多项操作?
最优实现方案
你最初写的filter判断方案已经非常接近正确写法,比你最终用的全量遍历scrollItems的写法性能更好,因为ID选择器匹配是低耗时操作,不需要遍历整个元素集合,只需要修正两个细节问题即可:
- jQuery对象的长度是
.length属性,不是.length()方法,调用.length()会直接报错 matched.index()获取的是元素在文档同级节点中的索引,不是它在你预定义的scrollItems集合中的索引,直接用会导致取错对应位置的属性
修正后的精简写法
const matched = scrollItems.filter('#' + curTopicId) // 长度非0即真,不用写 !=0 判断 if (matched.length) { matched.addClass("stick") // 用$.inArray直接获取元素在scrollItems中的索引 const idx = $.inArray(matched[0], scrollItems) // 给DOM元素加自定义属性 scrollItems[idx].somevar = someval // 直接用这个索引操作你自定义的topic_times数组 topic_times[idx].startTime = Date.now() / 1000 | 0 cur_idx = idx }
如果你想要接近你设想的链式调用写法,可以直接对filter返回的结果调用each方法,因为ID是唯一的,匹配结果只会有一个,不会有额外性能损耗:
scrollItems.filter('#' + curTopicId).each(function(_, el) { const idx = $.inArray(el, scrollItems) $(el).addClass('stick') el.somevar = someval topic_times[idx].startTime = Date.now() / 1000 | 0 cur_idx = idx })
额外优化提示
如果只是需要给DOM元素绑定自定义数据,不需要额外维护topic_times数组的话,更推荐用jQuery内置的.data()方法,不会污染DOM原生属性,也不需要额外记录索引对应关系:
// 存数据 matched.data('startTime', Date.now() / 1000 | 0) // 后续取数据 const startTime = scrollItems.eq(idx).data('startTime')
内容的提问来源于stack exchange,提问作者Brian
相关产品推荐
相关产品推荐

