Добавление первых/последних классов CSS в меню
Возможно ли это без взломов 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>
9 answers
Лучший и более простой подход:
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');
Вот примерный фрагмент, который заботится об изменении вывода меню и добавлении первого/последнего в первый и последний класс (внешний 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;
}
Я немного зациклен на том, как заставить его обрабатывать вложенные списки, но это должно помочь вам, по крайней мере, начать.
Здесь есть функция только для добавления первого/последнего классов в родительские пункты меню. Для большинства стилей 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 );
Узнайте больше о новом API меню в wordpress 3. Вы можете вручную присвоить любому элементу его собственный класс. Кроме того, после освоения он превращает редактирование меню в удовольствие.
Если у вас есть вложенные меню
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');
Мне нравится простота ответа Исмаэля, но должно быть больше, если вы хотите классы подменю.
Если вам не нужна поддержка IE8 или ниже, не забывайте, что вы также можете использовать чистый CSS:
.my_menu > :first-child,
.my_menu > :last-child {
/* some styles */
}
Поддержка браузера jQuery еще лучше, но похоже, что вы пытаетесь этого избежать.
Вот лучший код для добавления первого и последнего классов пунктов меню, который включает поддержку вложенных подменю.
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;
}
Как насчет:
ul li:last-child{
// do something with the last li
}
И, возможно, некоторые http://selectivizr.com/
Чистый CSS, работает для меня. Это также будет работать с подменю
ul.nav>li:last-of-type a