Всех категорически приветствую!
Предисловие
Возможно многие, как и я, задавались вопросом «Как писать код правильно?». И каждый день приходя на работу, оглядываясь по сторонам, я понимаю, что даже в том месте, где много людей, работающих с кодом, помощи в данном вопросе просить не у кого. Каждый занят своим делом, решая задачи, любым доступным способом. И сегодня, придя на работу, я так же столкнулся с задачей, довольно простой задачей. Нужно зафиксировать верхнее меню при прокрутке сайта. И как то глубоко впав в себя, пронеслись мысли — «Готовое решение», «JQ плагин», «зачем целый плагин, можно ведь самому, пару строк ведь», «зачем изобретать велосипед», «а как этот велосипед изобрели», «найти плагин, заглянуть в исходники», «но ведь первый раз кто то писал не заглядывая — некуда ведь», «курица или яйцо», «брр… а как они к этому пришли, надо самому попробовать». И тут я открыл редактор и начал пробовать.
Задача
При прокрутке страницы сделать, нижнюю часть шапки, где находится навигация, фиксированной. Другими словами «плавающее меню».
Решение
И здесь, мне почему то, пришла в голову мысль о том, что сначала, я просто обязан написать псевдокод:
/*
переменные:
верхняя часть меню,
нижняя часть меню,
высота верхней части,
высота нижней части, (пока хватит)
скролл окна браузера (функция для фиксации меню);
функция для фиксации меню() {
если (скролл >= высота верхней части меню && !нижняя часть меню имеет класс("фиксированное меню")) {
нижняя часть меню.добавить класс("фиксированное меню");
}
если (скролл < высота верхней части меню && нижняя часть меню имеет класс("фиксированное меню")) {
нижняя часть меню.удалить класс("фиксированное меню");
}
}
*/
Будем просто добавлять CSS класс элементу, где будут прописаны стили:
фиксированное меню {
position: fixed;
width: 100%;
top: 0;
left: 0;
}
Посмотрел, и понял, что стоит это дело перевести к более реальному виду, перепишем наш псевдокод, на более реальный, но все еще псевдокод:
/*
var topItemMenu,
bottomItemMenu,
topItemMenu.height(),
bottomItemMenu.height(),
window.scroll(fixedUnfixedMenu);
fixedUnfixedMenu() {
if (пересекаем границу && topItemMenu нет класса("fixedNav")) {
addClass("fixedNav");
}
if (пересекаем границу && topItemMenu есть класс("fixedNav")) {
removeClass("fixedNav");
}
}
*/
Дальше в голове диалог:
"-Что видишь?"
"-можем addClass и removeClass заменить на одно действие toggleClass"
"-И все?"
"-В условном операторе первое условие одинаковое"
"-Так, что делаем?"
"-Можно сделать общее и внутрь поместить… хотя… не будем торопиться и объединим условие"
(далее буду рассматривать только функцию)
/*
fixedUnfixedMenu() {
if ((пересекаем границу && topItemMenu нет класса("fixedNav")) || (пересекаем границу && topItemMenu есть класс("fixedNav"))) {
toggleClass("fixedNav");
}
}
*/
И здесь мы наблюдаем, что мы использовали факт, совершение одного и того же действия, и извлекли из этого пользу. Но условие то какое получилось — «и то и это или вон то, а там если..».
Нет, нужно точно использовать факт того, что первое условие одинаковое… Вынесем его, а внутрь поместим остальное. Как то так:
/*
fixedUnfixedMenu() {
if (пересекаем границу) {
if (topItemMenu нет класса("fixedNav")) {
toggleClass("fixedNav");
}
if (topItemMenu есть класс("fixedNav")) {
toggleClass("fixedNav");
}
}
}
*/
Ну вот, теперь абсурд на лицо, убираем лишние условные операторы и получаем:
/*
fixedUnfixedMenu() {
if (пересекаем границу) {
toggleClass("fixedNav");
}
}
*/
Теперь можем написать наш код:
fixedUnfixedMenu() {
if (!crossed) return;
toggleClass("fixed");
}
Осталось написать функцию, которая будет определять, пересечение границы, и возможно в сумме это будет одно и тоже, но одну функцию мы сократили до максимума, и она выполняет свое действие, которое в ней подразумевалось. Из этого дня, я сделал вывод: прежде чем начать что то реализовывать, стоит начеркать это псевдокодом, он даст вам лучшее представление о том, что вы хотите реализовать.
Автор: Лунтик