You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何清理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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 04:07:00