js 简单拖动 div 示例

js简单拖动div示例

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>简单拖动示例</title>
  <style>
   .container {
      border: 1px solid #000;
      width: 200px;
      height: 200px;
      position: absolute;
    }
  </style>
</head>
<body>
  <div class="container">
    <h1 class="title">可拖动标题</h1>
  </div>

  <script>
    const container = document.querySelector(".container");
    const title = document.querySelector(".title");
    moveableDialog(container, title);
    function moveableDialog(dialog, dragEl) {
        let isDragging = false;
        let offsetX, offsetY;
        let dialogRect = dialog.getBoundingClientRect();
        const dragHandler = (e) => {
            if (e.type === 'mousedown') {
                // 开始拖动
                isDragging = true;
                document.removeEventListener('mousemove', dragHandler);
                document.removeEventListener('mouseup', dragHandler);
                document.addEventListener('mousemove', dragHandler);
                document.addEventListener('mouseup', dragHandler);
                offsetX = e.clientX - dialog.offsetLeft;
                offsetY = e.clientY - dialog.offsetTop;
                setTimeout(() => {
                    if(!isNaN(parseFloat(dialog.style.left)) && !isNaN(parseFloat(dialog.style.top))){
                        dialog.style.right = 'auto';
                        dialog.style.bottom = 'auto';
                    }
                }, 100);
            } else if (e.type === 'mousemove' && isDragging) {
                // 拖动中
                const x = e.clientX - offsetX;
                const y = e.clientY - offsetY;
                //限制不超过窗口大小
                if(x < 0) x = 0;
                if(y < 0) y = 0;
                if(x > window.innerWidth - dialogRect.width) x = window.innerWidth - dialogRect.width;
                if(y > window.innerHeight - dialogRect.height) y = window.innerHeight - dialogRect.height;
                dialog.style.left = x + 'px';
                dialog.style.top = y + 'px';
            } else if (e.type === 'mouseup') {
                // 拖动结束
                isDragging = false;
                document.removeEventListener('mousemove', dragHandler);
                document.removeEventListener('mouseup', dragHandler);
            }
            e.preventDefault();
        };
        // 注册拖动句柄
        dragEl.removeEventListener('mousedown', dragHandler);
        dragEl.addEventListener('mousedown', dragHandler);
        // 改变窗口大小事件
        window.addEventListener("resize", (event)=>{
            if (!isNaN(parseFloat(dialog.style.left)) && !isNaN(parseFloat(dialog.style.top))) {
                if(parseFloat(dialog.style.left) > window.innerWidth) {
                    dialog.style.left = (window.innerWidth - dialogRect.width) + 'px';
                }
                if(parseFloat(dialog.style.top) > window.innerHeight) {
                    dialog.style.top = (window.innerHeight - dialogRect.height) + 'px';
                }
            }
        });
    }
  </script>
</body>
</html>

兼容手机版

function moveableDialog(dialog, dragEl) {
    let isDragging = false;
    let offsetX, offsetY;
    let dialogRect = dialog.getBoundingClientRect();

    const dragHandler = (e) => {
        let clientX, clientY;

        // 处理触摸事件
        if (e.type.startsWith('touch')) {
            if (e.touches.length > 0) {
                clientX = e.touches[0].clientX;
                clientY = e.touches[0].clientY;
            } else {
                return; // 如果没有触摸点,直接返回
            }
        } else {
            clientX = e.clientX;
            clientY = e.clientY;
        }

        if (e.type === 'mousedown' || e.type === 'touchstart') {
            // 开始拖动
            isDragging = true;
            document.removeEventListener('mousemove', dragHandler);
            document.removeEventListener('mouseup', dragHandler);
            document.removeEventListener('touchmove', dragHandler);
            document.removeEventListener('touchend', dragHandler);
            document.addEventListener('mousemove', dragHandler);
            document.addEventListener('mouseup', dragHandler);
            document.addEventListener('touchmove', dragHandler);
            document.addEventListener('touchend', dragHandler);
            offsetX = clientX - dialog.offsetLeft;
            offsetY = clientY - dialog.offsetTop;
            setTimeout(() => {
                if (!isNaN(parseFloat(dialog.style.left)) && !isNaN(parseFloat(dialog.style.top))) {
                    dialog.style.right = 'auto';
                    dialog.style.bottom = 'auto';
                }
            }, 100);
        } else if ((e.type === 'mousemove' || e.type === 'touchmove') && isDragging) {
            // 拖动中
            const x = clientX - offsetX;
            const y = clientY - offsetY;
            // 限制不超过窗口大小
            const maxX = window.innerWidth - dialogRect.width;
            const maxY = window.innerHeight - dialogRect.height;
            const clampedX = Math.max(0, Math.min(x, maxX));
            const clampedY = Math.max(0, Math.min(y, maxY));
            dialog.style.left = clampedX + 'px';
            dialog.style.top = clampedY + 'px';
        } else if (e.type === 'mouseup' || e.type === 'touchend') {
            // 拖动结束
            isDragging = false;
            document.removeEventListener('mousemove', dragHandler);
            document.removeEventListener('mouseup', dragHandler);
            document.removeEventListener('touchmove', dragHandler);
            document.removeEventListener('touchend', dragHandler);
        }
        e.preventDefault();
    };

    // 注册拖动句柄
    dragEl.removeEventListener('mousedown', dragHandler);
    dragEl.removeEventListener('touchstart', dragHandler);
    dragEl.addEventListener('mousedown', dragHandler);
    dragEl.addEventListener('touchstart', dragHandler);

    // 改变窗口大小事件
    window.addEventListener("resize", (event) => {
        if (!isNaN(parseFloat(dialog.style.left)) && !isNaN(parseFloat(dialog.style.top))) {
            if (parseFloat(dialog.style.left) > window.innerWidth) {
                dialog.style.left = (window.innerWidth - dialogRect.width) + 'px';
            }
            if (parseFloat(dialog.style.top) > window.innerHeight) {
                dialog.style.top = (window.innerHeight - dialogRect.height) + 'px';
            }
        }
    });
}
image.png

留下你的脚步
推荐阅读