基于ul列表项数量的响应式block显示:纯JS最优实现方案咨询
Awesome question! Let's walk through an efficient, performance-focused solution using vanilla JavaScript—no libraries or Resize Observer required. The key here is to minimize unnecessary DOM work and reduce the number of times our logic runs during window resizing.
Step 1: Cache Elements & Define Configuration
First, we'll cache our target elements to avoid repeated DOM queries (a big performance win) and set up a clear configuration object to map list item counts to their corresponding trigger widths. This is way more flexible than a switch statement—you can easily add/remove rules later.
// Cache DOM elements once instead of querying on every resize const ulElement = document.querySelector("#ulClass"); const targetBlock = document.querySelector("#yourTargetBlock"); // Replace with your block's selector // Configuration: Map number of list items to the window width that triggers visibility const visibilityRules = { 2: 500, // Show block when window is ≥500px AND there are 2 list items 3: 600, // Add more rules as needed 4: 700 };
Step 2: Add Debouncing for Resize Performance
Window resize events fire constantly as the user drags the window edge. We'll use a debounce function to limit how often our visibility logic runs—this prevents unnecessary computations and keeps the UI smooth.
// Simple debounce function to throttle function execution function debounce(func, delay = 100) { let timeoutId; return function(...args) { clearTimeout(timeoutId); timeoutId = setTimeout(() => func.apply(this, args), delay); }; }
Step 3: Core Visibility Logic
Next, we'll write the function that checks the current window width and list item count, then toggles the block's visibility based on our rules.
function updateBlockVisibility() { const windowWidth = window.innerWidth; // Get list item count (move this outside if your list never changes dynamically) const listItemCount = ulElement.querySelectorAll("li").length; // Get the trigger width for the current list count; default to Infinity (never show) if no rule exists const triggerWidth = visibilityRules[listItemCount] || Infinity; // Toggle visibility targetBlock.style.display = windowWidth >= triggerWidth ? "block" : "none"; // If you use CSS classes instead of inline styles (better practice!), use this instead: // targetBlock.classList.toggle("visible", windowWidth >= triggerWidth); }
Step 4: Hook It All Up
Finally, we'll bind our debounced function to the resize event and run it once on page load to set the initial state.
// Wrap our visibility function with debounce to optimize performance const debouncedUpdate = debounce(updateBlockVisibility); // Listen for window resize events window.addEventListener("resize", debouncedUpdate); // Run once on page load to set initial visibility updateBlockVisibility();
Key Performance & Maintainability Wins
- DOM Caching: We only query the DOM once for our elements, avoiding expensive repeated lookups.
- Debouncing: Reduces the number of times our logic runs during resizing (from dozens of times per second to once after the user stops dragging).
- Config-Driven Logic: The
visibilityRulesobject makes it easy to adjust or add new rules without rewriting conditional logic. - Optional Static List Optimization: If your list items never change dynamically, move
const listItemCount = ulElement.querySelectorAll("li").length;outside the function to compute it only once.
Handling Dynamic List Items
If your list items are added/removed dynamically, just call updateBlockVisibility() right after modifying the list to refresh the visibility state immediately.
内容的提问来源于stack exchange,提问作者DaveJones

