讲师中心 微信公众号
AI工具推荐 视频效率加速

利用CSS变量与JavaScript事件实现鼠标按住与释放时的动画切换

浅宇酱_4790

浅宇酱_4790

发布时间:2025-12-12 14:44:13

|

962人浏览过

|

来源于php中文网

原创

利用CSS变量与JavaScript事件实现鼠标按住与释放时的动画切换

本文详细介绍了如何结合css动画和javascript事件监听,实现一个元素在鼠标左键按住时播放特定动画并保持最终状态,释放时则播放另一个动画的效果。核心方法是利用javascript的`mousedown`和`mouseup`事件动态更新css自定义属性,从而控制`@keyframes`动画的起始和结束值,实现流畅且响应式的用户交互体验。

在现代Web开发中,为用户提供丰富的交互体验至关重要。其中,根据鼠标的按住和释放状态来触发不同的动画效果是一种常见的需求。虽然CSS本身提供了:active伪类,但它通常只在元素被点击的瞬间有效,无法满足“按住时播放动画并保持,释放时播放另一动画”的复杂场景。本文将深入探讨如何通过结合JavaScript的事件监听和CSS的自定义属性(CSS变量),优雅地实现这一功能。

核心实现原理

实现鼠标按住和释放动画的关键在于:

  1. JavaScript事件监听: 捕捉全局的mousedown(鼠标按下)和mouseup(鼠标释放)事件。
  2. CSS自定义属性(变量): 定义一个或多个CSS变量,用于控制动画@keyframes的起始或结束值。
  3. JavaScript动态更新CSS变量: 在mousedown事件发生时,通过JavaScript修改CSS变量的值,触发“按住”动画;在mouseup事件发生时,再次修改CSS变量,触发“释放”动画。
  4. animation-fill-mode: forwards: 确保动画播放完成后,元素停留在动画的最后一帧状态,而不是返回初始状态。

这种方法允许我们灵活地控制动画的各个阶段,并且保持了CSS动画的性能优势。

详细步骤与示例代码

我们将创建一个简单的div元素,在鼠标按住时旋转45度并保持,释放时旋转回0度。

立即学习“Java免费学习笔记(深入)”;

1. HTML 结构

首先,定义一个简单的HTML结构,包含一个需要动画的元素。

chartjs-reporter
chartjs-reporter

此技能用于在用户需要将结构化数据(查询结果、CSV 摘要、JSON 记录或 Python 字典/列表)转换为独立的 HTML 页面时使用。

下载
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>鼠标按住与释放动画</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="animate"></div>
    <script src="script.js"></script>
</body>
</html>

2. CSS 样式与动画定义

在style.css文件中,我们将定义元素的初始样式和两个关键帧动画:mousein(按住时)和mouseout(释放时)。关键之处在于,我们使用CSS变量--mousein来动态控制@keyframes的结束值和起始值。

/* style.css */
body {
  background-color: #1c1c1c;
  display: flex; /* 居中显示 */
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  margin: 0;
}

.animate {
  background-color: white;
  position: relative;
  height: 50px;
  width: 59px;
  /* 初始应用mousein动画,持续0.4s,停留在最后一帧 */
  animation-name: mousein;
  animation-duration: 0.4s;
  animation-fill-mode: forwards;
  /* 初始旋转角度,由JS设置的CSS变量控制 */
  transform: rotate(var(--mousein, 0deg)); /* 提供一个默认值 */
}

/* 鼠标按住时播放的动画 */
@keyframes mousein {
  0% {
    /* 动画起始点,由当前--mousein变量值决定 */
    rotate: var(--mousein);
  }
  100% {
    /* 动画结束点,由JS设置的--mousein变量值决定 */
    rotate: var(--mousein);
  }
}

/* 鼠标释放时播放的动画 */
@keyframes mouseout {
  0% {
    /* 动画起始点,由当前--mousein变量值决定 */
    rotate: var(--mousein);
  }
  100% {
    /* 动画结束点,固定为0度 */
    rotate: 0deg;
  }
}

关键点解析:

  • animation-fill-mode: forwards;:这个属性确保动画完成后,元素会保持在动画的最后一帧状态。
  • rotate: var(--mousein);:我们利用CSS变量--mousein来控制旋转角度。JavaScript将负责更新这个变量的值。
  • @keyframes mousein:当鼠标按下时,我们希望元素旋转到45deg。JavaScript会将--mousein设置为45deg,动画将从当前角度(例如0deg)过渡到45deg。
  • @keyframes mouseout:当鼠标释放时,我们希望元素旋转回0deg。JavaScript会将--mousein设置为0deg,动画将从当前角度(例如45deg)过渡到0deg。
  • 注意: 原始代码中mousein的0%和100%都使用了var(--mousein),这会使得动画在变量改变时直接跳到新的变量值,而不是平滑过渡。为了实现平滑过渡,我们需要在JS中切换animation-name或者更精细地控制变量。更直接且符合原意的做法是,mousein动画的目标是45deg,mouseout动画的目标是0deg,而变量用于设定当前的“起始”或“结束”状态。

为了实现平滑过渡,我们调整CSS动画逻辑,让JavaScript在事件触发时切换animation-name。

/* 调整后的 style.css */
body {
  background-color: #1c1c1c;
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  margin: 0;
}

.animate {
  background-color: white;
  position: relative;
  height: 50px;
  width: 59px;
  /* 初始不应用动画,由JS控制 */
  /* animation-name: mousein; */
  /* animation-duration: 0.4s; */
  animation-fill-mode: forwards;
  /* 初始旋转角度 */
  transform: rotate(0deg); 
}

/* 鼠标按住时播放的动画 */
@keyframes mousein {
  0% {
    rotate: 0deg; /* 从0度开始 */
  }
  100% {
    rotate: 45deg; /* 旋转到45度 */
  }
}

/* 鼠标释放时播放的动画 */
@keyframes mouseout {
  0% {
    rotate: 45deg; /* 从45度开始 */
  }
  100% {
    rotate: 0deg; /* 旋转回0度 */
  }
}

3. JavaScript 逻辑

在script.js文件中,我们将监听mousedown和mouseup事件,并根据事件类型来切换元素的animation-name属性。

// script.js
document.addEventListener('DOMContentLoaded', () => {
  const animateElement = document.querySelector('.animate');

  // 设置初始旋转状态(这里我们不直接使用CSS变量来驱动动画的0%和100%)
  // 而是通过切换animation-name来实现
  // 初始状态为0度,所以mouseout动画的100%是0度
  // mousein动画的0%是0度

  window.addEventListener('mousedown', function() {
    // 鼠标按下时,应用mousein动画
    animateElement.style.animationName = 'mousein';
    animateElement.style.animationDuration = '0.4s';
    animateElement.style.animationFillMode = 'forwards';
  });

  window.addEventListener('mouseup', function() {
    // 鼠标释放时,应用mouseout动画
    animateElement.style.animationName = 'mouseout';
    animateElement.style.animationDuration = '0.4s';
    animateElement.style.animationFillMode = 'forwards';
  });
});

代码解释:

  • document.addEventListener('DOMContentLoaded', ...):确保DOM完全加载后再执行脚本。
  • animateElement.style.animationName = 'mousein';:当鼠标按下时,我们将元素的animation-name设置为mousein,这将触发从当前状态到mousein动画100%状态的过渡。
  • animateElement.style.animationName = 'mouseout';:当鼠标释放时,将animation-name设置为mouseout,触发从当前状态到mouseout动画100%状态的过渡。
  • animation-fill-mode: forwards;:确保动画完成后元素停留在最终状态。

优化与注意事项

  1. 全局事件监听与性能: 在window上监听mousedown和mouseup事件是有效的,但如果页面上有很多可交互元素,可能需要考虑事件委托或只在特定元素上监听,以避免不必要的计算。对于本例,全局监听是合适的。
  2. 动画平滑度: 确保mousein动画的结束状态与mouseout动画的起始状态匹配,反之亦然,这样可以保证动画切换时的平滑过渡。在本例中,mousein结束于45deg,mouseout开始于45deg,实现了平滑衔接。
  3. 动画持续时间: animation-duration需要根据实际需求调整,确保动画效果自然。
  4. CSS变量的优势: 虽然本例通过直接切换animation-name实现,但如果动画的复杂性更高,例如需要动态改变动画的多个属性(如颜色、大小、位置等),使用CSS变量来驱动@keyframes内部的多个属性值会更加灵活和强大。例如,可以定义--start-rotate和--end-rotate两个变量,然后@keyframes中引用它们。
  5. 用户体验: 考虑用户可能快速点击或拖动的情况。当前的实现能够很好地响应这些操作。
  6. 清除动画属性: 在某些复杂场景下,你可能需要在动画结束后清除animation-name属性,以避免不必要的动画重触发。可以通过监听animationend事件来完成。

总结

通过巧妙地结合JavaScript的事件监听和CSS的动画属性,我们可以轻松实现鼠标按住和释放时的自定义动画效果。这种方法不仅提供了高度的灵活性和控制力,而且利用了浏览器原生的CSS动画性能,为用户带来了流畅且富有交互性的体验。理解并掌握这种技术,将有助于开发者创建更动态、更具吸引力的Web界面。

热门AI工具

更多
蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

PixPix
PixPix Hot

PixPix是一款面向电商视觉生产的AI商品图生成工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

立刻MV
立刻MV Hot

立刻MV是一款AI文本写作工具,AI 音乐视频(MV)创作工具。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

相关专题

更多
js正则表达式
js正则表达式

php中文网为大家提供各种js正则表达式语法大全以及各种js正则表达式使用的方法,还有更多js正则表达式的相关文章、相关下载、相关课程,供大家免费下载体验。

4376

2023.06.20

js获取当前时间
js获取当前时间

JS全称JavaScript,是一种具有函数优先的轻量级,解释型或即时编译型的编程语言;它是一种属于网络的高级脚本语言,主要用于Web,常用来为网页添加各式各样的动态功能。js怎么获取当前时间呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

1335

2023.07.28

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

1738

2023.08.03

js是什么意思
js是什么意思

JS是JavaScript的缩写,它是一种广泛应用于网页开发的脚本语言。JavaScript是一种解释性的、基于对象和事件驱动的编程语言,通常用于为网页增加交互性和动态性。它可以在网页上实现复杂的功能和效果,如表单验证、页面元素操作、动画效果、数据交互等。

9923

2023.08.17

js删除节点的方法
js删除节点的方法

js删除节点的方法有:1、removeChild()方法,用于从父节点中移除指定的子节点,它需要两个参数,第一个参数是要删除的子节点,第二个参数是父节点;2、parentNode.removeChild()方法,可以直接通过父节点调用来删除子节点;3、remove()方法,可以直接删除节点,而无需指定父节点;4、innerHTML属性,用于删除节点的内容。

980

2023.09.01

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

2704

2023.09.04

Js中concat和push的区别
Js中concat和push的区别

Js中concat和push的区别:1、concat用于将两个或多个数组合并成一个新数组,并返回这个新数组,而push用于向数组的末尾添加一个或多个元素,并返回修改后的数组的新长度;2、concat不会修改原始数组,是创建新的数组,而push会修改原数组,将新元素添加到原数组的末尾等等。本专题为大家提供concat和push相关的文章、下载、课程内容,供大家免费下载体验。

1549

2023.09.14

js截取字符串的方法介绍
js截取字符串的方法介绍

JavaScript字符串截取方法,包括substring、slice、substr、charAt和split方法。这些方法可以根据具体需求,灵活地截取字符串的不同部分。在实际开发中,根据具体情况选择合适的方法进行字符串截取,能够提高代码的效率和可读性 。

4649

2023.09.21

OpenJDK JVM参数怎么调优
OpenJDK JVM参数怎么调优

Java应用运行缓慢,如何调整JVM参数?本专题介绍OpenJDK JVM性能调优的基本流程,涵盖性能指标确认、运行数据采集、内存配置和垃圾回收分析,帮助你先定位瓶颈,再通过对照测试验证效果,避免直接套用参数而影响应用稳定性。

100

2026.10.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Sass 教程
Sass 教程

共14课时 | 1.5万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 6万人学习

CSS教程
CSS教程

共754课时 | 98.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn