html
复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Div Swipe 示例</title>
<style>
* {
box-sizing: border-box;
}
html,
body {
padding: 0;
margin: 0;
height: 100%;
font-family: "Segoe UI", "PingFang SC", sans-serif;
background: #f6f8fb;
}
.wrapper {
position: relative;
width: min(95vw, 1200px);
height: min(80vh, 700px);
margin: 30px auto 20px;
border-radius: 12px;
overflow: hidden;
box-shadow: 0 8px 25px rgba(15, 23, 42, 0.18);
}
.panel {
position: absolute;
inset: 0;
display: grid;
place-items: center;
color: #fff;
font-size: 32px;
font-weight: 600;
text-shadow: 0 2px 8px rgba(0, 0, 0, 0.35);
}
.panel.panel-left {
background: linear-gradient(135deg, #43cea2 0%, #185a9d 100%);
}
.panel.panel-right {
background: linear-gradient(135deg, #ff512f 0%, #dd2476 100%);
clip-path: inset(0 0 0 50%);
}
.panel iframe {
width: 100%;
height: 100%;
border: none;
}
.handle {
position: absolute;
top: 0;
bottom: 0;
width: 4px;
background: #fff;
border-radius: 4px;
box-shadow: 0 0 8px rgba(0, 0, 0, 0.4);
cursor: ew-resize;
transform: translateX(-50%);
}
.handle::before {
content: "";
position: absolute;
top: 50%;
left: 50%;
width: 36px;
height: 36px;
border-radius: 50%;
border: 3px solid #fff;
background: rgba(24, 90, 157, 0.95);
transform: translate(-50%, -50%);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.35);
}
.tip {
text-align: center;
color: #4b4d52;
font-size: 14px;
}
</style>
</head>
<body>
<div class="wrapper" id="swipeWrapper">
<div class="panel panel-left"></div>
<div class="panel panel-right" id="panelRight">After</div>
<div class="handle" id="handle"></div>
</div>
<p class="tip">在两个 div 上实现的 Swipe,对比任意内容或样式</p>
<script>
const wrapper = document.getElementById("swipeWrapper");
const handle = document.getElementById("handle");
const panelRight = document.getElementById("panelRight");
let isDragging = false;
const setPosition = (clientX) => {
const rect = wrapper.getBoundingClientRect();
const clamped = Math.min(Math.max(clientX - rect.left, 0), rect.width);
const percent = (clamped / rect.width) * 100;
panelRight.style.clipPath = `inset(0 ${100 - percent}% 0 0)`;
handle.style.left = `${percent}%`;
};
const onPointerMove = (event) => {
if (!isDragging) return;
setPosition(event.clientX ?? event.touches?.[0]?.clientX ?? 0);
};
const startDrag = (event) => {
isDragging = true;
wrapper.setPointerCapture?.(event.pointerId);
setPosition(event.clientX ?? event.touches?.[0]?.clientX ?? 0);
};
const stopDrag = (event) => {
isDragging = false;
wrapper.releasePointerCapture?.(event.pointerId);
};
handle.addEventListener("pointerdown", startDrag);
window.addEventListener("pointermove", onPointerMove);
window.addEventListener("pointerup", stopDrag);
// 初始化到中间位置
setPosition(wrapper.getBoundingClientRect().width / 2);
</script>
</body>
</html>