Menambahkan kelas CSS pertama / terakhir ke menu

15

Apakah itu mungkin, tanpa hack javascript? seperti ini:

<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>
Alex
sumber
1
apa yang salah dengan penggunaan javascript? apakah ini fungsionalitas inti untuk mereka? Atau dapatkah itu dilihat sebagai peningkatan progresif?
Mild Fuzz

Jawaban:

14

Pendekatan yang lebih baik dan sederhana:

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');
Ismaelj
sumber
1
Bagus dan sederhana. Saya suka itu!
Jonathan Wold
Saya melihat kode ini berfungsi untuk menu nav khusus (saya melihatnya berfungsi di widget menu kustom), tetapi tidak berfungsi dalam menu yang sama dengan yang digunakan di bilah nav utama (diuji di Twenty Eleven). Haruskah begitu? atau apakah itu kode yang berbeda? atau hanya filter yang berbeda? Terima kasih!
Evan Mattson
2
Ini akan berfungsi untuk menu tingkat tunggal, tetapi mungkin tidak untuk yang lebih kompleks karena pada titik ini array dengan semua item, bukan yang tingkat atas.
Rarst
6

Berikut ini cuplikan singkat yang menangani modifikasi keluaran menu dan menambahkan kelas pertama / terakhir ke kelas pertama dan terakhir (bagian luar ultidak diterapkan pada tahap ini jadi tidak masuk hitungan). Catatan - membutuhkan PHP5 untukstrripos()

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;
}

Saya agak bingung dengan cara membuatnya menangani daftar bersarang, tetapi setidaknya Anda harus memulainya.

Jarang
sumber
6

Berikut adalah fungsi untuk hanya menambahkan kelas pertama / terakhir ke item menu induk. Untuk sebagian besar gaya CSS, ini semua yang diperlukan.

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 );
Chaoix
sumber
1
persis apa yang saya cari. Terima kasih. agak mengejutkan wp_nav_menu tidak melakukan ini secara otomatis
yitwail
Saya setuju. Saya percaya ada permintaan fitur di bugtracker Wordpress untuk sementara waktu, tetapi tidak ada yang datang darinya. Setidaknya ada filter yang tepat sehingga kami dapat menambahkan kelas ini;).
Chaoix
1
Terima kasih. Sedang mencari konter, yang bisa digunakan di menu walker. jawaban Anda memungkinkan ini. Baru saja menambahkan $ item-> number = $ i; dan mendapatkannya di walker. Terima kasih!!!
BasTaller
5

Pelajari lebih lanjut tentang API Menu baru di wordpress 3. Anda dapat memberikan elemen apa pun itu kelasnya sendiri secara manual. Juga, setelah dikuasai, itu membuat menu menjadi hal yang menyenangkan untuk diedit.

Fuzz ringan
sumber
2
Ini akan menjadi cara untuk pergi, cukup memunculkan layar menu nav di admin dan menambahkan kelas ke item pertama dan terakhir. Tentu saja jika pengguna memindahkan item menu ini, kelas-kelas harus ditugaskan ulang, tetapi ini saya rasa adalah jawaban yang paling valid / terbaik (karena tidak ada pengkodean yang terlibat).
t31os
5

Jika Anda memiliki menu bersarang

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');

Saya suka kesederhanaan jawaban Ismaelj, tetapi harus ada lebih banyak jika Anda ingin kelas sub-menu.

brent
sumber
2

Jika Anda tidak memerlukan dukungan untuk IE8 atau lebih rendah, jangan lupa bahwa Anda juga dapat menggunakan CSS murni:

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

Dukungan browser jQuery bahkan lebih baik, tetapi sepertinya Anda mencoba menghindarinya.

mrwweb
sumber
Saya menggunakan itu, karena anak terakhir sekarang didukung oleh IE 9 juga, dan saya tidak peduli lagi tentang 8, 7 ..
Alex
2

Berikut adalah beberapa kode yang lebih baik untuk menambahkan kelas item menu pertama dan terakhir yang mencakup dukungan untuk submenu bersarang.

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;

}

Anda dapat menemukan intinya di sini dan tutorial terkait di sini .

Thomas
sumber
0

Bagaimana tentang:

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

dan mungkin beberapa http://selectivizr.com/

saya
sumber
Ini akan menjadi yang pertama <li>dalam setiap daftar yang tidak diurutkan di situs, bukan hanya di menu. Ini juga secara substansial identik dengan jawaban ini wordpress.stackexchange.com/a/63128/9844
mrwweb
Maaf, kode semu.
Saya
0

CSS murni, bekerja untuk saya. Ini juga akan bekerja dengan submenu

ul.nav>li:last-of-type a
Dan Green-Leipciger
sumber
hanya di IE9 ke atas, yang mengesampingkan hampir semua yang saya lakukan :)
Milo