当前位置: 首页 > news >正文

跨域场景下的Iframe事件监听

背景

在当前window窗口,对于一些浮窗组件,一般需要点击当前window下的其他位置才能够隐藏浮窗。但如果当前窗口中存在iframe区域,那么由于一些特殊的性质,无法通过常规的click点击事件监听iframe元素的点击,而通过contentDocument的形式也很难在跨域存在的情况下实现。

解决方案

window对象本身可以监听到blur方法,在点击到iframe时,会触发父级窗口的blur事件,此时可以间接监听到相当于点击到了iframe的事件。

缺陷

当然,缺陷很明显,其他方式触发了窗口的blur时,也会触发该事件,而不是点击到了iframe。但对于以上场景,是完全够用的。

代码

import { ref, onUnmounted, Ref } from 'vue';export function useIframeClick(iframeRef: Ref<HTMLIFrameElement | undefined>,handleIframeClick: () => void
) {// 监听iframe点击的状态const iframeClickDetection = ref({isSetup: false,blurTimer: null as NodeJS.Timeout | null,focusTimer: null as NodeJS.Timeout | null,});// 覆盖层相关状态const showClickOverlay = ref(false);const overlayTimer = ref<NodeJS.Timeout | null>(null);// 处理覆盖层点击const handleOverlayClick = () => {console.log('覆盖层检测到点击');handleIframeClick();// 点击后短暂隐藏覆盖层,让用户能正常与iframe交互showClickOverlay.value = false;setTimeout(() => {showClickOverlay.value = true;}, 100);};// 鼠标进入覆盖层时暂时隐藏,允许正常交互const handleOverlayMouseEnter = () => {if (overlayTimer.value) {clearTimeout(overlayTimer.value);}overlayTimer.value = setTimeout(() => {showClickOverlay.value = false;}, 500); // 500ms后隐藏};// 鼠标离开后重新显示覆盖层const handleOverlayMouseLeave = () => {if (overlayTimer.value) {clearTimeout(overlayTimer.value);}overlayTimer.value = setTimeout(() => {showClickOverlay.value = true;}, 1000); // 1s后重新显示};// 设置iframe点击检测const setupIframeClickDetection = () => {if (iframeClickDetection.value.isSetup) return;const detection = iframeClickDetection.value;// 监听window的焦点事件const handleWindowBlur = () => {// 延迟检测,确保是iframe获得了焦点detection.blurTimer = setTimeout(() => {// 检查当前活动元素是否是iframeif (document.activeElement === iframeRef.value) {handleIframeClick();}}, 0);};const handleWindowFocus = () => {// 清除blur定时器if (detection.blurTimer) {clearTimeout(detection.blurTimer);detection.blurTimer = null;}};// 监听鼠标移动事件,确保是真实的点击而不是键盘导航let mouseMovedOverIframe = false;const handleMouseMove = (e: MouseEvent) => {const iframeRect = iframeRef.value?.getBoundingClientRect();if (iframeRect) {const isOverIframe =e.clientX >= iframeRect.left &&e.clientX <= iframeRect.right &&e.clientY >= iframeRect.top &&e.clientY <= iframeRect.bottom;mouseMovedOverIframe = isOverIframe;}};// 改进的blur处理const handleWindowBlurImproved = () => {detection.blurTimer = setTimeout(() => {if (document.activeElement === iframeRef.value && mouseMovedOverIframe) {handleIframeClick();}}, 0);};window.addEventListener('blur', handleWindowBlurImproved);window.addEventListener('focus', handleWindowFocus);document.addEventListener('mousemove', handleMouseMove);detection.isSetup = true;// 清理函数onUnmounted(() => {window.removeEventListener('blur', handleWindowBlurImproved);window.removeEventListener('focus', handleWindowFocus);document.removeEventListener('mousemove', handleMouseMove);if (detection.blurTimer) {clearTimeout(detection.blurTimer);}});};return {showClickOverlay,setupIframeClickDetection,handleOverlayClick,handleOverlayMouseEnter,handleOverlayMouseLeave,};
}

http://www.lryc.cn/news/611265.html

相关文章:

  • Nature Neuroscience | 如何在大规模自动化MRI分析中规避伪影陷阱?
  • Android 开发中,HandlerThread、IntentService 和 AsyncTask区别对比
  • 性能测试终极指南:从指标到实战
  • 《传统企业如何借助数字化转型实现企业增长》
  • 机器学习通关秘籍|Day 03:决策树、随机森林与线性回归
  • 分布式微服务--Nacos持久化
  • Python-机器学习初识
  • 机器学习——集成学习(Ensemble Learning):随机森林(Random Forest),AdaBoost、Gradient Boosting,Stacking
  • 论文阅读笔记:《Curriculum Coarse-to-Fine Selection for High-IPC Dataset Distillation》
  • 2.4 组件通信
  • 高阶 RAG :技术体系串联与实际落地指南​
  • 计算机网络 第2章通信基础(竟成)
  • PYQT的QMessageBox使用示例
  • 深入理解 Ext 系列文件系统:从磁盘物理到文件系统原理
  • 注意点:如何使用conda创建虚拟环境并使用虚拟环境以及当安装相关库时,如何指定安装到那个环境里面 ---待看
  • LINUX-进程管理及基础管理
  • Java开发时出现的问题---并发与资源管理深层问题
  • OpenSpeedy绿色免费版下载,提升下载速度,网盘下载速度等游戏变速工具
  • day25 进程
  • FastAPI快速入门P2:与SpringBoot比较
  • 【数据结构初阶】--排序(三):冒泡排序,快速排序
  • add_key系统调用及示例
  • 《C++》继承完全指南:从入门到精通
  • 【Day 16】Linux-性能查看
  • 计算机基础:操作系统学习的基石
  • 分布式微服务--Nacos 集群部署
  • RabbitMQ延时队列的两种实现方式
  • 磁悬浮转子的“静音术”:深度解析无接触抑制旋转幽灵的奥秘
  • 基于华为开发者空间的Open WebUI数据分析与可视化实战
  • 【Linux系统编程】线程概念与控制