WordPress не работает dropdown при использовании wp_nav_menu с bootstrap 5

Делаю так

    wp_nav_menu(array(
        'theme_location' => 'header_menu',
        'container' => false,
        'menu_class' => '',
        'fallback_cb' => '__return_false',
        'items_wrap' => '<ul id="%1$s" class="navbar-nav me-auto mb-2 mb-md-0 %2$s">%3$s</ul>',
        'depth' => 2,
        'walker' => new bootstrap_5_wp_nav_menu_walker()
    ));

в файле functions так

class bootstrap_5_wp_nav_menu_walker extends Walker_Nav_menu
{

    private $current_item;
    private $dropdown_menu_alignment_values = [
        'dropdown-menu-start',
        'dropdown-menu-end',
        'dropdown-menu-sm-start',
        'dropdown-menu-sm-end',
        'dropdown-menu-md-start',
        'dropdown-menu-md-end',
        'dropdown-menu-lg-start',
        'dropdown-menu-lg-end',
        'dropdown-menu-xl-start',
        'dropdown-menu-xl-end',
        'dropdown-menu-xxl-start',
        'dropdown-menu-xxl-end'
    ];

    function start_lvl(&$output, $depth = 0, $args = null)
    {
        $dropdown_menu_class[] = '';
        foreach($this->current_item->classes as $class) {
            if(in_array($class, $this->dropdown_menu_alignment_values)) {
            $dropdown_menu_class[] = $class;
            }
        }
        $indent = str_repeat("\t", $depth);
        $submenu = ($depth > 0) ? ' sub-menu' : '';
        $output .= "\n$indent<ul class=\"dropdown-menu$submenu " . esc_attr(implode(" ",$dropdown_menu_class)) . " depth_$depth\">\n";
    }

    function start_el(&$output, $item, $depth = 0, $args = null, $id = 0)
    {
        $this->current_item = $item;

        $indent = ($depth) ? str_repeat("\t", $depth) : '';

        $li_attributes = '';
        $class_names = $value = '';

        $classes = empty($item->classes) ? array() : (array) $item->classes;

        $classes[] = ($args->walker->has_children) ? 'dropdown' : '';
        $classes[] = 'nav-item';
        $classes[] = 'nav-item-' . $item->ID;
        if ($depth && $args->walker->has_children) {
            $classes[] = 'dropdown-menu dropdown-menu-end';
        }

        $class_names =  join(' ', apply_filters('nav_menu_css_class', array_filter($classes), $item, $args));
        $class_names = ' class="' . esc_attr($class_names) . '"';

        $id = apply_filters('nav_menu_item_id', 'menu-item-' . $item->ID, $item, $args);
        $id = strlen($id) ? ' id="' . esc_attr($id) . '"' : '';

        $output .= $indent . '<li ' . $id . $value . $class_names . $li_attributes . '>';

        $attributes = !empty($item->attr_title) ? ' title="' . esc_attr($item->attr_title) . '"' : '';
        $attributes .= !empty($item->target) ? ' target="' . esc_attr($item->target) . '"' : '';
        $attributes .= !empty($item->xfn) ? ' rel="' . esc_attr($item->xfn) . '"' : '';
        $attributes .= !empty($item->url) ? ' href="' . esc_attr($item->url) . '"' : '';

        $active_class = ($item->current || $item->current_item_ancestor || in_array("current_page_parent", $item->classes, true) || in_array("current-post-ancestor", $item->classes, true)) ? 'active' : '';
        $nav_link_class = ( $depth > 0 ) ? 'dropdown-item ' : 'nav-link ';
        $attributes .= ( $args->walker->has_children ) ? '  class="'. $nav_link_class . $active_class . ' dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"' : ' class="'. $nav_link_class . $active_class . '"';

        $item_output = $args->before;
        $item_output .= '<a' . $attributes . '>';
        $item_output .= $args->link_before . apply_filters('the_title', $item->title, $item->ID) . $args->link_after;
        $item_output .= '</a>';
        $item_output .= $args->after;

        $output .= apply_filters('walker_nav_menu_start_el', $item_output, $item, $depth, $args);
    }
}

Скрипты и стили подключил так

function tplider_scripts() {

    wp_enqueue_style( 'style-css', get_stylesheet_uri() );
    wp_enqueue_style( 'bootstrap-min', get_template_directory_uri() . '/libraries/bootstrap_5/css/bootstrap.min.css' );
    wp_enqueue_style( 'bootstrap-offcanvas', get_template_directory_uri() . '/libraries/bootstrap_offcanvas/offcanvas.css' );
    wp_enqueue_style( 'bootstrap-icons', get_template_directory_uri() . '/libraries/bootstrap-icons/bootstrap-icons.css' );

    wp_enqueue_script( 'jquery-3.1.1', get_template_directory_uri() . '/libraries/jquery-3.1.1.min.js' );
    wp_enqueue_script( 'bootstrap.bundle.min', get_template_directory_uri() . '/libraries/bootstrap_5/js/bootstrap.bundle.min.js' );
    wp_enqueue_script( 'offcanvas', get_template_directory_uri() . '/libraries/bootstrap_offcanvas/offcanvas.js' , array(), false, true );
    
}

add_action( 'wp_enqueue_scripts', 'tplider_scripts' );

И не работает выпадающее меню, хотя сам html правельный.


Ответы (1 шт):

Автор решения: Viktor

Если ваше выпадающее меню не работает, несмотря на правильный HTML, проблема может быть связана с несколькими факторами. Давайте рассмотрим несколько возможных причин и решений:

1. Проверка подключения JavaScript Убедитесь, что все необходимые скрипты Bootstrap правильно подключены и загружаются на странице. Вы можете проверить это в консоли разработчика браузера (F12 или Ctrl+Shift+I).

2. Проверка правильности HTML-структуры Убедитесь, что структура HTML для выпадающего меню соответствует требованиям Bootstrap 5. Вот пример правильной структуры:

<ul class="navbar-nav me-auto mb-2 mb-md-0">
    <li class="nav-item dropdown">
        <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
            Dropdown
        </a>
        <ul class="dropdown-menu" aria-labelledby="navbarDropdown">
            <li><a class="dropdown-item" href="#">Action</a></li>
            <li><a class="dropdown-item" href="#">Another action</a></li>
            <li><hr class="dropdown-divider"></li>
            <li><a class="dropdown-item" href="#">Something else here</a></li>
        </ul>
    </li>
</ul>

Проверка правильности Walker Убедитесь, что ваш кастомный Walker правильно генерирует HTML для выпадающего меню. Вот несколько моментов, которые стоит проверить:

  • Убедитесь, что классы dropdown, dropdown-toggle, dropdown-menu и dropdown-item добавляются корректно.
  • Убедитесь, что атрибуты data-bs-toggle="dropdown" и aria-expanded="false" добавляются к элементам .

Проверка конфликтов с другими скриптами Иногда другие скрипты могут конфликтовать с Bootstrap. Попробуйте временно отключить другие скрипты и проверить, работает ли выпадающее меню.

Проверка консоли браузера Откройте консоль разработчика в браузере (F12 или Ctrl+Shift+I) и проверьте, есть ли какие-либо ошибки JavaScript. Это может дать подсказку о том, что идет не так.

Пример исправленного Walker Вот пример исправленного Walker, который должен работать с Bootstrap 5:

class bootstrap_5_wp_nav_menu_walker extends Walker_Nav_menu
{
    private $current_item;
    private $dropdown_menu_alignment_values = [
        'dropdown-menu-start',
        'dropdown-menu-end',
        'dropdown-menu-sm-start',
        'dropdown-menu-sm-end',
        'dropdown-menu-md-start',
        'dropdown-menu-md-end',
        'dropdown-menu-lg-start',
        'dropdown-menu-lg-end',
        'dropdown-menu-xl-start',
        'dropdown-menu-xl-end',
        'dropdown-menu-xxl-start',
        'dropdown-menu-xxl-end'
    ];

    function start_lvl(&$output, $depth = 0, $args = null)
    {
        $dropdown_menu_class[] = '';
        foreach($this->current_item->classes as $class) {
            if(in_array($class, $this->dropdown_menu_alignment_values)) {
                $dropdown_menu_class[] = $class;
            }
        }
        $indent = str_repeat("\t", $depth);
        $submenu = ($depth > 0) ? ' sub-menu' : '';
        $output .= "\n$indent<ul class=\"dropdown-menu$submenu " . esc_attr(implode(" ",$dropdown_menu_class)) . " depth_$depth\">\n";
    }

    function start_el(&$output, $item, $depth = 0, $args = null, $id = 0)
    {
        $this->current_item = $item;

        $indent = ($depth) ? str_repeat("\t", $depth) : '';

        $li_attributes = '';
        $class_names = $value = '';

        $classes = empty($item->classes) ? array() : (array) $item->classes;

        $classes[] = ($args->walker->has_children) ? 'dropdown' : '';
        $classes[] = 'nav-item';
        $classes[] = 'nav-item-' . $item->ID;
        if ($depth && $args->walker->has_children) {
            $classes[] = 'dropdown-menu dropdown-menu-end';
        }

        $class_names =  join(' ', apply_filters('nav_menu_css_class', array_filter($classes), $item, $args));
        $class_names = ' class="' . esc_attr($class_names) . '"';

        $id = apply_filters('nav_menu_item_id', 'menu-item-' . $item->ID, $item, $args);
        $id = strlen($id) ? ' id="' . esc_attr($id) . '"' : '';

        $output .= $indent . '<li ' . $id . $value . $class_names . $li_attributes . '>';

        $attributes = !empty($item->attr_title) ? ' title="' . esc_attr($item->attr_title) . '"' : '';
        $attributes .= !empty($item->target) ? ' target="' . esc_attr($item->target) . '"' : '';
        $attributes .= !empty($item->xfn) ? ' rel="' . esc_attr($item->xfn) . '"' : '';
        $attributes .= !empty($item->url) ? ' href="' . esc_attr($item->url) . '"' : '';

        $active_class = ($item->current || $item->current_item_ancestor || in_array("current_page_parent", $item->classes, true) || in_array("current-post-ancestor", $item->classes, true)) ? 'active' : '';
        $nav_link_class = ( $depth > 0 ) ? 'dropdown-item ' : 'nav-link ';
        $attributes .= ( $args->walker->has_children ) ? '  class="'. $nav_link_class . $active_class . ' dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"' : ' class="'. $nav_link_class . $active_class . '"';

        $item_output = $args->before;
        $item_output .= '<a' . $attributes . '>';
        $item_output .= $args->link_before . apply_filters('the_title', $item->title, $item->ID) . $args->link_after;
        $item_output .= '</a>';
        $item_output .= $args->after;

        $output .= apply_filters('walker_nav_menu_start_el', $item_output, $item, $depth, $args);
    }
}

Подключение скриптов и стилей Убедитесь, что скрипты и стили подключены правильно:

function tplider_scripts() {
    wp_enqueue_style( 'style-css', get_stylesheet_uri() );
    wp_enqueue_style( 'bootstrap-min', get_template_directory_uri() . '/libraries/bootstrap_5/css/bootstrap.min.css' );
    wp_enqueue_style( 'bootstrap-offcanvas', get_template_directory_uri() . '/libraries/bootstrap_offcanvas/offcanvas.css' );
    wp_enqueue_style( 'bootstrap-icons', get_template_directory_uri() . '/libraries/bootstrap-icons/bootstrap-icons.css' );

    wp_enqueue_script( 'jquery-3.1.1', get_template_directory_uri() . '/libraries/jquery-3.1.1.min.js' );
    wp_enqueue_script( 'bootstrap.bundle.min', get_template_directory_uri() . '/libraries/bootstrap_5/js/bootstrap.bundle.min.js', array('jquery'), false, true );
    wp_enqueue_script( 'offcanvas', get_template_directory_uri() . '/libraries/bootstrap_offcanvas/offcanvas.js', array('jquery'), false, true );
}

add_action( 'wp_enqueue_scripts', 'tplider_scripts' );

Если после всех этих шагов выпадающее меню все еще не работает, пожалуйста, предоставьте больше информации о том, что именно не работает, и какие ошибки вы видите в консоли браузера.

→ Ссылка