

新闻资讯
技术学院本文介绍在多卡片场景下,如何通过状态标记机制确保每个卡片的“点赞”或“踩”按钮仅响应一次点击,避免重复计数与样式误改,同时不影响其他卡片的独立交互。
在实际开发中,尤其是基于循环渲染的卡片列表(如资讯流、商品卡片),常需为每张卡片提供“点赞”和“踩”功能。原始代码存在两个关键问题:
✅ 正确解法不是“移除事件监听器”,而是从业务逻辑层阻止重复操作——即为每个 contentid 维护独立的已操作状态,并在函数入口做拦截。
使用一个 Set(或数组)记录已触发过 Like/Dislike 的 contentid,并在每次调用前校验:
// 使用 Set 实现 O(1) 查找,更高效且自动去重
const operatedIds = new Set();
function contentLike_Dislike(contentid, islike) {
const key = `${contentid}-${islike}`; // 区分 like/dislike 操作(同一卡片可单独点赞/踩)
if (operatedIds.has(key)) {
console.warn(`Operation [${key}] already performed. Ignored.`);
return;
}
// 执行业务逻辑
if (islike === "true") {
const $likeP = $(`#p-like-${contentid}`);
const count = parseInt($likeP.text()) || 0;
$likeP.text(count + 1).removeClass("d-none");
// 仅更新当前卡片内的图标(使用 closest 定位父卡片,再 find 子元素)
$likeP.closest('.d-flex').find('.fa-thumbs-up')
.removeClass('far').addClass('fa');
} else {
const $dislikeP = $(`#p-dislike-${contentid}`);
const count = parseInt($dislikeP.text()) || 0;
$dislikeP.text(count + 1).removeClass("d-none");
$dislikeP.closest('.d-flex').find('.fa-thumbs-down')
.removeClass('far').addClass('fa');
}
// 标记该操作已完成
operatedIds.add(key);
}
jQuery 事件堆积风险; 在首次点击后可见(原示例中初始为 d-none)。
此方案轻量、可靠、无副作用,完美适配遗留代码改造场景,是多实例组件防重复交互的经典实践。