29.07.2015, 18:01
|
Новичок на форуме
|
|
Регистрация: 29.07.2015
Сообщений: 6
|
|
Скроллинг между якорями + отступ на ширину статического меню вверху
Здравствуйте.
Помогите править js код.
Имеется одностраничный сайт и пункты меню являются ссылками на различные места страницы. При прокрутке страницы активные пункты меню сменяются в зависимости от положения на странице.
Меню статически закреплено при прокрутке вверху и имеет ширину 40 пикселей.
1. Как сделать так, чтобы страница при клике по пункту меню останавливалась ниже на величину его ширины?
2. Как сделать переключение активных пунктов меню не в тот момент, когда граница соответствующего блока достигает верхнего окна браузера, а, когда она чуть ниже, на величину меню?
Исходник брал на сайте
http://stanhub.com/sticky-header-cha...l-with-jquery/
Буду очень благодарен, если кто-то поможет править код.
|
|
29.07.2015, 19:11
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,989
|
|
А если такой?
$(function() {
//инициализация меню
var lastId, //текущий выбранный
topMenu = $("#menu"), //селектор меню
topMenuHeight = topMenu.outerHeight()+1, //высота меню + коррекция при необходимости
menuItems = topMenu.find("a"), //коллекция ссылок меню
scrollItems = menuItems.map(function() { //якоря
var item = $($(this).attr("href"));
if(item.length) return item;
});
//прокрутка к выбранному в меню
menuItems.click(function(e) {
var href = $(this).attr("href"),
offsetTop = href === "#" ? 0 : $(href).offset().top-topMenuHeight+15; //прокручиваем якорь за минусом высоты меню плюс коррекция при необходимости
$('body,html').stop().animate({
scrollTop: offsetTop
}, 1500, 'easeOutExpo', function() {
history.pushState(null, null, href); //изменили адресную строку
});
e.preventDefault();
});
//слежение меню за прокруткой страницы
$(window).scroll(function(){
var fromTop = $(this).scrollTop()+topMenuHeight;
var cur = scrollItems.map(function() {
if($(this).offset().top < fromTop) return this;
});
//изменение стиля элементов меню при скролле
cur = cur[cur.length-1];
var id = cur && cur.length ? cur[0].id : "";
if(/\d/g.exec(id)) id = id.split('-',1)[0];
if(lastId !== id) {
lastId = id;
menuItems.parent()
.removeClass("current")
.end()
.filter("[href=#"+id+"]")
.parent()
.addClass("current");
}
});
});
|
|
30.07.2015, 12:36
|
Новичок на форуме
|
|
Регистрация: 29.07.2015
Сообщений: 6
|
|
Спасибо! Будьте добры, дайте ссылку на демо этого скрипта. В программировании я не силён, попробую переделать с примера.
Мой первый вариант я сделал под свой сайт, но он конфликтует с каруселью Bootstrap (при нажатии на стрелки карусели происходит вертикальная прокрутка страницы)
Мне нужно либо убрать конфликт первого скрипта или приспосабливать этот вариант скрипта для себя.
|
|
30.07.2015, 13:02
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,989
|
|
Нет ссылки, это код не мой, а некогда правил по заказу одностраничник, это код из него, я лишь внес небольшие косметические изменения. Единственное, это посмотреть не сохранилось ли в архивах проекта все остальное, кроме js файла к нему, чтобы взять html и стили от него. Но сейчас нет времени ковыряться в архиве, как и править чей-то код. )
Этот код существует еще у меня только лишь потому, что не был вычищен своевременно из черновиков.
|
|
30.07.2015, 13:16
|
Новичок на форуме
|
|
Регистрация: 29.07.2015
Сообщений: 6
|
|
Методом проб и ошибок я правил скрипт, теперь всё работает.
Единственное, что не могу исправить, это последний кусочек кода, который присваивает класс current не ссылке, а тегу li в который она вложена. Помогите разобраться с этим.
//изменение стиля элементов меню при скролле
cur = cur[cur.length-1];
var id = cur && cur.length ? cur[0].id : "";
if(/\d/g.exec(id)) id = id.split('-',1)[0];
if(lastId !== id) {
lastId = id;
menuItems.parent()
.removeClass("current")
.end()
.filter("[href=#"+id+"]")
.parent()
.addClass("current");
}
И ещё небольшой момент: я сделал плавную прокрутку страницы от пункта к пункту и при прокрутке через несколько пунктов меню (по кликам в меню), стиль current поочерёдно присваивается всем li до последнего. Как сделать так, чтобы этого не происходило, а класс current сразу присваивался сразу конечной ссылке?
Последний раз редактировалось infostream, 30.07.2015 в 13:32.
|
|
30.07.2015, 14:13
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,989
|
|
Давно это было, я уж не помню html-структуру кода меню, а класс "current" определят стиль не конечной ссылке, а текущей. У него стиль текущей - это подчеркивание кнопки меню нижним бордюром в несколько px, и что-то там он связанное с изображением, стрелка была вроде бы, может поэтому и .parent() ... .parent().... не помню.
Суть этого участка кода, это удалить у всех кнопок меню стиль "current" , и назначить его выбранной (текущей, а также текущей при скролле) кнопке, которая определяется фильтром по селектору имеющему в ссылке ID текущего (и текущий при скролле) якоря. А текущий определяется по массиву коллекции якорей/ссылок ранее определенной.
Под свою html-стркутуру меню это и нужно будет подправить.
|
|
30.07.2015, 14:25
|
Новичок на форуме
|
|
Регистрация: 29.07.2015
Сообщений: 6
|
|
Сейчас скрипт делает так:
<li class="active"><a href="#link">Ссылка</a></li>
А нужно так:
<li><a href="#link" class="active">Ссылка</a></li>
|
|
30.07.2015, 14:36
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,989
|
|
Убрать строку 11 в этом участке кода.
|
|
30.07.2015, 15:09
|
Новичок на форуме
|
|
Регистрация: 29.07.2015
Сообщений: 6
|
|
Сообщение от laimas
|
Убрать строку 11 в этом участке кода.
|
Тогда все ссылки в меню остаются активными всегда и не выключаются уже никогда.
|
|
30.07.2015, 15:37
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,989
|
|
Ну тогда так, в вашем случае по идее должно быть:
menuItems //коллекция ссылок
.closest('ul') //получить родительский элемент меню,
.find('>li') //получить меню, я так понимаю, что есть кнопки с раскрываемым списком?
.removeClass("current") //удалить стиль активной кнопки
.filter("[href=#"+id+"]") //получить текущую кнопку
.addClass("current"); //и сделать ее активной
|
|
|
|