การเพิ่มคลาส CSS แรก / สุดท้ายไปยังเมนู


15

เป็นไปได้หรือไม่หากไม่มี javascript hacks แบบนี้:

<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
มีอะไรผิดปกติกับการใช้จาวาสคริปต์? มันเป็นฟังก์ชั่นหลักที่พวกเขามีไว้เพื่อ? หรืออาจถูกมองว่าเป็นการพัฒนาที่ก้าวหน้า?
Mild Fuzz

คำตอบ:


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
ดีและเรียบง่าย ฉันชอบมัน!
Jonathan Wold

ฉันเห็นว่ารหัสนี้ใช้ได้กับเมนูนำทางที่กำหนดเอง (ฉันเห็นมันทำงานในวิดเจ็ตเมนูที่กำหนดเอง) แต่มันไม่ทำงานในเมนูเดียวกับที่ใช้ในแถบนำทางหลัก (ทดสอบใน Twenty Eleven) มันควรจะเป็นอย่างไร หรือว่าจะเป็นรหัสอื่น หรือเพียงแค่ตัวกรองอื่น ขอบคุณ!
Evan Mattson

2
สิ่งนี้จะใช้งานได้สำหรับเมนูระดับเดียว แต่อาจไม่เหมาะกับเมนูที่ซับซ้อนมากขึ้นเพราะ ณ จุดนี้มันมีรายการทั้งหมดไม่ใช่รายการระดับบนสุด
Rarst

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

เรียนรู้เพิ่มเติมเกี่ยวกับMenus API ใหม่ใน wordpress 3 คุณสามารถให้องค์ประกอบใด ๆ ที่เป็นคลาสของตัวเองได้ นอกจากนี้เมื่อเชี่ยวชาญก็ทำให้เมนูเป็นเรื่องของความสุขในการแก้ไข


2
นี่จะเป็นวิธีที่จะไปเพียงแค่เปิดหน้าจอเมนู nav ในผู้ดูแลระบบและเพิ่มคลาสในรายการแรกและสุดท้าย แน่นอนถ้าผู้ใช้ย้ายรายการเมนูเหล่านี้คลาสจะต้องถูกกำหนดใหม่ แต่ฉันรู้สึกว่านี่เป็นคำตอบที่ถูกต้องที่สุด / ดีที่สุด (เพราะไม่มีการเข้ารหัสที่เกี่ยวข้อง)
t31os

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

ฉันชอบความเรียบง่ายของคำตอบของ Ismaelj แต่จะต้องมีมากขึ้นถ้าคุณต้องการเรียนเมนูย่อย


2

หากคุณไม่ต้องการการสนับสนุน IE8 หรือต่ำกว่าอย่าลืมว่าคุณสามารถใช้ CSS บริสุทธิ์ได้ด้วย:

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

การสนับสนุนเบราว์เซอร์ jQuery ดียิ่งขึ้น แต่ดูเหมือนว่าคุณกำลังพยายามหลีกเลี่ยงปัญหานั้น


ฉันใช้สิ่งนี้เพราะ IE 9 ก็รองรับเด็กคนสุดท้ายแล้วและฉันก็ไม่สนใจอีกต่อไปแล้วเช่น 8, 7 ..
อเล็กซ์

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

ขออภัยรหัสหลอก
am

0

CSS เพียวใช้งานได้สำหรับฉัน นี้จะทำงานกับเมนูย่อยด้วย

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

เฉพาะใน IE9 ขึ้นซึ่งกฎออกสำหรับทุกอย่างสวยมากฉันทำ :)
ไมโล
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.