jQuery点击事件首次点击无响应,后续表现如双击问题求助
解决jQuery点击事件首次无响应、后续表现如双击的问题
嘿,我一眼就看出问题出在哪了——你重复绑定点击事件啦!
问题根源分析
你在Angular模板里给.faq-title加了(click)="faqBodyLoader(data.faq_id)",每次点击这个元素时,都会调用faqBodyLoader函数,而函数里又会给同一个#faqTitle{id}元素再次绑定一个jQuery的click事件:
- 第一次点击:其实只是完成了事件绑定,根本没执行
toggleClass的逻辑,所以看起来"无响应" - 后续点击:这个元素已经被绑定了N次点击事件,每次点击会触发N次
toggleClass,相当于反复切换状态,自然表现得像"双击"
两种解决方案,按需选
方案1:抛弃jQuery,用Angular原生方式处理(更推荐)
Angular本身就有响应式状态管理,完全没必要混用jQuery,代码更简洁也不容易出问题:
- 组件里定义一个对象,用来记录每个FAQ的展开状态:
expandedFaqIds: {[key: number]: boolean} = {};
- 修改模板,用Angular的属性绑定控制类名,同时把点击事件改成直接切换状态:
<span *ngFor="let data of _table" id="faqList"> <div class="faq-title d-flex align-items-center" (click)="toggleFaq(data.faq_id)"> {{data.faq_question}} <!-- 你的其他图标/内容 --> </div> <div class="faq-body" [class.hide]="!expandedFaqIds[data.faq_id]"> {{data.faq_answer}} <!-- FAQ内容 --> </div> </span>
- 实现切换逻辑的函数:
toggleFaq(id: number) { // 先关闭所有其他展开的FAQ Object.keys(this.expandedFaqIds).forEach(key => { const faqId = parseInt(key); if (faqId !== id) { this.expandedFaqIds[faqId] = false; } }); // 切换当前FAQ的状态 this.expandedFaqIds[id] = !this.expandedFaqIds[id]; }
方案2:坚持用jQuery?那要避免重复绑定
如果你一定要保留jQuery的写法,必须确保每个元素只绑定一次点击事件,有两种方式:
方式A:绑定前先解绑旧事件
修改faqBodyLoader函数,每次绑定前先移除该元素已有的click事件:
faqBodyLoader(id) { $("#faqTitle" + id) .off('click') // 先解绑之前的所有click事件 .on('click', function(e) { e.preventDefault(); const $currentBody = $("#faqBody" + id); $currentBody.toggleClass("hide"); // 关闭其他所有FAQ的内容 $("div[id^=faqBody]").not($currentBody).addClass("hide"); }); }
方式B:用事件委托一次性绑定
更优雅的做法是利用事件委托,在父元素上绑定一次事件,不用循环给每个子元素绑定:
- 模板里去掉
(click)="faqBodyLoader(data.faq_id)" - 在组件的
ngAfterViewInit生命周期里绑定事件:
ngAfterViewInit() { $("#faqList").on('click', '.faq-title', function(e) { e.preventDefault(); // 从元素ID里提取faq_id const faqId = $(this).attr('id').replace('faqTitle', ''); const $currentBody = $("#faqBody" + faqId); $currentBody.toggleClass("hide"); // 关闭其他所有FAQ $("div[id^=faqBody]").not($currentBody).addClass("hide"); }); }
内容的提问来源于stack exchange,提问作者rckycls
相关产品推荐
相关产品推荐

