如何将下拉菜单的JQuery代码转换为Vanilla JavaScript?
Hey there! Let's take that jQuery-powered multi-level dropdown and rewrite it using plain vanilla JavaScript, keeping all the original functionality intact. I'll walk through the conversion step by step, explaining how each part maps from jQuery to native JS.
Original jQuery Logic Recap
First, let's remember what the original jQuery code was doing:
$(document).ready(function(){ $('.menu-item').hover(function(){ $(this).children('.submenu').stop(true, false).slideDown(300); }, function(){ $(this).children('.submenu').stop(true, false).slideUp(300); }); });
It waits for the DOM to load, then adds hover handlers to menu items to slide their submenus open/closed with a 300ms animation.
Vanilla JavaScript Conversion
We'll replicate this logic using native APIs, and use CSS transitions for smooth sliding (since vanilla JS doesn't have a built-in slideDown/slideUp method).
Step 1: Update CSS (For Animation)
First, adjust your .submenu styling to support the slide animation (this replaces jQuery's slide methods):
.submenu { max-height: 0; overflow: hidden; /* Keep your existing submenu styles (padding, background, etc.) */ }
Step 2: Vanilla JavaScript Code
// Wait for the DOM to be fully loaded (equivalent to $(document).ready()) document.addEventListener('DOMContentLoaded', function() { // Get all menu items (equivalent to $('.menu-item')) const menuItems = document.querySelectorAll('.menu-item'); // Loop through each menu item (equivalent to jQuery's each()) menuItems.forEach(menuItem => { // Find the submenu inside this item (equivalent to $(this).children('.submenu')) const submenu = menuItem.querySelector('.submenu'); // Skip items that don't have a submenu if (!submenu) return; // Mouse enter handler (opens submenu) menuItem.addEventListener('mouseenter', function() { // Get the full height of the submenu content const fullHeight = submenu.scrollHeight; // Add transition for smooth slide submenu.style.transition = 'max-height 0.3s ease-out'; // Set max-height to the full content height to expand submenu.style.maxHeight = `${fullHeight}px`; }); // Mouse leave handler (closes submenu) menuItem.addEventListener('mouseleave', function() { // Collapse the submenu by setting max-height back to 0 submenu.style.maxHeight = '0'; // Clean up the transition after animation ends to avoid layout issues submenu.addEventListener('transitionend', function cleanup() { submenu.style.transition = ''; // Remove this cleanup handler so it only runs once submenu.removeEventListener('transitionend', cleanup); }, { once: true }); }); }); });
Key Equivalents & Explanations
$(document).ready()→DOMContentLoadedevent: Ensures we don't run code until the DOM is fully rendered.$('.menu-item')→document.querySelectorAll('.menu-item'): Gets all matching elements as a NodeList, which we can loop through withforEach.hover()→mouseenter+mouseleaveevents: jQuery'shoveris just a shorthand for these two native events.slideDown()/slideUp()→ CSSmax-heighttransition: Since vanilla JS doesn't have built-in slide animations, usingmax-heightwith a transition gives us the same smooth slide effect. We usescrollHeightto get the exact height of the submenu's content..stop(true, false)→ CSS transition behavior: When a new transition is triggered (like hovering off before the open animation finishes), CSS automatically cancels the previous animation, just like jQuery'sstop().
This code will behave exactly like the original jQuery version, but without relying on any external libraries!
内容的提问来源于stack exchange,提问作者Alex Al

