如何清理iframe message监听器,仅获取当前单选按钮响应?
问题解决:单选按钮对应iframe的message监听器重复触发
问题原因
你当前的代码每次点击单选按钮且iframe未加载时,都会给window注册一个新的message事件监听器。这些监听器不会自动销毁,当iframe发送pickerResult消息时,所有已注册的监听器都会被触发,导致所有历史点击对应的$main元素都被执行处理逻辑,所以console.log会输出所有历史的$main。
解决方案
方案1:全局仅注册一次监听器(推荐)
把message监听器改为全局只注册一次,通过消息来源的event.source判断是哪个iframe发送的消息,再关联到对应的父级li元素:
// 全局注册一次message监听器,统一处理所有iframe的消息 window.addEventListener('message', function(event) { if (event.data?.message === 'pickerResult') { // 通过event.source找到对应的iframe元素,再获取父级li const $iframe = $(event.source.frameElement); const $main = $iframe.closest('li'); if ($main.length) { $main.find('.iframe-wrap').hide(); $main.find('.zip-code-select-text').text(event.data.point.address); $main.find('.zip-code-select input:hidden').val(event.data.point.zip); $main.find('.zip-code-select').show(); } } }); // 处理单选按钮点击逻辑,仅负责加载iframe $('.transfer-item').on('click', function() { const $main = $(this).closest('li'); const $iframe = $main.find('iframe'); if (!$iframe.attr('src')) { $iframe.attr('src', $iframe.data('src')); } });
方案2:动态管理监听器(按需移除旧监听器)
如果需要保留点击时绑定监听器的逻辑,可以给每个li存储监听器引用,每次点击时先移除旧监听器,再添加新的,同时校验消息来源:
$('.transfer-item').each(function(key, item) { $(item).on('click', function() { const $main = $(this).closest('li'); const $iframe = $main.find('iframe'); // 移除当前li之前绑定的message监听器 const oldListener = $main.data('messageListener'); if (oldListener) { window.removeEventListener('message', oldListener); } // 仅在iframe未加载时设置src if (!$iframe.attr('src')) { $iframe.attr('src', $iframe.data('src')); } // 创建新的监听器,仅处理当前iframe的消息 const newListener = function(event) { if (event.data?.message === 'pickerResult' && event.source === $iframe[0].contentWindow) { const point = event.data.point; $main.find('.iframe-wrap').hide(); $main.find('.zip-code-select-text').text(point.address); $main.find('.zip-code-select input:hidden').val(point.zip); $main.find('.zip-code-select').show(); } }; // 保存监听器引用到li元素上 $main.data('messageListener', newListener); window.addEventListener('message', newListener); }); });
内容的提问来源于stack exchange,提问作者tomasr
相关产品推荐
相关产品推荐

