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

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

HIT

18.12.2016

2937

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

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

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

<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 это не очень хорошо. Подумать как сделать чтоб оглавление выводилось в исходном коде.

Тэги:

[site-socialshare]
  • Похожие записи
  • Комментарии
  • Вложения
Добавление кнопки more при узком меню

Добавление кнопки more при узком меню

Если пункты меню не вмещаются в его заданную ширину, то их можно спрятать в кнопку more. Вариант 1 Работает в целом неплохо. Но если именно придираться, то при изменении размера Читать далее »

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

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

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

Scrollspy jquery

Scrollspy jquery

Скрипт scrollspy jquery отслеживающий положение скрола, в котором мы находится в данный момент. Чаще всего это используется для изменения состояния меню, изменение фона, а также для каких-либо событий. Подключение скрипта Читать далее »

/

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

Notice: Функция WP_Styles::add вызвана неправильно. Стиль с дескриптором "editor-buttons" был поставлен в очередь с незарегистрированными зависимостями: dashicons. Дополнительную информацию можно найти на странице «Отладка в WordPress». (Это сообщение было добавлено в версии 6.9.1.) in /home/t/tiberi6w/opttour.ru/public_html/wp-includes/functions.php on line 6260

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

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