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>