Scriptify.ru

В ходе создания этого сайта возникла идея создания навигации по статье, или, как это еще называется на английском, table of contents. Естественно, каждый раз прописывать навигацию вручную утомительно. Для того, чтобы она генерировалась автоматически, существуют решения как на чистом javascript, так и на JQuery. Здесь мы рассмотрим решение в виде готового плагина.

Требования к задаче

Для реализации идеи условия были такие - это генерация содержимого по заголовкам h2, подсвечивание активного пункта меню и плавная прокрутка к заголовку. С этими задачами хорошо справляется плагин JQuery TOC. Однако для этого нужно немного отредактировать код плагина, что мы и рассмотрим ниже. Пример использования можно посмотреть на странице проекта.

JQuery TOC

JQuery TOC

Использование плагина

Использование плагина предельно простое. Для этого указываем селектор, в котором будет генерироваться навигация, и записываем необходимые настройки. Обратите внимание, что в качестве свойства smoothScrolling указывается функция, а не оператор true/false, как это указано на странице проекта:

$('#toc').toc({
     // заголовки, которые будут использоваться в навигации
    'selectors': 'h1,h2,h3',
     // элемент, в котором будут искаться заголовки
    'container': 'body',
     // функция плавной прокрутки до элемента
    'smoothScrolling': function(target, options) {
        $(target).smoothScroller({offset: options.scrollToOffset});
    },
     // префикс для якорей
    'prefix': 'toc',
     // функция, которая будет выполняться при подсветке элемента
    'onHighlight': function(el) {},
     // подветка при прокрутке
    'highlightOnScroll': true,
     // максимальный отступ для подсветки 
    'highlightOffset': 100,
    // метод для формирования якорей
    'anchorName': function(i, heading, prefix) { 
        return prefix+i;
    },
    // метод для формирования имен заголовков в навигации
    'headerText': function(i, heading, $heading) { 
        return $heading.text();
    },
    // метод для формирования css класса элемента навигации
    'itemClass': function(i, heading, $heading, prefix) { 
        return $heading[0].tagName.toLowerCase();
    }
});

Доработка плагина

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

var a = $('<a/>')
    .text(opts.headerText(i, heading, $h))
    .attr('href', '#' + anchorName)
    .bind('click', function (e) {
        // эту код убираем
        //$(window).unbind('scroll', highlightOnScroll);
        scrollTo(e, function () {
            $(window).bind('scroll', highlightOnScroll);
        });
        el.trigger('selected', $(this).attr('href'));
    });

Как видно, здесь при нажатии на ссылку открепляется обработчик события highlightOnScroll.

Вторая ошибка заключается в том, что плавная прокрутка изначально работает некорректно. Иногда, вместо того, чтобы пролистать вниз, она будет листать вверх. Проблема заключается в следующем коде:

$(options.scrollEl).animate({
      scrollTop: el.offset().top - $(options.scrollEl).offset().top - options.offset
    },
    ...
});

Дело в том, что здесь $(options.scrollEl).offset().top учитывает расстояние от элемента до начала страницы, а должен учитывать текующую прокрутку. Исправленный код выглядит так:

// текущая прокрутка страницы
var scrollOffset = window.pageYOffset;

$(options.scrollEl).animate({
      scrollTop: el.offset().top + scrollOffset - options.offset
    },
    ...
});

Теперь все должно работать корректно. Работающий вариант можно просмотреть здесь

Содержание статьи