aabbabababaa 2024-10-10 17:11 采纳率: 60%
浏览 15

跨域生成的iframe监听点击事件?

<div class="pui-text-sm" id="single_beforeend{$article.ID}">
<script type="text/javascript">
atOptions = {
  'key': 'abc',
  'format': 'iframe',
  'height': 60,
  'width': 468,
  'params': {}
};

</script>
<script type="text/javascript" src="https://www.123.com/abc/invoke.js"></script>
</div>



<script type="text/javascript">
let Clicked{$article.ID} = 'no'; // 初始化状态

// 创建并插入 iframe
function createIframe{$article.ID}() {
  const iframe = document.createElement('iframe');
  iframe.src = 'https://www.123.com/abc/invoke.js'; // 设置 iframe 的 src
  iframe.style.display = 'none'; // 可以隐藏 iframe
  document.getElementById('single_beforeend{$article.ID}').appendChild(iframe);

    checkInvokeStatus{$article.ID}();

}

// 检查和调用状态
function checkInvokeStatus{$article.ID}() {
  fetch('https://www.123.com/abc/invoke.js', { method: 'GET', mode: 'cors' })
    .then(response => {
      if (response.ok) {
        console.log('response.ok', response.status);
        updateContent{$article.ID}();        
        const iframe = document.getElementById('#single_beforeend{$article.ID} iframe');        
        const messageHandler = (event) => {
          if (event.origin === 'https://www.123.com') { // 确保来源是可信的
            if (event.data === 'clicked') {
              const Clicked{$article.ID} = 'ok'; // 确保 Clicked 在这里被声明
              setTimeout(updateContent, 10000);
            } else {
              console.log('error clicked:', event.data);
            }
          } else {
            console.log('error origin:', event.origin);
          }
        };
        // 添加事件监听器
        window.addEventListener('message', messageHandler);
      } else {
        console.error('error invoke.js Fetch failed with status:', response.status);
        showNoAd{$article.ID}(); // 显示广告获取失败
      }
    })
    .catch(error => {
      console.error('Error fetching invoke.js:', error);
      showNoAd{$article.ID}(); // 显示广告获取失败
    });
}


// 监听文档加载
document.addEventListener('DOMContentLoaded', () => {
  createIframe{$article.ID}(); // 创建并插入 iframe
});
document.body.addEventListener('click', function(event) {
       if (event.target.matches('#single_beforeend{$article.ID} iframe')) {
           window.parent.postMessage('clicked', 'https://blog.888.net');
       }else{
      console.log('error event.target.matches:', event);
      }
   });

</script>

跨域invoke.js生成的iframe,document.body.addEventListener('click', function(event) 监听不到点击事件,当前页面的本域元素点击就能监听到点击事件,请教怎么改代码?

  • 写回答

2条回答 默认 最新

  • 一轮明月照丘壑 2024-10-10 17:12
    关注

    以下回复参考:皆我百晓生券券喵儿等免费微信小程序作答:

    跨域生成的 iframe 中的内容被视为隔离的上下文,这意味着你不能直接访问或操作 iframe 中的 DOM 元素或事件。因此,当你尝试监听 iframe 的点击事件时,由于跨域限制,可能不会触发你的监听器。但你可以通过向 iframe 发送消息来实现通信。这是一个基于消息传递的跨域通信示例:

    你可以修改代码如下:

    1. 在 iframe 中创建一个事件监听器来监听点击事件。当点击事件发生时,向父窗口发送一个消息。
    2. 在父窗口中创建一个事件监听器来接收来自 iframe 的消息。接收到消息后,你可以执行需要的操作。

    示例代码如下:

    iframe 中的代码(假设为 invoke.js)

    window.addEventListener('click', function() {
        window.parent.postMessage('iframeClicked', '*'); // 向父窗口发送消息
    });
    

    父窗口的代码

    你可以在父窗口中使用 window.addEventListener('message', callback) 来监听来自 iframe 的消息。修改你的代码如下:

    // 其他代码...
    
    // 添加消息监听器来接收来自 iframe 的消息
    window.addEventListener('message', (event) => {
      if (event.origin === 'https://www.123.com') { // 确保消息来源是可信的
        if (event.data === 'iframeClicked') {
          console.log('iframe 被点击了');
          // 执行你的逻辑操作,例如更新内容等。
        } else {
          console.log('收到未知消息:', event.data);
        }
      } else {
        console.log('消息来源不可信:', event.origin);
      }
    });
    

    请注意,你需要确保跨域消息的来源是可信任的,并且在接收消息时使用 event.origin 进行检查。此外,由于跨域限制,你可能无法直接操作 iframe 中的元素或执行某些操作,因此你可能需要通过消息传递来告知父窗口进行相应操作。

    评论

报告相同问题?

问题事件

  • 创建了问题 10月10日