如何在WordPress模板中用div包裹主菜单li(含子菜单)?Navwalker可行吗?
Absolutely! Using a custom NavWalker is the most flexible and reliable way to tweak WordPress menu output to your needs—exactly what you're asking for here. Let's walk through how to wrap those parent menu <li> elements in a <div>:
Step 1: Create a Custom NavWalker Class
Add this code to your theme's functions.php file (or a custom plugin if you prefer):
class Custom_Parent_Menu_Wrapper extends Walker_Nav_Menu { // Triggered before outputting a menu item's <li> tag public function start_el(&$output, $item, $depth = 0, $args = null, $id = 0) { // Check if this is a top-level menu item with children $is_parent_top_level = $item->has_children && $depth === 0; // Wrap the parent item in a div if it meets the criteria if ($is_parent_top_level) { $output .= '<div class="menu-parent-wrapper">'; } // Let WordPress output the default <li> and link markup parent::start_el($output, $item, $depth, $args, $id); } // Triggered after outputting a menu item's closing </li> tag public function end_el(&$output, $item, $depth = 0, $args = null) { // Close the default </li> tag first parent::end_el($output, $item, $depth, $args); // Close our wrapper div if this was a top-level parent item $is_parent_top_level = $item->has_children && $depth === 0; if ($is_parent_top_level) { $output .= '</div>'; } } }
Step 2: Update Your Menu Template Call
Instead of using static HTML for your menu, use WordPress's wp_nav_menu() function (this is required for the NavWalker to work). Replace your static menu code with something like this in your template file:
wp_nav_menu(array( 'menu_id' => 'menu-1', 'menu_class' => 'menu', 'walker' => new Custom_Parent_Menu_Wrapper(), // Use our custom walker // Uncomment and adjust if you're using registered menu locations: // 'theme_location' => 'primary', ));
How This Works
- The
start_elmethod checks if we're dealing with a top-level menu item (depth === 0) that has children ($item->has_children). If so, it outputs the opening<div>before the default<li>tag. - The
end_elmethod first closes the default</li>tag, then adds the closing</div>to wrap the entire parent menu item.
Alternative: Front-End Fix (Less Ideal)
If for some reason you can't use a NavWalker (e.g., you're stuck with static menu HTML), you can use jQuery to wrap the elements after the page loads. Add this to your theme's JS file:
jQuery(document).ready(function($) { // Wrap top-level parent menu items in a div $('#menu-1 > li.menu-item-has-children').wrap('<div class="menu-parent-wrapper"></div>'); });
Note: This method is less reliable for SEO and can cause layout flicker, so the NavWalker approach is always preferred.
内容的提问来源于stack exchange,提问作者user3241084

