Как отключить ссылки у родительских пунктов меню?

18 янв. 2013 г., 06:20:14
Просмотры: 15.6K
Голосов: 0

Я не хочу, чтобы родительские пункты меню моего сайта вели на отдельные страницы. Во-первых, мне не нужны лишние страницы. Во-вторых, эти ссылки усложняют навигацию для мобильных пользователей, которые не могут "навести" курсор на ссылку (чтобы увидеть дочерние элементы).

Лучшим решением было бы отключить ссылки у родительских пунктов меню. Но как это сделать, особенно теперь, когда с выходом WordPress 3.5 плагин Disable Parent Menu Item перестал работать?

Одно из возможных решений можно найти здесь.

0
Все ответы на вопрос 5
6

Не создавайте фальшивые URL (#). Это очень плохо для пользователей с программами чтения с экрана: они используют список доступных ссылок для навигации по вашему сайту. То же самое касается ссылок с javascript:, которые и так не являются элегантной разметкой.

Вам нужно выполнить два шага:

  1. Пометьте элементы с дочерними элементами до начала работы walker.
  2. Замените разметку для верхних родительских элементов.

Я буду использовать пустой элемент <a> здесь, чтобы упростить получение курсора. Вам, вероятно, понадобится что-то подобное в вашей таблице стилей:

.menu > .has-children {
    cursor: pointer;
}

Фильтр для пометки родительских элементов взят из этого ответа. Вторая функция просто проверяет наличие этого свойства и проверяет, не является ли сам элемент дочерним.

add_filter( 'wp_nav_menu_objects',      't5_add_has_children_to_nav_items' );
add_filter( 'walker_nav_menu_start_el', 't5_unlink_parent_item', 10, 4 );

/**
 * Добавляет свойство 'has_children' к элементам меню
 *
 * @wp-hook wp_nav_menu_objects
 * @param   array $items
 * @return  array
 */
function t5_add_has_children_to_nav_items( $items )
{
    $parents = wp_list_pluck( $items, 'menu_item_parent' );
    $out     = array ();

    foreach ( $items as $item )
    {
        in_array( $item->ID, $parents ) && $item->has_children = TRUE;
        $out[] = $item;
    }
    return $items;
}
/**
 * Заменяет разметку верхнего родительского элемента.
 *
 * @wp-hook walker_nav_menu_start_el
 * @param   string $item_output
 * @param   object $item
 * @param   int    $depth
 * @param   object $args
 * @return  string
 */
function t5_unlink_parent_item( $item_output, $item, $depth, $args )
{
    // не родительский элемент первого уровня
    if ( empty ( $item->has_children ) or 0 != $item->menu_item_parent )
        return $item_output;

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

    $classes = empty( $item->classes ) ? array() : (array) $item->classes;
    $classes[] = 'menu-item-' . $item->ID;
    $classes[] = 'has-children';
    $class_names = join(
        ' ',
        apply_filters(
            'nav_menu_css_class',
            array_filter( $classes ),
            $item,
            $args
        )
    );
    $class_names = $class_names
        ? ' class="' . esc_attr( $class_names ) . '"'
        : '';

    return "<li$id>$args->before<a class='menu-item has-children'>$title</a>$args->after";
}
18 янв. 2013 г. 08:14:18
Комментарии

Этот ответ лучше моего, но он указывает на фундаментальный недостаток в меню WordPress — для достижения того, что должно быть простой вещью, требуется столько кода :)

JCL1178 JCL1178
18 янв. 2013 г. 08:23:23

@JCL1178 Полагаю, немногие авторы используют верхний уровень без href. Да и большинство пользовательских тем используют собственный walker в любом случае. Я рассматриваю нативную реализацию как отправную точку, которая работает в большинстве случаев, но не навязывается разработчику.

fuxia fuxia
18 янв. 2013 г. 08:27:57

Спасибо за ваш развернутый ответ, toscho. Видно, что вы вложили в него много труда. На самом деле, в ответе по ссылке, которую я привел, говорится о необходимости удалить символ решетки, так что в ссылке меню ее не будет: она становится ссылкой без href, то есть без URL, поддельного или иного. Поскольку ваше решение, кажется, также зависит от удаления href, мне интересно, чем оно лучше для скринридеров. Стоит ли использовать ваш walker?

JohnK JohnK
24 мар. 2013 г. 03:44:56

@JohnK Плагин из той ветки — это, вероятно, худший из возможных способов решения этой проблемы. У вас обязательно возникнут конфликты с другими плагинами, потому что он вызывает wp_print_scripts второй раз. Это вообще не должно было пройти проверку плагинов... В любом случае, используйте PHP-решение здесь; оно не имеет побочных эффектов, за исключением случаев, когда вы используете плагин с собственным пользовательским walker.

fuxia fuxia
24 мар. 2013 г. 03:57:46

Ссылка была не на плагин, toscho, а на простой, 'ручной' способ замены для создания не кликабельного пункта меню. Кажется, дает тот же эффект, что и ваш код. Хотел бы отдать должное вашей работе, но я могу выбрать ваш ответ как правильный только если вы обоснуете его превосходство над простым способом.

JohnK JohnK
24 мар. 2013 г. 04:25:06

А, понятно. Используйте то, что лучше подходит для вашего случая. Мое решение работает автоматически, другое требует ручной настройки. Я предпочитаю решения, которые просто работают. Но если вас устраивают дополнительные шаги — делайте так.

fuxia fuxia
24 мар. 2013 г. 04:35:53
Показать остальные 1 комментариев
3

Я бы просто создал пользовательские пункты меню с javascript:void(0) в качестве href, когда требуется элемент верхнего уровня.

18 янв. 2013 г. 07:15:45
Комментарии

Хороший ответ, и гораздо лучшее решение, чем использование символа решетки в ссылке, как указано в ссылке автора сообщения.

gteh gteh
18 янв. 2013 г. 07:38:43

На самом деле, если внимательно прочитать, в том решении предлагается убрать символ решетки, так что в ссылке его не будет.

JohnK JohnK
24 мар. 2013 г. 03:31:44

Но как? Можете привести пример?

244boy 244boy
26 нояб. 2019 г. 12:05:08
1

Работает с WordPress 3.5:

  1. Добавьте пункт меню Ссылка с нужным вам названием и URL в виде #
  2. Отредактируйте только что созданный пункт меню и удалите символ #

Необходимо выполнить оба шага, так как нельзя добавить пункт меню с пустым URL.

6 июн. 2013 г. 14:36:15
Комментарии

Можете объяснить подробнее?

244boy 244boy
26 нояб. 2019 г. 11:50:00
0

Немного поздно, но для будущего использования. Вы можете создать пользовательскую ссылку для родительского элемента. При добавлении вам нужно указать символ #, но после добавления вы можете удалить его, что отключит ссылку.

25 апр. 2018 г. 20:18:11
0
-1

Чтобы убрать активный курсор "hover":

Настройки темы > Выпадающее меню > Сделать родительские пункты меню кликабельными : отключить

29 июл. 2015 г. 18:28:38