You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现可拖拽且不溢出屏幕的彩色div,支持随机定位、显隐切换功能

修正后可直接运行的完整代码
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <style type="text/css">
        /* 清除页面默认边距 */
        body {margin:0; padding:0; min-height: 100vh; overflow-x: hidden;}
        /* 左上角控制按钮样式,层级最高防止被彩色块遮挡 */
        button {position: absolute; width: 30px; height: 30px; background: #edd6bc; top:0; left:0; z-index: 999;}
        /* 彩色块公共样式:添加拖拽手势,禁止选中内容避免拖拽异常 */
        .random {position: absolute; width: 30px; height: 30px; cursor: move; user-select: none;}
    </style>
</head>
<body>
    <button onclick="showhide()" value="Zeige Features" id="button"></button>
    <!-- 彩色div配置和你原有代码保持一致 -->
    <div style="display: none; background: #6d97b4;" class="random" ></div>
    <div style="display: none; background: #c9656f;" class="random" ></div>
    <div style="display: none; background: #f1eb40;" class="random" ></div>
    <div style="display: none; background: #00825c;" class="random" ></div>
    <div style="display: none; background: #009ce0;" class="random" ></div>
    <div style="display: none; background: #cee4a6;" class="random" ></div>

<script type="text/javascript">
const btn = document.querySelector("button");
const boxes = document.querySelectorAll(".random");
// 彩色块固定宽高,统一配置方便后续修改
const BOX_SIZE = 30;

// 按钮点击生成随机位置逻辑
btn.addEventListener("click", () => {
    // 每次点击重新获取当前视口宽高,适配窗口缩放场景
    const viewportHeight = document.documentElement.clientHeight;
    const viewportWidth = document.documentElement.clientWidth;
    Array.from(boxes).forEach(box => {
        // 随机顶部坐标:最大值=视口高度-块高度,保证底部不会超出屏幕
        const randomTop = Math.floor(Math.random() * (viewportHeight - BOX_SIZE));
        // 随机左侧坐标:最大值=视口宽度-块宽度,保证右侧不会超出屏幕
        const randomLeft = Math.floor(Math.random() * (viewportWidth - BOX_SIZE));
        box.style.top = randomTop + "px";
        box.style.left = randomLeft + "px";
    })
});

// 切换显示隐藏功能,和原有逻辑保持一致
function showhide() {
  const x = document.querySelectorAll(".random");
  for (let i = 0; i < x.length; i++) {
    x[i].style.display = x[i].style.display === "block" ? "none" : "block";
  }
}

// ========== 新增拖拽功能 ==========
boxes.forEach(box => {
    // 鼠标按下时触发拖拽
    box.addEventListener('mousedown', function(e) {
        // 记录鼠标按下位置和块左上角的偏移量,保证拖拽点和鼠标位置贴合
        const offsetX = e.clientX - box.getBoundingClientRect().left;
        const offsetY = e.clientY - box.getBoundingClientRect().top;

        // 鼠标移动时更新块位置
        function moveBox(e) {
            // 计算块新的坐标
            let newLeft = e.clientX - offsetX;
            let newTop = e.clientY - offsetY;
            const viewportHeight = document.documentElement.clientHeight;
            const viewportWidth = document.documentElement.clientWidth;

            // 边界校验,超出边界就重置为边界值
            newLeft = Math.max(0, Math.min(newLeft, viewportWidth - BOX_SIZE));
            newTop = Math.max(0, Math.min(newTop, viewportHeight - BOX_SIZE));

            // 赋值新位置
            box.style.left = newLeft + 'px';
            box.style.top = newTop + 'px';
        }

        // 鼠标松开结束拖拽
        function stopMove() {
            document.removeEventListener('mousemove', moveBox);
            document.removeEventListener('mouseup', stopMove);
        }

        // 事件绑定到document上,保证鼠标移出块范围也能正常拖拽
        document.addEventListener('mousemove', moveBox);
        document.addEventListener('mouseup', stopMove);
        e.preventDefault();
    })
})
</script>
</body>
</html>

验证说明

直接复制代码保存为本地html文件即可打开使用:

  • 点击左上角按钮可切换彩色块显示/隐藏,随机生成的位置不会超出屏幕
  • 按住任意彩色块可自由拖拽,拖拽全程不会超出屏幕边界

内容的提问来源于stack exchange,提问作者jieun kim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.13 06:36:04