前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >实现鼠标悬停标题出现下划线动画的详细技术解析

实现鼠标悬停标题出现下划线动画的详细技术解析

原创
作者头像
摸五休二
发布2024-06-23 19:53:36
2300
发布2024-06-23 19:53:36

在现代网页开发中,用户交互是一个非常重要的部分。在这篇文章中,我们将详细介绍如何使用原生 JavaScript 实现块级元素的拖拽与缩放功能。具体来说,我们将实现以下功能:

  1. 点击并拖动 outer 元素,可以移动整个块。
  2. 点击并拖动 inner 元素,可以调整 outer 元素的宽高。

实现思路

为了实现上述功能,我们需要对两个元素分别进行事件监听和处理。具体来说,我们需要监听 mousedownmousemovemouseup 事件,并根据事件触发的位置和元素的状态,来决定执行拖动还是缩放操作。

HTML 结构

首先,我们定义两个块元素 outerinnerinner 位于 outer 的右下角,用于调整 outer 的大小。

代码语言:html
复制
<div id="outer" style="width: 100px; height: 100px; border: 1px solid black; position: relative;">
    <span id="inner" style="position: absolute; bottom: 0; right: 0; width: 10px; height: 10px; background: red; cursor: nwse-resize;"></span>
</div>

CSS 样式

简单的样式来定义块元素的尺寸和位置:

代码语言:css
复制
#outer {
    width: 100px;
    height: 100px;
    border: 1px solid black;
    position: relative;
}

#inner {
    position: absolute;
    bottom: 0;
    right: 0;
    width: 10px;
    height: 10px;
    background: red;
    cursor: nwse-resize;
}

JavaScript 实现

接下来,我们编写 JavaScript 代码,实现块的拖动和缩放功能。我们需要两个主要的事件处理程序,一个用于 outer 的拖动,另一个用于 inner 的缩放。

拖动功能

首先实现 outer 的拖动功能:

代码语言:javascript
复制
document.addEventListener('DOMContentLoaded', function() {
    const outer = document.getElementById('outer');
    let isDragging = false;
    let dragStartX, dragStartY, startLeft, startTop;

    outer.addEventListener('mousedown', function(e) {
        if (e.target === outer) {
            isDragging = true;
            dragStartX = e.clientX;
            dragStartY = e.clientY;
            startLeft = outer.offsetLeft;
            startTop = outer.offsetTop;
            document.addEventListener('mousemove', drag);
            document.addEventListener('mouseup', stopDrag);
        }
    });

    function drag(e) {
        if (isDragging) {
            const dx = e.clientX - dragStartX;
            const dy = e.clientY - dragStartY;
            outer.style.left = `${startLeft + dx}px`;
            outer.style.top = `${startTop + dy}px`;
        }
    }

    function stopDrag() {
        isDragging = false;
        document.removeEventListener('mousemove', drag);
        document.removeEventListener('mouseup', stopDrag);
    }
});

以下是实现拖动效果,此时还未实现缩放功能。

缩放功能

接下来实现 inner 的缩放功能:

代码语言:javascript
复制
document.addEventListener('DOMContentLoaded', function() {
    const outer = document.getElementById('outer');
    const inner = document.getElementById('inner');
    let isResizing = false;
    let resizeStartX, resizeStartY, startWidth, startHeight;

    inner.addEventListener('mousedown', function(e) {
        e.stopPropagation(); // 阻止事件冒泡到 outer
        isResizing = true;
        resizeStartX = e.clientX;
        resizeStartY = e.clientY;
        startWidth = outer.offsetWidth;
        startHeight = outer.offsetHeight;
        document.addEventListener('mousemove', resize);
        document.addEventListener('mouseup', stopResize);
    });

    function resize(e) {
        if (isResizing) {
            const dx = e.clientX - resizeStartX;
            const dy = e.clientY - resizeStartY;
            outer.style.width = `${startWidth + dx}px`;
            outer.style.height = `${startHeight + dy}px`;
        }
    }

    function stopResize() {
        isResizing = false;
        document.removeEventListener('mousemove', resize);
        document.removeEventListener('mouseup', stopResize);
    }
});

组合功能

为了确保两个功能可以同时存在,我们需要确保在 inner 被拖动时,outer 的拖动功能不会被触发。为此,我们在 innermousedown 事件处理程序中调用 e.stopPropagation(),以阻止事件冒泡到 outer

完整代码

以下是完整的实现代码,包括 HTML、CSS 和 JavaScript 部分:

代码语言:html
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>拖拽与缩放功能</title>
    <style>
        #outer {
            width: 100px;
            height: 100px;
            border: 1px solid black;
            position: absolute;
        }

        #inner {
            position: absolute;
            bottom: 0;
            right: 0;
            width: 10px;
            height: 10px;
            background: red;
            cursor: nwse-resize;
        }
    </style>
</head>
<body>
    <div id="outer">
        <span id="inner"></span>
    </div>

    <script>
        document.addEventListener('DOMContentLoaded', function() {
            const outer = document.getElementById('outer');
            const inner = document.getElementById('inner');
            let isDragging = false;
            let isResizing = false;
            let dragStartX, dragStartY, startLeft, startTop;
            let resizeStartX, resizeStartY, startWidth, startHeight;

            outer.addEventListener('mousedown', function(e) {
                if (e.target === outer) {
                    isDragging = true;
                    dragStartX = e.clientX;
                    dragStartY = e.clientY;
                    startLeft = outer.offsetLeft;
                    startTop = outer.offsetTop;
                    document.addEventListener('mousemove', drag);
                    document.addEventListener('mouseup', stopDrag);
                }
            });

            inner.addEventListener('mousedown', function(e) {
                e.stopPropagation(); // 阻止事件冒泡到 outer
                isResizing = true;
                resizeStartX = e.clientX;
                resizeStartY = e.clientY;
                startWidth = outer.offsetWidth;
                startHeight = outer.offsetHeight;
                document.addEventListener('mousemove', resize);
                document.addEventListener('mouseup', stopResize);
            });

            function drag(e) {
                if (isDragging) {
                    const dx = e.clientX - dragStartX;
                    const dy = e.clientY - dragStartY;
                    outer.style.left = `${startLeft + dx}px`;
                    outer.style.top = `${startTop + dy}px`;
                }
            }

            function stopDrag() {
                isDragging = false;
                document.removeEventListener('mousemove', drag);
                document.removeEventListener('mouseup', stopDrag);
            }

            function resize(e) {
                if (isResizing) {
                    const dx = e.clientX - resizeStartX;
                    const dy = e.clientY - resizeStartY;
                    outer.style.width = `${startWidth + dx}px`;
                    outer.style.height = `${startHeight + dy}px`;
                }
            }

            function stopResize() {
                isResizing = false;
                document.removeEventListener('mousemove', resize);
                document.removeEventListener('mouseup', stopResize);
            }
        });
    </script>
</body>
</html>

总结

通过本文的介绍和代码示例,我们成功实现了使用原生 JavaScript 实现块级元素的拖拽与缩放功能。在实际开发中,这种交互功能非常常见,并且对于提升用户体验非常有帮助。希望本文能够帮助你更好地理解事件处理和 DOM 操作。如果你有任何问题或建议,欢迎交流讨论。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 实现思路
    • HTML 结构
      • CSS 样式
        • JavaScript 实现
          • 拖动功能
          • 缩放功能
        • 组合功能
          • 完整代码
          • 总结
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档