拖拉拽效果加点击事件

javascript 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>自由拖拽+点击元素</title>
    <style>
        body {
            margin: 0;
            height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
            background: #f0f0f0;
        }

        #container {
            width: 800px;
            height: 600px;
            border: 2px dashed #999;
            position: relative;
            overflow: hidden;
        }

        .draggable {
            position: absolute;
            width: 120px;
            height: 120px;
            background: #fff;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
            cursor: grab;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            transition: box-shadow 0.2s;
        }

        .draggable.dragging {
            cursor: grabbing;
            box-shadow: 0 5px 15px rgba(0,0,0,0.2);
        }

        .tag {
            padding: 6px 12px;
            background: #4CAF50;
            color: white;
            border-radius: 4px;
            margin-bottom: 8px;
            cursor: pointer;
            transition: background 0.2s;
        }

        .tag:hover {
            background: #45a049;
        }
    </style>
</head>
<body>
    <div id="container">
        <div class="draggable" style="left: 100px; top: 100px">
            <div class="tag">可拖拽标签</div>
            <div class="coordinates">(100, 100)</div>
        </div>
    </div>

    <script>
        (function() {
            // 拖拽系统初始化
            const draggables = document.querySelectorAll('.draggable');
            let currentDraggable = null;
            let startX = 0;
            let startY = 0;
            let initialX = 0;
            let initialY = 0;
            let isClick = true;

            // 鼠标按下事件
            document.addEventListener('mousedown', e => {
                const target = e.target.closest('.draggable');
                if (!target) return;

                currentDraggable = target;
                startX = e.clientX;
                startY = e.clientY;
                initialX = parseFloat(target.style.left) || 0;
                initialY = parseFloat(target.style.top) || 0;
                isClick = true;
                
                target.classList.add('dragging');
                document.addEventListener('mousemove', onMouseMove);
                document.addEventListener('mouseup', onMouseUp);
            });

            // 鼠标移动事件
            function onMouseMove(e) {
                if (!currentDraggable) return;
                
                // 判断是否达到移动阈值(3像素)
                if (Math.abs(e.clientX - startX) > 3 || 
                    Math.abs(e.clientY - startY) > 3) {
                    isClick = false;
                }

                const container = document.getElementById('container');
                const containerRect = container.getBoundingClientRect();
                const elementRect = currentDraggable.getBoundingClientRect();
                
                // 计算新位置
                let newX = initialX + (e.clientX - startX);
                let newY = initialY + (e.clientY - startY);

                // 边界限制
                newX = Math.max(0, Math.min(
                    newX, 
                    containerRect.width - elementRect.width
                ));
                
                newY = Math.max(0, Math.min(
                    newY,
                    containerRect.height - elementRect.height
                ));

                // 更新位置
                currentDraggable.style.left = `${newX}px`;
                currentDraggable.style.top = `${newY}px`;
                
                // 更新坐标显示
                currentDraggable.querySelector('.coordinates').textContent = 
                    `(${Math.round(newX)}, ${Math.round(newY)})`;
            }

            // 鼠标松开事件
            function onMouseUp(e) {
                if (!currentDraggable) return;
                
                currentDraggable.classList.remove('dragging');
                document.removeEventListener('mousemove', onMouseMove);
                document.removeEventListener('mouseup', onMouseUp);
                currentDraggable = null;

                // 如果移动距离太小视为点击
                if (isClick) {
                    handleClick(e);
                }
            }

            // 点击处理函数
            function handleClick(e) {
                const tag = e.target.closest('.tag');
                if (tag) {
                    // 标签点击
                    tag.style.background = '#ff5722';
                    setTimeout(() => tag.style.background = '#4CAF50', 200);
                    alert('标签被点击!');
                } else {
                    // 整个元素点击
                    const element = e.target.closest('.draggable');
                    element.style.background = '#f8f8f8';
                    setTimeout(() => element.style.background = '#fff', 200);
                    alert('元素被点击!');
                }
            }
        })();
    </script>
</body>
</html>
相关推荐
一朵好运莲2 分钟前
超详细mac上用nvm安装node环境,配置npm
前端·macos·npm
大樊子11 分钟前
JavaScript 中的单例模式
开发语言·javascript·单例模式
天天扭码12 分钟前
一分钟解决 | 高频面试算法题——最小覆盖子串
前端·算法·面试
白飞飞13 分钟前
原生小程序工程化指北:从混乱到规范的进化之路
前端·vue.js·微信小程序
加油乐16 分钟前
JS判断当前时间是否在指定时段内(支持多时段使用)
前端·javascript
Epat19 分钟前
关于一个小菜鸡是如何通过自定义 postcss 插件解决 color-mix 兼容问题的
前端
小小小小宇21 分钟前
webComponent实现一个拖拽组件
前端
满怀101521 分钟前
【Python核心库实战指南】从数据处理到Web开发
开发语言·前端·python
PBitW29 分钟前
工作中突然发现零宽字符串的作用了!
前端·javascript·vue.js
VeryCool30 分钟前
React Native新架构升级实战【从 0.62 到 0.72】
前端·javascript·架构