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

test123

<template>
<div class="container">
<!-- div(覆盖 iframe) -->
<div
ref="dragDiv"
class="drag-div"
:style="{
left: position.x + 'px',
top: position.y + 'px',
backgroundColor: isDragging ? '#ff6b6b' : 'rgba(0, 0, 0, 0.3)',
pointerEvents: isDragging ? 'auto' : 'none'
}"
>
拖拽
</div>

<!-- iframe(下层,被 div 覆盖) -->
<iframe ref="iframeRef" src="about:blank" class="iframe-content"></iframe>
</div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, nextTick } from 'vue';

const dragDiv = ref(null);
const iframeRef = ref(null);
const isDragging = ref(false);
const position = ref({ x: 0, y: 0 });
const dragOffset = ref({ x: 0, y: 0 });

// 检测鼠标是否在 iframe 的 .checkarea 区域的按钮上
const isOnIframeButton = (e) => {
const iframe = iframeRef.value;
if (!iframe) return false;

try {
// 获取 iframe 的内部文档
const iframeDoc = iframe.contentDocument || iframe.contentWindow?.document;
if (!iframeDoc) return false;

// 找到 .checkarea 区域
const checkarea = iframeDoc.querySelector('.checkarea');
if (!checkarea) return false;

// 获取 .checkarea 的边界矩形(相对于视口)
const checkareaRect = checkarea.getBoundingClientRect();

// 如果鼠标不在 .checkarea 区域内,直接返回 false
if (e.clientX < checkareaRect.left || e.clientX > checkareaRect.right ||
e.clientY < checkareaRect.top || e.clientY > checkareaRect.bottom) {
return false;
}

// 在 .checkarea 内部查找所有按钮
const buttons = checkarea.querySelectorAll('button');
for (const btn of buttons) {
const rect = btn.getBoundingClientRect();
if (e.clientX >= rect.left && e.clientX <= rect.right &&
e.clientY >= rect.top && e.clientY <= rect.bottom) {
return true;
}
}
return false;
} catch (error) {
// 跨域 iframe 会报错,此时无法检测
console.warn('无法访问 iframe 内容(可能跨域):', error);
return false;
}
};

// 检测鼠标是否在 div 上
const isOnDiv = (e) => {
const div = dragDiv.value;
if (!div) return false;
const rect = div.getBoundingClientRect();
return e.clientX >= rect.left && e.clientX <= rect.right &&
e.clientY >= rect.top && e.clientY <= rect.bottom;
};

// 全局鼠标按下
const onMouseDown = (e) => {
if (e.button !== 0) return;

if (isOnDiv(e)) {
// 如果点击在 iframe 的 .checkarea 按钮上,不启动拖拽
if (isOnIframeButton(e)) return;

const div = dragDiv.value;
const rect = div.getBoundingClientRect();
isDragging.value = true;
dragOffset.value = {
x: e.clientX - rect.left,
y: e.clientY - rect.top
};
e.preventDefault();
}
};

// 全局鼠标移动
const onMouseMove = (e) => {
if (!isDragging.value) return;

const div = dragDiv.value;
if (!div) return;

let newX = e.clientX - dragOffset.value.x;
let newY = e.clientY - dragOffset.value.y;

newX = Math.max(0, Math.min(newX, window.innerWidth - div.offsetWidth));
newY = Math.max(0, Math.min(newY, window.innerHeight - div.offsetHeight));

position.value = { x: newX, y: newY };
};

// 全局鼠标释放
const onMouseUp = () => {
if (isDragging.value) {
isDragging.value = false;
}
};

// 初始化位置
const initPosition = () => {
const div = dragDiv.value;
if (!div) return;
position.value = {
x: (window.innerWidth - div.offsetWidth) / 2,
y: (window.innerHeight - div.offsetHeight) / 2
};
};

onMounted(() => {
initPosition();
document.addEventListener('mousedown', onMouseDown);
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('mouseup', onMouseUp);
});

onUnmounted(() => {
document.removeEventListener('mousedown', onMouseDown);
document.removeEventListener('mousemove', onMouseMove);
document.removeEventListener('mouseup', onMouseUp);
});
</script>

<style scoped>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

.container {
width: 100vw;
height: 100vh;
position: relative;
background: #f0f0f0;
}

.iframe-content {
width: 100%;
height: 100%;
border: none;
z-index: 1;
position: relative;
}

.drag-div {
position: absolute;
width: 300px;
height: 200px;
background: rgba(0, 0, 0, 0.3);
backdrop-filter: blur(8px);
border-radius: 16px;
border: 2px solid rgba(255, 255, 255, 0.1);
z-index: 2;
cursor: grab;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 18px;
font-weight: 500;
user-select: none;
transition: background-color 0.2s ease;
pointer-events: none;
}

.drag-div.dragging {
cursor: grabbing;
}
</style>

http://www.jsqmd.com/news/1190017/

相关文章:

  • 微信小程序开发进入AI决胜期:Cursor已成Tencent MiniProgram认证推荐工具(仅限前500名领取《Cursor小程序开发白皮书V2.3》)
  • 2026 年更新:桃城热门的膜结构电动推拉棚销售厂家深度剖析,暴雨夜车间积水?这玩意儿一秒收回,老板直呼专业 - 企业信息推荐【官方】
  • AMAT 0190-27952-04 终端服务器
  • 不卷渗透也能高薪!2026三条差异化网安黑马赛道,新手直接抄作业
  • 043-如何设定有效的练习目标
  • C#中如何设置软件开机自启动
  • 泾川卖黄金别踩坑!三大本土合规回收门店全实测,报价透明无隐形扣费 - 福金阁黄金回收
  • TB67H480FNG与MSP432P401R电机控制方案详解
  • 紧急更新!Copilot v2.4测试生成引擎重大升级,这5个模板必须立即迁移(附兼容性检测脚本)
  • 2026东莞企业AI转型机构排名(附本地落地变现渠道) - 资讯纵览
  • VSCode 2026 新特性与 AI 智能配置指南(超详细)
  • 奇富科技正式开源ModelEvo 以自动建模能力参与行业基础建设
  • 元初混沌 6G 全域通感一体化体系架构 第一卷二阶第二十篇 移动终端跨层级快速适配机制
  • Linux内核调试利器:ftrace原理与应用详解
  • DeepSeek API成本优化:Codex工具链实现80%成本节省方案
  • 肃州旧金变现避坑指南!三大实体连锁全城覆盖,无损检测当场全款结算 - 福金阁黄金回收
  • 2026生成式引擎优化(GEO)方案选择指南:五大服务商硬核实力测评 - 资讯纵览
  • OpenViking:AI Agent上下文工程与自我进化技术解析
  • 伯爵中国售后电话腕表维修保养服务热线权威公示(2026年7月最新) - 亨得利官方服务中心
  • 044-刻意练习的时间规划
  • 【IOS逆向】麦当劳保姆级分析过程
  • 计算机系统安全实验:栈帧结构与缓冲区溢出漏洞利用
  • 避坑式网安路线!90%新人都会学错的10个顺序,看完少走一年弯路
  • 从Q250机架到妙算/NX:拆解FAST-Lab 250mm自主无人机硬件选型逻辑
  • Dify Agent模式配置必须在24小时内完成的3项合规加固(GDPR/等保2.0双标适配实录)
  • 【冷冻电镜】IMOD实战:从零构建双轴断层图(Etomo全流程解析)
  • 车型识别 车型检测数据集 suv识别 车辆计数 面包车检测
  • 北京产检、孕期就诊不方便?正规头部陪诊守嘉陪诊,专属孕期温和陪护服务 - 深鉴新闻
  • AI 检索品牌可见度提升方案:五大GEO服务商实力全景 - 资讯纵览
  • 2026界面清爽八字排盘工具怎么选:看字段层级、模块显隐和广告干扰