Thêm các lớp CSS đầu tiên / cuối cùng vào các menu


15

điều đó là có thể, mà không cần hack javascript? như thế này:

<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
Có gì sai khi sử dụng javascript? đó là chức năng cốt lõi mà họ dành cho? Hoặc nó có thể được coi là một sự tăng cường tiến bộ?
Fuzz nhẹ

Câu trả lời:


14

Một cách tiếp cận tốt hơn và đơn giản hơn:

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
Đẹp và đơn giản. Tôi thích nó!
Jonathan Wold

Tôi thấy mã này hoạt động cho các menu điều hướng tùy chỉnh (tôi thấy nó hoạt động trong tiện ích menu tùy chỉnh), nhưng nó không hoạt động trong cùng một menu đang được sử dụng trong thanh điều hướng chính (được thử nghiệm trong Twenty Eleven). Nó phải được? hoặc đó sẽ là mã khác nhau? hay chỉ là một bộ lọc khác nhau? Cảm ơn!
Evan Mattson

2
Điều này sẽ hoạt động cho menu cấp đơn, nhưng có thể không phức tạp hơn vì tại thời điểm này, nó là mảng với tất cả các mục, không phải là cấp cao nhất.
Hết

6

Đây là đoạn mã thô đảm nhiệm việc sửa đổi đầu ra menu và thêm lớp đầu tiên / cuối cùng vào lớp đầu tiên và lớp cuối cùng (bên ngoài ulkhông được áp dụng ở giai đoạn này vì vậy không được tính). Lưu ý - yêu cầu PHP5 chostrripos()

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

Tôi hơi bế tắc với cách làm cho nó xử lý các danh sách lồng nhau, nhưng nó sẽ giúp bạn bắt đầu ít nhất.


6

Đây là một chức năng chỉ thêm các lớp đầu tiên / cuối cùng vào các mục menu cha. Đối với hầu hết các kiểu CSS, đây là tất cả những gì cần thiết.

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
Chính xác những gì tôi đang tìm kiếm. cảm ơn. wp_nav_menu thật đáng ngạc nhiên không làm điều này một cách tự động
vào

Tôi đồng ý. Tôi tin rằng đã có một yêu cầu tính năng trong trình sửa lỗi Wordpress trong một thời gian, nhưng không có gì đến từ nó. Ít nhất là các bộ lọc thích hợp tồn tại để chúng ta có thể thêm các lớp này;).
Chaoix

1
Cảm ơn. Đã tìm kiếm các quầy, có thể được sử dụng trong menu walker. câu trả lời của bạn cho phép điều này. Chỉ cần thêm $ item-> number = $ i; và có nó trong walker. Cảm ơn!!!
BasTaller

5

Tìm hiểu thêm về API Menu mới trong wordpress 3. Bạn có thể cung cấp bất kỳ phần tử nào theo cách thủ công. Ngoài ra, một khi thành thạo, nó làm cho các menu trở thành một niềm vui để chỉnh sửa.


2
Đây sẽ là cách để đi, chỉ cần hiển thị màn hình menu điều hướng trong quản trị viên và thêm một lớp vào các mục đầu tiên và cuối cùng. Tất nhiên, nếu người dùng di chuyển các mục menu này, các lớp sẽ phải được chỉ định lại, nhưng điều này tôi cảm thấy là câu trả lời hợp lệ / tốt nhất (vì không có mã hóa liên quan).
t31os

5

Nếu bạn có các menu lồng nhau

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

Tôi thích sự đơn giản trong câu trả lời của Ismaelj, nhưng cần phải có nhiều hơn nếu bạn muốn các lớp menu phụ.


2

Nếu bạn không cần hỗ trợ cho IE8 hoặc thấp hơn, đừng quên rằng bạn cũng có thể sử dụng CSS thuần túy:

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

Hỗ trợ trình duyệt jQuery thậm chí còn tốt hơn, nhưng có vẻ như bạn đang cố tránh điều đó.


Tôi đang sử dụng điều đó, bởi vì đứa con cuối cùng cũng được IE 9 hỗ trợ và tôi không quan tâm nhiều đến 8, 7 ..
Alex

2

Dưới đây là một số mã tốt hơn để thêm các lớp mục menu đầu tiên và cuối cùng bao gồm hỗ trợ cho các menu con lồng nhau.

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;

}

Bạn có thể tìm thấy ý chính ở đây và hướng dẫn liên quan ở đây .



0

CSS thuần túy, hoạt động với tôi. Điều này cũng sẽ làm việc với các menu con

ul.nav>li:last-of-type a

chỉ trong IE9 trở lên, quy định này cho hầu hết mọi thứ tôi làm :)
Milo
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.