Додавання до меню першого / останнього класів CSS


15

це можливо, без злому JavaScript? подобається це:

<ul class="my_menu">
  <li class="first"> ... </li>
  <li> ... </li>
  <li> ... </li>
  <li class"with_sub"> ... 
    <ul class="my_menu_sub">
      <li class="first"> ... </li>
      <li> ... </li>
      <li> ... </li>
      <li class="last"> ... </li>
    </ul>
  </li>
  <li> ... </li>
  <li> ... </li>
  <li class="last"> ... </li>
</ul>

1
що не так з використанням JavaScript? це основна функціональність, для якої вони призначені? Або це можна розглядати як прогресивне посилення?
Легкий фузз

Відповіді:


14

Кращий і простіший підхід:

function add_first_and_last($items) {
  $items[1]->classes[] = 'first-menu-item';
  $items[count($items)]->classes[] = 'last-menu-item';
  return $items;
}

add_filter('wp_nav_menu_objects', 'add_first_and_last');

1
Приємно і просто. Мені це подобається!
Джонатан Уолд

Я бачу, що цей код працює для користувацьких меню nav (я бачив, що він працює у віджеті користувальницького меню), але він не працює в тому самому меню, яке використовується в первинному навігаційному рядку (перевірено в двадцяти одинадцяти). Чи має бути? чи це був би інший код? чи просто інший фільтр? Спасибі!
Еван Матсон

2
Це буде працювати для однорівневого меню, але може не для більш складного, оскільки на даний момент це масив зі всіма пунктами, а не з найвищим рівнем.
Рарст

6

Ось приблизний фрагмент, який піклується про зміну виводу меню та додавання першого / останнього до першого та останнього класу (зовнішній ulна цьому етапі не застосовується, тому не враховується). Примітка - потрібен PHP5 дляstrripos()

add_filter( 'wp_nav_menu_items', 'first_last_class' );

function first_last_class( $items ) {

    $first = strpos( $items, 'class=' );

    if( false !== $first )
         $items = substr_replace( $items, 'first ', $first+7, 0 );

    $last = strripos( $items, 'class=');

    if( false !== $last )
         $items = substr_replace( $items, 'last ', $last+7, 0 );

    return $items;
}

Я трохи застряг у тому, як змусити його обробляти вкладені списки, але це повинно вам принаймні почати.


6

Ось функція лише додавання перших / останніх класів до елементів батьківського меню. Для більшості стилів CSS - це все, що необхідно.

function nav_menu_add_classes( $items, $args ) {
    //Add first item class
    $items[1]->classes[] = 'menu-item-first';

    //Add last item class
    $i = count($items);
    while($items[$i]->menu_item_parent != 0 && $i > 0) {
        $i--;
    }
    $items[$i]->classes[] = 'menu-item-last';

    return $items;
}
add_filter( 'wp_nav_menu_objects', 'nav_menu_add_classes', 10, 2 );

1
саме те, що я шукав. Спасибі. це дивно, що wp_nav_menu не робить цього автоматично
yitwail

Я згоден. Я вважаю, що у програмі Wordpress якийсь час був запит на функцію, але нічого з цього не вийшло. Принаймні існують відповідні фільтри, щоб ми могли додати ці класи;).
Chaoix

1
Спасибі. Шукав лічильник, який можна було б використовувати в ходунку меню. Ваша відповідь дозволяє це. Щойно додано $ item-> number = $ i; і дістала його в ходунку. Спасибі!!!
BasTaller

5

Дізнайтеся більше про новий API меню у wordpress 3. Ви можете вручну ввести будь-який елемент, який є його власним класом. Крім того, після освоєння, це робить меню, що радість редагувати.


2
Це був би шлях, просто піднесіть екран меню навігації до адміністратора та додайте клас до першого та останнього пунктів. Звичайно, якщо користувач переміщає ці пункти меню, класам доведеться перепризначити, але це, на мою думку, є найбільш вірною / найкращою відповіддю (тому що кодування не бере участь).
t31о

5

Якщо ви вклали меню

function add_first_and_last($items) {
    // first class on parent most level
    $items[1]->classes[] = 'first';
    // separate parents and children
    $parents = $children = array();
    foreach($items as $k => $item){
        if($item->menu_item_parent == '0'){
            $parents[] = $k;
        } else {
            $children[$item->menu_item_parent] = $k;
        }
    }
    // last class on parent most level
    $last = end(array_keys($parents));
    foreach ($parents as $k => $parent) {
        if ($k == $last) {
            $items[$parent]->classes[] = 'last';
        }
    }
    // last class on children levels
    foreach($children as $child){
        $items[$child]->classes[] = 'last';
    }
    // first class on children levels
    $r_items = array_reverse($items, true);
    foreach($r_items as $k => $item){
        if($item->menu_item_parent !== '0'){
            $children[$item->menu_item_parent] = $k;
        }
    }
    foreach($children as $child){
        $items[$child]->classes[] = 'first';
    }
    return $items;
}
add_filter('wp_nav_menu_objects', 'add_first_and_last');

Мені подобається простота відповіді Ісмаїля, але їх потрібно більше, якщо ви хочете класи підменю.


2

Якщо вам не потрібна підтримка IE8 або новішої версії, не забувайте, що ви також можете використовувати чистий CSS:

.my_menu > :first-child,
.my_menu > :last-child {
    /* some styles */
}

Підтримка браузера jQuery ще краща, але це здається, що ви намагаєтесь цього уникнути.


Я використовую це, тому що останній дитина також підтримується IE 9, і я вже не так хвилююся, тобто 8, 7 ..
Alex

2

Ось кращий код для додавання класів першого та останнього пунктів меню, який включає підтримку вкладених підменю.

add_filter( 'wp_nav_menu_objects', 'tgm_filter_menu_class', 10, 2 );
/**
 * Filters the first and last nav menu objects in your menus
 * to add custom classes.
 *
 * This also supports nested menus.
 *
 * @since 1.0.0
 *
 * @param array $objects An array of nav menu objects
 * @param object $args Nav menu object args
 * @return object $objects Amended array of nav menu objects with new class
 */
function tgm_filter_menu_class( $objects, $args ) {

    // Add first/last classes to nested menu items
    $ids        = array();
    $parent_ids = array();
    $top_ids    = array();
    foreach ( $objects as $i => $object ) {
        // If there is no menu item parent, store the ID and skip over the object
        if ( 0 == $object->menu_item_parent ) {
            $top_ids[$i] = $object;
            continue;
        }

        // Add first item class to nested menus
        if ( ! in_array( $object->menu_item_parent, $ids ) ) {
            $objects[$i]->classes[] = 'first-menu-item';
            $ids[]          = $object->menu_item_parent;
        }

        // If we have just added the first menu item class, skip over adding the ID
        if ( in_array( 'first-menu-item', $object->classes ) )
            continue;

        // Store the menu parent IDs in an array
        $parent_ids[$i] = $object->menu_item_parent;
    }

    // Remove any duplicate values and pull out the last menu item
    $sanitized_parent_ids = array_unique( array_reverse( $parent_ids, true ) );

    // Loop through the IDs and add the last menu item class to the appropriate objects
    foreach ( $sanitized_parent_ids as $i => $id )
        $objects[$i]->classes[] = 'last-menu-item';

    // Finish it off by adding classes to the top level menu items
    $objects[1]->classes[] = 'first-menu-item'; // We can be assured 1 will be the first item in the menu :-)
    $objects[end( array_keys( $top_ids ) )]->classes[] = 'last-menu-item';

    // Return the menu objects
    return $objects;

}

Ви можете знайти суть тут та відповідний підручник тут .


0

Як щодо:

 ul li:last-child{
     // do something with the last li
 }

а може бути, якийсь http://selectivizr.com/


Це буде стиль першого <li>в кожному не упорядкованому списку на сайті, а не лише в меню. Це також суттєво ідентично цій відповіді wordpress.stackexchange.com/a/63128/9844
mrwweb

Вибачте, псевдо-код.
Я

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.