/ Сайтостроение / Scripts & jquery / Автоматическое меню, оглавление, измененное состояние меню

Автоматическое меню, оглавление, измененное состояние меню

HIT

18.12.2016

1067

Меню с изменяемым состоянием может применяться для различных задач, в т.ч. для меню лэндинга или для оглавления длинной страницы. Такое меню состоит из хэш-ссылок для перемещения по самой странице. Смысл в том, чтобы при перемещении по различным блокам соответствующий пункт меню изменялся.

Меню лэндинга

Верста максимально проста и коротка

<ul id="land-menu">
<li class="punkt-action"><a href="#">Главная</a></li>
<li><a href="#features-block">Преимущества</a></li>
<li><a href="#testing">Двигающиеся объекты</a></li>
<li><a href="#forma">Forma</a></li>
<li><a href="#promo">Man is the cruelest animal</a></li>
</ul>

Ссылка на главный блок упрощена — #

CSS

/* Меню лэндинга */

#land-menu {position: fixed; z-index: 100; top: 40%; left: 25px;}

#land-menu li {list-style: none;}

#land-menu li a {
   float: left;
   background-color: rgba(0, 0, 0, 0.8);
   margin-bottom: 5px;
   padding: 5px 15px;
   border-radius: 3px;
   color: #fff;
   width: 100%; /* пункты одинаковой ширины */
   position: relative;
}

#land-menu li a:hover {background-color: #000;}

/* #land-menu .punkt-action a {background-color: #ff5a00 !important;}  выделение цветом фона текста */

/* точка */

#land-menu a:before {
    content: " ";
    border-radius: 50%;
    position: absolute;
    z-index: 1;
    height: 4px;
    width: 4px;
    border: 0;
    background: #000;
    left: -10px;
    top: 50%;
    margin: -2px 0 0 -2px;
    -webkit-transition: all .3s ease-in-out;
    -moz-transition: all .3s ease-in-out;
    -o-transition: all .3s ease-in-out;
    transition: all .3s ease-in-out;
}

#land-menu li a:hover:before {
    height: 12px;
    width: 12px;
    margin: -6px 0 0 -6px;
    border-radius: 100%;	
}	

#land-menu .punkt-action a:before {
    background-color: #ff5a00 !important;
    height: 12px;
    width: 12px;
    margin: -6px 0 0 -6px;
    border-radius: 100%;	
}

Скрипт (не нужно подключать никаких библиотек, как со scrollspy)

$(document).ready(function() {

// Cache selectors
var lastId,
  topMenu = $("#land-menu"),
  topMenuHeight = topMenu.outerHeight() + 15,
  // All list items
  menuItems = topMenu.find("a"),
  // Anchors corresponding to menu items
  scrollItems = menuItems.map(function() {
    var item = $($(this).attr("href"));
    if (item.length) {
      return item;
    }
  });

// Bind click handler to menu items
// so we can get a fancy scroll animation
menuItems.click(function(e) {
  var href = $(this).attr("href"),
    offsetTop = href === "#" ? 0 : $(href).offset().top - topMenuHeight + 1;
  $('html, body').stop().animate({
    scrollTop: offsetTop
  }, 300);
  e.preventDefault();
});

// Bind to scroll
$(window).scroll(function() {
  // Get container scroll position
  var fromTop = $(this).scrollTop() + topMenuHeight;

  // Get id of current scroll item
  var cur = scrollItems.map(function() {
    if ($(this).offset().top < fromTop)
      return this;
  });
  // Get the id of the current element
  cur = cur[cur.length - 1];
  var id = cur && cur.length ? cur[0].id : "";

  if (lastId !== id) {
    lastId = id;
    // Set/remove active class
    menuItems
      .parent().removeClass("punkt-action")
      .end().filter("[href='#" + id + "']").parent().addClass("punkt-action");
  }
});


});

Не корректно работает с плавным скроллингом. т.к. скрипт сам делает этот функционал!

Если мы делаем слайды во всю высоту экрана (min-height: 100vh;), то для нормального скроллинга нужно убрать компенсацию высоты из этой строки:

offsetTop = href === '#' ? 0 : jQuery(href).offset().top - topMenuHeight + 1;

Динамическое формирование меню

Для универсальности данного функционала, необходим алгоритм динамического формирования меню. Либо по заголовкам h2, либо по блокам с id содержащихся в определенном контейнере.

Для того чтобы отследить блоки лэндинга и сформировать из них меню нужно следующее:

1. Обвести все блоки лэндинга общим блоком с id=»landing».
2. Каждому блоку лэндинга задать уникальный id и атрибут title, в котором будет прописан пункт меню
3. Создаем после открывающего тэга body div id=»land-menu-container»
4. Включаем скрипт, обязательно перед предыдущим скриптом

/* Автоматическое создание меню лэндинга */

$(document).ready(function() {

 var ToC = "<ul id='land-menu'>";
 
 var newLine, el, title, link;
 
 $("#landing > div").each(function() {
 el = $(this);
 title = el.attr("title");
 link = "#" + el.attr("id");
 newLine =
 "<li>" +
 "<a href='" + link + "'>" +
 title +
 "</a>" +
 "</li>";
 ToC += newLine;
 });
 
 ToC +=
 "</ul>";
 
 $("#land-menu-container").prepend(ToC);
 
 $("#land-menu > li:first-child").addClass("punkt-action");

});

Рекомендация: заменить атрибут title на name. Потому что title при наведении выводит текст, а name нет.

Автоматическое оглавление

Данный метод jquery (из предыдущего пункта) мы можем применить для автоматического построения оглавления.

Первым делом отыскиваем все h2 в области #post-content и присваиваем им автоматические id

$(document).ready(function() {	 
	 
	var num=1; 
	
	$("#post-content h2").each(function() {
        $(this).attr('id', 'title-' + num);
		num++;
    });	 
	 
});

А после этого, формируем оглавление

$(document).ready(function() {

var ToC =
"<nav role='navigation' class='table-of-contents'>" +
"<ul>";

var newLine, el, title, link;

$("#post-content h2").each(function() {
el = $(this);
title = el.text();
link = "#" + el.attr("id");
newLine =
"<li>" +
"<a href='" + link + "'>" +
title +
"</a>" +
"</li>";
ToC += newLine;
});

ToC +=

"</ul>" +
"</nav>";

$("#all-titles").prepend(ToC);

});

Можно комбинировать с плавным скроллингом

Где-то в верстке необходимо создать div с id=»all-titles». Наилучший вариант вывести его в sitebar напрямую, либо в виде виджета. При этом сайтбар лучше сделать фиксированным, чтоб навигация по содержанию всегда была под рукой.

Проверка: есть ли h2

Можно запрограммировать чтоб блок Оглавление автоматически выводился перед статьей либо в области виджетов. При этом, данный блок можно оформить и задать ему заголовок — Содержание статьи. Но нужна проверка — выводить оглавление только в том случае если есть h2 заголовки. Для этого оборачиваем весь прошлый скрипт (кроме $(document).ready(function()) конструкцией проверки:

if( $('#post-content h2').length ) {
основной скрипт оглавления
}

А в абзац var ToC = добавить после строки nav еще одну строку:

"<p>Оглавление</p>" +

Данное оглавление не отображается в исходном коде, для SEO это не очень хорошо. Подумать как сделать чтоб оглавление выводилось в исходном коде.

Тэги:

Поделится информацией с друзьями

  • Похожие записи
  • Комментарии
  • Вложения
Меню для мобильной версии

Меню для мобильной версии

Делаем простую адаптацию меню под мобильную версию, превращая в иконку, при нажатии на которую меню раскрывается. Трансформируем меню в иконку Стандартный код вывода меню <nav id="topmenu" role="navigation"> <?php wp_nav_menu( array( Читать далее »

/
Фиксированное меню 2.0

Фиксированное меню 2.0

Продолжая работать над совершенствованием фиксированного меню, нашел следующее решение. Верстка фиксируемого блока <div id="stick_menu" class="default"> В отличие от предыдущей версии меню, перед блоком ставить ничего не нужно. Стили для фиксированного Читать далее »

Манипуляции с меню

Манипуляции с меню

Проводим различные эксперименты и манипуляции с меню. Добавить пункт функцией Добавляем произвольный пункт меню при помощи функции (!данный пример будет работать только с установленным плагином woocommerce) add_filter( 'wp_nav_menu_items', 'my_account_loginout_link', 10, Читать далее »

Добавить комментарий

Пока нет комментариев. Будь первым!

Автоматическое меню, оглавление, измененное состояние меню
Сортировка категорий
Рекомендации для васСортировка категорийOpttour.ru
Спасибо! Наш менеджер свяжется с Вами в течении 5 минут.