PC端前端开发中实现鼠标移入动态菜单的多种方式

在PC端前端开发中,实现鼠标移入后出现动态菜单有多种实现方式,下面我将列举常见的方法并提供简单示例代码。

1. 纯CSS实现 (hover伪类)

这是最简单的方式,利用CSS的:hover伪类触发菜单显示。

html 复制代码
<!DOCTYPE html>
<html>
<head>
<style>
.dropdown {
  position: relative;
  display: inline-block;
}

.dropdown-content {
  display: none;
  position: absolute;
  background-color: #f9f9f9;
  min-width: 160px;
  box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
  padding: 12px 16px;
  z-index: 1;
}

.dropdown:hover .dropdown-content {
  display: block;
}
</style>
</head>
<body>

<div class="dropdown">
  <span>鼠标移入我</span>
  <div class="dropdown-content">
    <p>菜单项1</p>
    <p>菜单项2</p>
    <p>菜单项3</p>
  </div>
</div>

</body>
</html>

2. CSS过渡动画实现

在显示/隐藏时添加平滑的过渡效果。

html 复制代码
<!DOCTYPE html>
<html>
<head>
<style>
.dropdown {
  position: relative;
  display: inline-block;
}

.dropdown-content {
  position: absolute;
  background-color: #f9f9f9;
  min-width: 160px;
  box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
  padding: 12px 16px;
  z-index: 1;
  
  opacity: 0;
  visibility: hidden;
  transform: translateY(-10px);
  transition: all 0.3s ease;
}

.dropdown:hover .dropdown-content {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}
</style>
</head>
<body>

<div class="dropdown">
  <span>鼠标移入我(有动画)</span>
  <div class="dropdown-content">
    <p>菜单项1</p>
    <p>菜单项2</p>
    <p>菜单项3</p>
  </div>
</div>

</body>
</html>

3. JavaScript事件监听实现

使用mouseover/mouseout或mouseenter/mouseleave事件。

html 复制代码
<!DOCTYPE html>
<html>
<head>
<style>
.dropdown-content {
  display: none;
  position: absolute;
  background-color: #f9f9f9;
  min-width: 160px;
  box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
  padding: 12px 16px;
  z-index: 1;
}
</style>
</head>
<body>

<div id="dropdown">
  <span>鼠标移入我(JS控制)</span>
  <div id="dropdown-content" class="dropdown-content">
    <p>菜单项1</p>
    <p>菜单项2</p>
    <p>菜单项3</p>
  </div>
</div>

<script>
const dropdown = document.getElementById('dropdown');
const content = document.getElementById('dropdown-content');

dropdown.addEventListener('mouseenter', () => {
  content.style.display = 'block';
});

dropdown.addEventListener('mouseleave', () => {
  content.style.display = 'none';
});
</script>

</body>
</html>

4. jQuery实现

使用jQuery简化DOM操作和事件处理。

html 复制代码
<!DOCTYPE html>
<html>
<head>
<style>
.dropdown-content {
  display: none;
  position: absolute;
  background-color: #f9f9f9;
  min-width: 160px;
  box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
  padding: 12px 16px;
  z-index: 1;
}
</style>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>

<div id="dropdown">
  <span>鼠标移入我(jQuery)</span>
  <div class="dropdown-content">
    <p>菜单项1</p>
    <p>菜单项2</p>
    <p>菜单项3</p>
  </div>
</div>

<script>
$(document).ready(function() {
  $('#dropdown').hover(
    function() {
      $(this).find('.dropdown-content').stop(true, true).fadeIn(300);
    },
    function() {
      $(this).find('.dropdown-content').stop(true, true).fadeOut(300);
    }
  );
});
</script>

</body>
</html>

5. Vue.js实现

使用Vue的指令和数据绑定。

html 复制代码
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<style>
.dropdown-content {
  display: none;
  position: absolute;
  background-color: #f9f9f9;
  min-width: 160px;
  box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
  padding: 12px 16px;
  z-index: 1;
}
.dropdown-content.show {
  display: block;
}
</style>
</head>
<body>

<div id="app">
  <div class="dropdown" 
       @mouseenter="showMenu = true" 
       @mouseleave="showMenu = false">
    <span>鼠标移入我(Vue)</span>
    <div class="dropdown-content" :class="{show: showMenu}">
      <p>菜单项1</p>
      <p>菜单项2</p>
      <p>菜单项3</p>
    </div>
  </div>
</div>

<script>
new Vue({
  el: '#app',
  data: {
    showMenu: false
  }
});
</script>

</body>
</html>

6. React实现

使用React的状态和事件处理。

jsx 复制代码
import React, { useState } from 'react';

function DropdownMenu() {
  const [isOpen, setIsOpen] = useState(false);

  return (
    <div 
      className="dropdown" 
      onMouseEnter={() => setIsOpen(true)}
      onMouseLeave={() => setIsOpen(false)}
    >
      <span>鼠标移入我(React)</span>
      {isOpen && (
        <div className="dropdown-content">
          <p>菜单项1</p>
          <p>菜单项2</p>
          <p>菜单项3</p>
        </div>
      )}
    </div>
  );
}

// 对应的CSS
// .dropdown {
//   position: relative;
//   display: inline-block;
// }
// .dropdown-content {
//   position: absolute;
//   background-color: #f9f9f9;
//   min-width: 160px;
//   box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
//   padding: 12px 16px;
//   z-index: 1;
// }

7. CSS动画关键帧实现

使用@keyframes创建更复杂的动画效果。

html 复制代码
<!DOCTYPE html>
<html>
<head>
<style>
.dropdown {
  position: relative;
  display: inline-block;
}

.dropdown-content {
  position: absolute;
  background-color: #f9f9f9;
  min-width: 160px;
  box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
  padding: 12px 16px;
  z-index: 1;
  
  opacity: 0;
  transform: scale(0.8);
  transform-origin: top center;
  transition: all 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55);
  pointer-events: none;
}

.dropdown:hover .dropdown-content {
  opacity: 1;
  transform: scale(1);
  pointer-events: auto;
}
</style>
</head>
<body>

<div class="dropdown">
  <span>鼠标移入我(弹性动画)</span>
  <div class="dropdown-content">
    <p>菜单项1</p>
    <p>菜单项2</p>
    <p>菜单项3</p>
  </div>
</div>

</body>
</html>

8. Web Components实现

使用自定义元素封装菜单组件。

html 复制代码
<!DOCTYPE html>
<html>
<head>
<style>
.dropdown-content {
  display: none;
  position: absolute;
  background-color: #f9f9f9;
  min-width: 160px;
  box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
  padding: 12px 16px;
  z-index: 1;
}
</style>
</head>
<body>

<custom-dropdown>
  <span slot="trigger">鼠标移入我(Web组件)</span>
  <div slot="content">
    <p>菜单项1</p>
    <p>菜单项2</p>
    <p>菜单项3</p>
  </div>
</custom-dropdown>

<script>
class CustomDropdown extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({ mode: 'open' });
    
    this.shadowRoot.innerHTML = `
      <style>
        :host {
          position: relative;
          display: inline-block;
        }
        .dropdown-content {
          display: none;
          position: absolute;
          background-color: #f9f9f9;
          min-width: 160px;
          box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
          padding: 12px 16px;
          z-index: 1;
        }
      </style>
      <div class="dropdown">
        <slot name="trigger"></slot>
        <div class="dropdown-content">
          <slot name="content"></slot>
        </div>
      </div>
    `;
    
    this.dropdown = this.shadowRoot.querySelector('.dropdown');
    this.content = this.shadowRoot.querySelector('.dropdown-content');
    
    this.dropdown.addEventListener('mouseenter', () => {
      this.content.style.display = 'block';
    });
    
    this.dropdown.addEventListener('mouseleave', () => {
      this.content.style.display = 'none';
    });
  }
}

customElements.define('custom-dropdown', CustomDropdown);
</script>

</body>
</html>

9. GSAP动画库实现

使用GSAP创建更专业的动画效果。

html 复制代码
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.1/gsap.min.js"></script>
<style>
.dropdown {
  position: relative;
  display: inline-block;
}

.dropdown-content {
  position: absolute;
  background-color: #f9f9f9;
  min-width: 160px;
  box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
  padding: 12px 16px;
  z-index: 1;
  opacity: 0;
  transform: translateY(-10px);
}
</style>
</head>
<body>

<div id="dropdown">
  <span>鼠标移入我(GSAP动画)</span>
  <div id="dropdown-content" class="dropdown-content">
    <p>菜单项1</p>
    <p>菜单项2</p>
    <p>菜单项3</p>
  </div>
</div>

<script>
const dropdown = document.getElementById('dropdown');
const content = document.getElementById('dropdown-content');

dropdown.addEventListener('mouseenter', () => {
  gsap.to(content, {
    opacity: 1,
    y: 0,
    duration: 0.3,
    ease: "power2.out"
  });
});

dropdown.addEventListener('mouseleave', () => {
  gsap.to(content, {
    opacity: 0,
    y: -10,
    duration: 0.2,
    ease: "power2.in"
  });
});
</script>

</body>
</html>

10. 使用CSS框架实现

利用Bootstrap等CSS框架内置的组件。

html 复制代码
<!DOCTYPE html>
<html>
<head>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>

<div class="dropdown">
  <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-bs-toggle="dropdown" aria-expanded="false">
    鼠标移入我(Bootstrap)
  </button>
  <ul class="dropdown-menu" aria-labelledby="dropdownMenuButton">
    <li><a class="dropdown-item" href="#">菜单项1</a></li>
    <li><a class="dropdown-item" href="#">菜单项2</a></li>
    <li><a class="dropdown-item" href="#">菜单项3</a></li>
  </ul>
</div>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
<script>
// Bootstrap 5默认需要点击触发,改为鼠标悬停
const dropdownElementList = [].slice.call(document.querySelectorAll('.dropdown-toggle'))
dropdownElementList.map(function (dropdownToggleEl) {
  dropdownToggleEl.addEventListener('mouseenter', function () {
    const dropdownMenu = dropdownToggleEl.nextElementSibling;
    dropdownMenu.classList.add('show');
  });
  
  const dropdown = dropdownToggleEl.closest('.dropdown');
  dropdown.addEventListener('mouseleave', function () {
    const dropdownMenu = dropdown.querySelector('.dropdown-menu');
    dropdownMenu.classList.remove('show');
  });
});
</script>

</body>
</html>

总结

以上列举了10种实现鼠标移入动态菜单的方法,从最简单的CSS hover到复杂的框架实现,开发者可以根据项目需求和技术栈选择最适合的方式。对于简单的需求,纯CSS实现是最轻量级的解决方案;对于需要复杂交互和动画的场景,可以考虑使用JavaScript或动画库实现。

相关推荐
小高0074 分钟前
JavaScript 内存管理是如何工作的?
前端·javascript
是大林的林吖11 分钟前
解决 elementui el-cascader组件懒加载时存在选中状态丢失的问题?
前端·javascript·elementui
鹏仔工作室11 分钟前
elemetui中el-date-picker限制开始结束日期只能选择当月
前端·vue.js·elementui
一 乐13 分钟前
个人博客|博客app|基于Springboot+微信小程序的个人博客app系统设计与实现(源码+数据库+文档)
java·前端·数据库·spring boot·后端·小程序·论文
sTone8737522 分钟前
Android Room部件协同使用
android·前端
晴殇i27 分钟前
前端代码规范体系建设与团队落地实践
前端·javascript·面试
用户740546399430927 分钟前
Vite 库模式输出 ESM 格式时的依赖处理方案
前端·vite
开发者小天35 分钟前
React中使用useParams
前端·javascript·react.js
lichong95143 分钟前
Android studio release 包打包配置 build.gradle
android·前端·ide·flutter·android studio·大前端·大前端++
nvvas1 小时前
npm : 无法加载文件 D:\nvm\nodejs\npm.ps1,因为在此系统上禁止运行脚本问题解决
前端·npm·node.js