В шаблоне работают два сборщика GULP и WEBPACK, каждый делает то в чем он хорош. Есть возможность работать в режимах разработки и продакшена. Режим разработки выполняет только необходимые для работы задачи, а продакшн обеспечивает оптимизацию файлов, конвертацию и прочие необходимые действия. Таким образом повышается скорость работы сборщиков. Добавлю что тип работы указанный в package.json равен module
GULP играет роль вспомогательного сборщика и выполняет следующие задачи:
WEBPACK играет основную роль сборщика HTML/SCSS/JS файлов и выполняет следующие задачи:
HTML файлы можно собирать из частей благодаря шаблонизатору FileInclude. То есть мы можем вынести отдельные части кода, например header и footer, в отдельные файлы и подключать их для всех страниц сайта. Таким образом, при необходимости внести изменения, нам достаточно редактировать только один подключаемый файл. FileInclude позволяет передавать переменные со значением в подключаемый файл. Например мы можем передать свой заголовок (title) для каждой страницы.
Если вам не хватает возможностей FileInclude вы можете использовать шаблонизатор PUG и все его возможности. Сборка сама обработает PUG-файлы и преобразует в HTML
В шаблоне используется препроцессор SASS в синтаксисе SCSS. Благодаря этому, есть возможность порадовать вас отличными наработками:
Отмечу, что поскольку JS файлы собирает WEBPACK, то у нас появляется возможность использовать подключение ES6 модулей. Таким образом в результат попадает только используемый функционал. Для добавления той или иной возможности, как правило, достаточно раскомментировать строку. Также каждый модуль удобно управляется и настраивается с помощью дата атрибутов в HTML/PUG файлах, а сам код подробно прокомментирован.
Модуль параллакса мышью. Элементы плавно реагируют на движение мышью Система глобального логгинга (Full Logging System или FLS)
Я подумал, почему бы не научить функционал ЧФ общаться (отчитываться) о своей работе пользователю в консоли?! Это очень удобно в процессе разработки и имеет обучающий эффект.
Первым делом следует разархивировать zip-архив в вашу папку проекта. Следите за тем, чтобы сама папка и её родительские папки не содержали в названии кириллицу, пробелы, символы # и !
Если вы до этого момента не пользовались сборщиками GULP, WEBPACK и пакетным менеджером NPM, следует скачать и установить Node.js. Качайте версию рекомендованную для большинства.
Далее, открываем терминал в этой папке проекта. Терминал может быть встроен или открыт отдельно от редактора. Рекомендую использовать терминал GIT Bash.
Если вы до этого момента не пользовались сборщиком GULP введите в терминал команду npm npm i gulp-cli -g это установит GULP в систему глобально.
После завершения установки GULP введите команду npm i
В процессе установки в терминале могут возникать сообщение с пометкой WARN на желтом фоне. Эти сообщения можно игнорировать. Но, если вы получаете сообщение ERR! красным цветом — это критическая ошибка и её нужно исправлять.
Часто может возникнуть ошибка зависимостей устанавливаемых пакетов (плагинов), и в NPM выше 7й версии это приводит к критической ошибке и остановке инсталляции
Чтобы решить проблему выполните команду npm i --legacy-peer-deps, это запустит процесс установки игнорируя подобные несовместимости.
Помните — версии NodeJS и Python в вашей системе должны быть свежих версий.
После успешной установки, у вас появится папка node_modules и файл package-lock.json
Установка завершена Подробнее про архитектуру папок и файлов ЧФ мы поговорим в следующей главе, а пока продолжаем подготовку к работе
Ручное создание SVG спрайта. Команда запуска npm run sprite Конвертация шрифтов с принудительной перезаписью файла стилей. Команда запуска npm run fonts
В режиме разработчика выполняются только необходимые для процесса разработки задачи:
В режиме продакшена выполняется финализация проекта, а именно:
Итак, давайте же запустим наш шаблон в режиме разработчика, для этого в терминале выполняем команду npm run dev
После запуска система выполняет все задачи режима разработчика описанные выше. Результатом работы должна стать открытая в браузере страница содержания.
Внимание, страница содержания не обновляется автоматически при её редактировании
Если браузер не запустился, а в терминале видны ошибки (ERR!) убедитесь что:
При ошибке связанной с node-sass запустите команду npm rebuild node-sass
При ошибке связанной с Python запустите команду npm install -g windows-build-tools
Качаем версию 14.15.1 (https://nodejs.org/dist/v14.15.1/), в Zip архиве. Заходим в папку с установленным NodeJS, распаковываем содержимое архива в папку, с заменой файлов. Далее идем сюда «Панель управления» => «Система» => «Дополнительные параметры системы» => «Дополнительно» => «Переменные среды» В Системных переменных «Создать» переменную с именем ‘NODE_SKIP_PLATFORM_CHECK’ и присваиваем ей значение ‘1’.
Перезапускаем систему, и запускаем шаблон согласно инструкции
Для того чтобы наслаждаться возможностями шаблона ЧФ по полной, нам следует произвести некоторые настройки редактора. В качестве примера представлен редактор VS Code
В главе Архитектура шаблона. Файлы и папки вы узнаете что различные части HTML/PUG SCSS файлов находятся на разных уровнях вложенности, что создает определенные неудобства при подключении, например картинок, в процессе разработки.
Неудобства мы не любим поэтому настроим, так называемые, псевдонимы (алиасы) путей к папкам. Для этого нам нужно установить плагин Path Autocomplete. После установки открываем настройки редактора (settings.json), для этого жмем F1 в редакторе и в строке поиска пишем Open Settings и жмем на ссылку Open Settings (JSON).
"path-autocomplete.pathMappings": {
"img": "${folder}/simg", //alias for images
"@scss": "${folder}/src/scss", //alias for scss
"@js": "${folder}/src/js", // alias for js
}
После этого вы смело можете использовать псевдонимы при подключении файлов, например:
Редактор распознает псевдоним и выведет список файлов в указанной папке, а во время сборки система сама поменяет псевдоним на нужный путь!
Сниппеты — это короткие коды которые могут вызывать готовые заготовки кода любого объема. Это колоссально повышает скорость разработки.
Конечно же, я использовал эту супер возможность в своих чертогах. То есть, построение, например, правильной HTML структуры для того или иного JS модуля я добавил в сниппеты.
Отлично, сниппеты ЧФ на борту! В этой документации, а также в коде шаблона вы часто будете встречать подсказки с указанием сниппета.
Для лучшего понимания установки Node.JS, GIT Bash, GULP, настройки псевдонимов посмотрите это видео:
Смотреть видеоВ стартовом шаблоне «Чертоги Фрилансера» v3.0.0 (далее ЧФ) весь процесс подключения локальных и иконочных шрифтов максимально автоматизирован. Исходные файлы шрифтов конвертируются с современные форматы .WOFF и .WOFF2, а также производится запись подключения шрифтов в файл стилей, включая значение font-weight на основе имени файла.
При запуске шаблона в любом режиме, ЧФ проверит, есть ли файлы шрифтов в форматах .TTF и/или .OTF в папке src/fonts.
После конвертации ЧФ проверит наличие файла стилей scss/fonts/fonts.scss и, если его нет, запишет в него конструкции @font-face для всех файлов, включая значение font-weight основанное на имени файла.
Если файл scss/fonts/fonts.scss уже существует, данные не перезапишутся. Это сделано для того, что если нам придется внести изменения в файл scss/fonts/fonts.scss после работы ЧФ, эти изменения не затерлись.
В каких случаях нам потребуется внести изменения в файл scss/fonts/fonts.scss в ручную? Дело в том, что значение font-weight основывается на имени файла шрифта, то есть если файлы называется Roboto-bold, то значение font-weight будет 700. Но если файл будет назван без отделения начертания, например RobotoBold, то адекватное определение не удастся и будет записано значение по умолчанию (400). И вот в этих случаях нам необходимо отредактировать файл указав адекватные значения.
Если мы хотим перезаписать данные в файле scss/fonts/fonts.scss, нам следует его удалить и перезапустить систему, или запустить команду npm run fonts (система сама удалит файл и создаст новый)
При необходимости, вы можете отредактировать созданный и заполненный файл scss/fonts/fonts.scss
При необходимости пересоздать данные в файле стилей scss/fonts/fonts.scss полностью, следует его удалить и перезапустить систему, или запустить команду npm run fonts (система сама удалит файл и создаст новый)
@import url(https://fonts.googleapis.com/css?family=Montserrat:400,500,800&display=swap);
Шрифты подключенные из Google Fonts не должны попадать в папку с результатом (dist), они подгружаются с сервера Google.
Также, стоит отметить, что получить строку для подключения шрифта вы можете и без плагина на сайте Google Fonts.
Файл scss/style.scss является основным файлом стилей в стартовом шаблоне «Чертоги Фрилансера» v3.0.0. (далее ЧФ). Обычно, стили проекта тут не пишут, файл выполняет роль материнского файла куда подключаются отдельные файлы страниц, модулей и т.д.
Тут же подключаются шрифты и расположены основные переменные для настройки семейства и размера шрифта по умолчанию, цветов, адаптивной сетки, корректной работы миксинов и так далее…
После выполнения действий по подключению шрифтов, необходимо указать значения для следующих переменных:
$fontFamily — имя семейства шрифта по умолчанию. Указываем имя основного шрифта в проекте.
$fontFamily: "Montserrat";
$fontSize — размер шрифта по умолчанию. Этой переменной присвоена одна из SCSS-функций шаблона, она выполняет перевод пикселей в REM. Соответственно, в эту функцию следует передать значение размера шрифта по умолчанию в пикселях (только число без px).
$fontSize: rem(14);
$mainColor — цвет шрифта по умолчанию. Указываем цветовой код.
$mainColor: #000;
В ЧФ есть возможность настроить ограничивающий контейнер на работу как с отзывчивой адаптивной версткой, так и с версткой по брейкпоинтам.
Перед началом работ, настраиваем следующие переменные:
$minWidth — минимальная ширина вьюпорта (экрана), поддерживаемая проектом. Обычно это 320px, но, с отмиранием старых устройств, это значение можно менять на любое нужное, указываем только число без px:
$minWidth: 320;
$maxWidth — ширина всего макета (полотна), не путать с шириной ограничивающего контейнера. Как правило, дизайнеры предоставляют макеты шириной 1920 или 1440 пикселей, но это значение может быть любым. Меряем макет и указываем только число без px:
$maxWidth: 1920;
$maxWidthContainer — ширина ограничивающего контейнера. Собственно, это ширина контента в макете дизайна. Меряем макет и указываем только число без px:
$maxWidthContainer: 1170;
Если в макете нет ограничения у контента, то есть контент расположен на всю ширину полотна (с отступами), то следует указать значение 0 (ноль):
$maxWidthContainer: 0;
$containerPadding — общий отступ (сумма отступов слева и справа) у ограничивающего контейнера. Указываем только число без px:
$containerPadding: 30;
Если отступов нет, либо вы хотите использовать адаптивное свойство, следует указать 0 (ноль):
$containerPadding: 0;
$containerWidth — ширина срабатывания первого брейкпоинта. Собственно, это сумма ширин ограничивающего контейнера и его отступов. Как правило, менять тут ничего не нужно.
$containerWidth: $maxWidthContainer + $containerPadding;
Вышеуказанные переменные влияют и на функционал отзывчивого свойства, который описан в отдельной статье
Переменным брейкпоинтов присвоена одна из SCSS-функций шаблона em(), она выполняют перевод пикселей в EM.
$pc — ПК, ноутбуки, некоторые планшеты в горизонтальном положении. Обычно, тут указывается переменная $containerWidth:
$pc: em($containerWidth);
$tablet — планшеты, некоторые телефоны в горизонтальном положении. Обычно, значение равно 991.98px:
$tablet: em(991.98);
$mobile — большие телефоны. Обычно, значение равно 767.98px:
$mobile: em(767.98);
$mobileSmall — маленькие телефоны. Обычно, значение равно 479.98px:
$mobileSmall: em(479.98);
Для быстрого вызова медиа запроса с нужным брейкпоинтом можно использовать сниппеты md1, md2, md3, md4. Или, для Mobile First, mmd1, mmd2, mmd3, mmd4
$responsiveType — настройка типа адаптива (поведения ограничивающего контейнера):
$responsiveType: 1;
Ниже, в файле стилей scss/style.scss указан селектор ограничивающего контейнера и его стили, значения которых во многом состоят из настроенных выше переменных. Стили ограничивающего контейнера будут применяться к любому элементу в классе которого есть строка «__container». Для удобства можно использовать сниппет cnt
<div class="block__container">
...
</div>
В файл scss/style.scss уже подключены и можно подключать прочие файлы стилей. Порядок подключения имеет значение!
@use «sass:math»; — подключает SASS-модуль математических вычислений. Теперь мы можем использовать деление с помощью math.div(число, число).
@import «base/mixins»; — подключение используемых в ЧФ миксинов. Файл scss/base/mixins.scss.
@import «base/null»; — подключение обнуляющих стилей. Файл scss/base/null.scss.
@import «base»; — подключение общего файла базовых стилей модулей ЧФ, SASS-шаблонов (заготовок) и вспомогательных классов. Файл scss/base.scss. Для подключения/отключения конкретных стилей смотри scss/base.scss.
@import «common»; — подключение файла стилей общих элементов конкретного проекта. Файл scss/common.scss (изначально пуст).
@import «header»; , @import «footer»; — подключение стилей отдельных блоков (изначально scss/header.scss и scss/footer.scss ). Вы можете дополнять список подключением своих файлов
@import «home»; — подключение стилей отдельных страниц (изначально scss/home.scss). Вы можете дополнять список подключением своих файлов
Изначально в файле стилей scss/style.scss есть ряд SCSS-селекторов:
body {} — стили основного тега <body> часть из которых описана в файле обнуления scss/base/null.scss. Также добавлена подготовка для появления у тега <html> двух классов:
.wrapper {} — обвертка всего контента на странице. Для неё написаны стили прижатия подвала к низу страницы, важный параметр overflow: hidden; который не даст появиться горизонтальному скроллу страницы, а также решение проблемы для слайдеров внутри дочерних flex-элементов.
С помощью SCSS-миксина «Отзывчивое (адаптивное) свойство» можно отзывчиво (в зависимости ширины экрана) изменять значение того или иного CSS-свойства от начального значения, на определенной ширине экрана, до конечного значения на другой ширине экрана. Можно указывать произвольные промежутки ширин. Также, существует несколько режимов поведения миксина вне указанных промежутках.
Миксин представлен в двух реализациях — clamp() и calc(). Сlamp работает быстрее, но если возникают проблемы с поддержкой браузерами миксин автоматически переключится на calc().
Принудительно использовать calc() можно изменив код миксина в файле scss/base/mixins.scss
Чтобы работать с миксином нужно в SCSS селекторе вызвать сниппет av:
@include adaptiveValue("свойство", начальное значение, конечное значение);
Где:
свойство — CSS-свойство, значение которого нужно адаптировать. Можно указать любое свойство значение которого указывается в цифрах.
начальное значение — стартовое значение свойства в пикселях, пишем число без px. Обычно указывается по макету.
конечное значение — финальное значение свойства в пикселях, пишем число без px. Значение, к которому мы хотим прийти на меньших ширинах экрана.
Примеры:
@include adaptiveValue("font-size", 50, 20);
@include adaptiveValue("padding-top", 80, 10);
Миксин работает на основе значений переменных $minWidth, $maxWidth, $maxWidthContainer, $containerPadding и $containerWidth расположенных в блоке «Настройка адаптивной сетки» файла scss/style.scss
Если $maxWidthContainer больше нуля, то значения свойства будут меняться в промежутке ширин от $containerWidth до $minWidth. То есть, по всей ширине ограничивающего контейнера.
При этом, если ширина экрана больше чем $containerWidth, то значение свойства будет равно начальному значению. Если ширина экрана меньше чем $minWidth, то значение свойства будет равно конечному значению.
Если $maxWidthContainer равен нулю, то значения свойства будут меняться в промежутке ширин от $maxWidth до $minWidth. То есть, по всей ширине экрана (вьюпорта).
Миксин позволяет указать свой промежуток ширины внутри которого будет адаптироваться значение свойства.
@include adaptiveValue("свойство", начальное значение, конечное значение, ширина от, ширина до);
@include adaptiveValue("font-size", 50, 20, 800, 480);
режим работы — может принимать числовые значения 1, 2 или 3:
@include adaptiveValue("font-size", 50, 20, 800, 480, 1);
Также мы можем использовать несколько вызовов миксина с разными промежутками:
@include adaptiveValue("font-size", 50, 20, 800, 480, 2);
@include adaptiveValue("font-size", 20, 10, 480, 320);
В примере произойдет следующее: значение font-size будет 50px, в промежутке ширин экрана от 800px до 480px, он будет отзывчиво адаптироваться от 50px до 20px. А в промежутке от 480px до 320px отзывчиво адаптироваться от 20px до 10px.
Миксин adaptiveValue находится в файле scss/base/mixins.scss
Функционал реагирует на клик по кнопке меню «бургера» (элемент с классом icon-menu). При этом к тегу html добавляется класс menu-open, а также срабатывает блокировка прокрутки страницы (функция bodyLockToggle() ). При повторном клике происходят обратные действия.
Функционал находится в js/files/functions.js. Название функции menuInit(), дополнительные функции menuOpen() и menuClose() для открытия/закрытия меню из произвольного кода. Все функции импортируемые.
Данный функционал добавляет возможность использовать всплывающие окна. Работа модуля заключается в следующем: пользователь нажимает на указанный элемент (по умолчанию это атрибут с указанным селектором data-popup=‘selector‘). При этом к тегу body добавляется класс popup-show. Также блокируется прокрутка страницы (можно отключить), фокусировка элементов «перелетает» на popup, с запоминанием предыдущего сфокусированного элемента на странице. Закрытие popup происходит при клике на кнопку закрытия (по умолчанию элемент с атрибутом data-close ), по клику на «пустом месте» (не на popup), по нажатию кнопки ESC.
Для того, чтобы вызвать попап, необходимо на странице ввести объект с дата-атрибутом, в котором указан селектор (класс или id) всплывающего окна, на которое ссылаемся:
<a href="#" data-popup="#popup" class="link">Я открываю попап</a>
Далее открыть файл html/_popup.htm , раскомментировать HTML-код подготовки попапа, указать селектор (id или класс) по которому вызывается попап, изменить код под свои нужды.
<div id="popup" aria-hidden="true" class="popup">
<div class="popup__wrapper">
<div class="popup__content">
<button data-close type="button" class="popup__close">Закрыть</button>
<div class="popup__text">
</div>
</div>
</div>
</div>
Для того чтобы открыть видеоролик в попапе, следует добавить к кнопке, которая вызывает попап, атрибут data-popup-youtube, а в качестве значения указать код ролика. Также следует указать атрибут data-popup-youtube-place для объекта в котором хотим вывести ролик (если атрибут data-popup-youtube-place не будет указан, ролик автоматически появится в объекте с классом popup__text ):
<button type="button" data-popup="#video" data-popup-youtube="6S5Zw2WuyFE">Видео</button>
<div id="video" aria-hidden="true" class="popup">
<div class="popup__wrapper">
<div class="popup__content">
<button data-close type="button" class="popup__close">Закрыть</button>
<div data-youtube-place class="popup__text">
</div>
</div>
</div>
</div>
Стили попапа можно писать и изменять в файле scss/base/popup.scss
Для того чтобы открыть попап при открытии страницы, добавляем к адресу хеш с именем селектора попапа
https://template.fls.guru/index.html#popup
Работать с попапом из любого места можно импортировать переменную flsModules:
import { flsModules } from "./modules.js";
Далее обратится к классу popup и работать с методом, например open()
flsModules.popup.open('#popup')
где #popup селектор попапа
В классе попапов существуют ряд событий:
Чтобы работать с событием вешаем прослушку на document
document.addEventListener("afterPopupOpen", function (e) {
// Попап
const currentPopup = e.detail.popup;
});
Во время работы над адаптивом сайта, нам то и дело приходится изменять внешний вид объекта. В некоторых случаях нам необходимо изменить порядок элементов, когда при определенном разрешении экрана некоторый блок должен находится в совершенно другом месте структуры. Особенно часто это требуется при адаптации шапки сайта когда необходимо перенести блок с контактами в меню-бургер.
Функционал динамического адаптива перемещает необходимый блок (на определенном разрешении) в другой блок. Перемещение отображается в разметке HTML.
[JS] В файле js/app.js раскомментировать строку import «./libs/dynamic_adapt.js»
[HTML] В блок который нужно переместить добавляем атрибут data-da со значениями атрибута указанными ниже:
Функционал находится в js/libs/dynamic_adapt.js. Название функции DynamicAdapt(type).
У модуля есть ограничения, например, если перекидывать несколько объектов одновременно в один и тот же блок, может возникнуть путаница с порядком блоков.
В данном модуле реализован плавный скролл после клика по ссылке (кнопке) до нужного блока на странице. Если в адресе страницы будет передан хеш и блок с таким селектором будет найден на странице, прокрутка к блоку произойдет автоматически. Также, модуль позволяет построить навигацию по странице с добавлением класса текущему пункту навигации (пункту меню) при скролле к определенному блоку.
[JS] В файле js/app.js раскомментировать строку flsScroll.pageNavigation();
[HTML] К элементам навигации (пунктам меню), либо к произвольному объекту, добавляем HTML-атрибут data-goto а в качестве значения указываем CSS селектор блока до которого нужно прокрутить:
<a href="#" data-goto=".имя класса блока" class="link">Пункт навигации</a>
<a href="#" data-goto="#id блока" class="link">Пункт навигации</a>
Если нужно чтобы скролл учитывал шапку (не докручивал на высоту шапки, используется при фиксированных шапках) нужно добавить к объекту навигации атрибут data-goto-header:
<a href="#" data-goto-header data-goto=".имя класса блока" class="link">Пункт навигации</a>
Если нужно чтобы скролл не докручивал до блока на указанную высоту необходимо добавить к объекту навигации атрибут data-goto-top а в качестве значения указать число — необходимую высоту:
<a href="#" data-goto-top="30" data-goto="#id блока" class="link">Пункт навигации</a>
data-goto-top можно совмещать с data-goto-header, тогда значение data-goto-top добавится к высоте шапки.
<a href="#" data-goto=".some-section" class="link">Пункт навигации</a>
<section data-watch="navigator" class="some-section"></section>
После этого, при прокрутке к облоку (объекту) навигации, к соответствующему пункту навигации будет добавлен класс _navigator-active
Для того чтобы прокрутить страницу к нужному блоке при открытии страницы необходимо добавить к адресу хеш содержащий имя класса нужного блока.
Пример адресной строки и нужного блока:
https://template.fls.guru/index.html#some-section
<section class="some-section"> </section>
По умолчанию, прокрутка выполняется методом scrollTo() с параметром behavior: «smooth» без применения дополнительных плагинов. Но это ограничивает функционал этого модуля — нельзя указать скорость прокрутки, а также могут возникнуть проблемы в некоторых версия браузеров на iOS. Для решения всех проблем, можно подключить дополнительный плагин SmoothScroll, сделать это можно в файле js/files/scroll/gotoblock.js раскомментировав строку import SmoothScroll from ‘smooth-scroll’; дальнейшее переключение прокрутки на плагин произойдет автоматически.
При работе с плагином появляется возможность указать скорость прокрутки, для этого элементу навигации нужно добавить атрибут data-goto-speed и указать число означающее количество миллисекунд за которые совершится прокрутка (1000 = 1 секунда), по умолчанию 500.
<a href="#" data-goto-speed="1000" data-goto=".some-section" class="link">Пункт навигации</a>
Функционал находится в js/files/scroll/scroll.js. Название функции pageNavigation(). Вспомогательный модуль прокрутки gotoblock находится в js/files/scroll/gotoblock.js. Модуль наблюдатель находится в файле js/libs/watcher.js.
Если в момент клика на пункт навигации было открыто меню «бургер», то оно закроется автоматически.
Функционал позволяет добавлять класс к тегу header с классом header при прокрутке страницы вниз, а также другой класс при остановке прокрутки. Таким образом, можно добиться эффекта когда при самом скролле вниз шапка не видна, но стоит остановить скролл, как шапка плавно появляется вверху страницы (становится фиксированной). При обратной прокрутке вверх шапка так же остается видна.
Класс _header-scroll добавляется к шапке при скролле вниз (через указанное кол-во пикселей).
При остановке скролла добавляется класс _header-show.
[JS] В файле js/app.js раскомментировать строку flsScroll.headerScroll();
[HTML] К тегу header, добавляем HTML-атрибут data-scroll, в значении атрибута указываем через какое кол-во прокрученных вниз пикселей нам необходимо добавить класс к header (обычно по высоте шапки, по умолчанию 1px).
<header data-scroll="120" class="header"> </header>
Теперь как только пользователь прокрутит вниз указанные выше 120px к header добавится технический класс _header-scroll. Этот класс будет присутствовать до тех пор, пока пользователь не вернется на самый вверх (не доходя 120px).
<header data-scroll="120" class="header _header-scroll"> </header>
[HTML] Далее к тегу header, добавляем еще один HTML-атрибут data-scroll-show. Как только пользователь остановит прокрутку к тегу header, через определенное время, добавится еще один технический класс _header-show. Этот класс исчезает только в моменте прокрутке вниз. При прокрутке вверх класс не исчезает.
<header data-scroll="120" data-scroll-show class="header _header-scroll _header-show"> </header>
Время задержки добавления класса _header-show можно менять. Для это следует указать значение атрибута data-scroll-show в миллисекундах (по умолчанию 500)
<header data-scroll="120" data-scroll-show="1000" class="header _header-scroll _header-show"> </header>
[SCSS] Теперь осталось отредактировать свойства этих подключенных классов в scss. Например:
Функционал находится в js/files/scroll/scroll.js. Название функции headerScroll()
Модуль «Наблюдатель» можно использовать для решения самых разных задач: анимация элементов при скролле, подсветка активного пункта меню (используется в модуле «Прокрутка к нужному блоку») и многих других.
Суть работы наблюдателя заключается в добавлении класса _watcher-view элементу в момент его появлении в вьюпорте (экране) при скролле а также при открытии страницы. И, соответственно, убран при уходе объекта из вьюпорта.
[HTML] Для объекта, за которым нужно установить наблюдение, следует добавить атрибут data-watch
<div data-watch class="block"> </div>
[JS] В файле js/app.js раскомментировать строку import ‘./libs/watcher.js’
Пример — класс добавится только один раз, при появлении объекта на 50% его высоты:
<div data-watch-threshold="0.5" data-watch-once data-watch class="block"> </div>
После каждом срабатывании наблюдателя, возникает событие watcherCallback, его можно отловить в любой части кода:
document.addEventListener("watcherCallback", function (e) {
// Полная информация от наблюдателя
const entry = e.detail.entry;
// Наблюдаемый объект
const targetElement = entry.target;
});
Функционал находится в файле js/libs/watcher.js. Название класса ScrollWatcher. Модуль построен на основе Intersection Observer API.
Модуль снабжен системой FLS и будет сообщать о своих действиях в консоль браузера
Модуль «Показать ещё» позволяет изначально скрыть часть текста или элементов списка показывая только указанную высоту либо количество элементов. Есть возможность включать функционал на определенной ширине экрана (брейкпоинте).
[HTML] В нужном месте вызвать сниппет showmore (классы заменить на нужные). Либо вручную создать структуру где для оболочки добавлен атрибут data-showmore, для дочернего элемента data-showmore-content и для кнопки data-showmore-button. Кнопку изначально нужно скрыть добавив атрибут hidden и добавить два тега <span> с текстом показа и скрытия контента:
<div data-showmore class="block">
<div data-showmore-content class="block__content"></div>
<button hidden data-showmore-button type="button" lass="block__more">
<span>Показать еще</span>
<span>Скыть</span>
</button>
</div>
[JS] В файле js/app.js раскомментировать строку flsFunctions.showMore();
[SCSS] Раскомментировать строку @import «base/showmore»; в файле src/scss/base.scss — это подключит базовые стили, отредактировать под свои нужды
В элемент с атрибутом data-showmore-content добавляем текст и прочий контент, либо, если это список (UL/OL) элементы списка (LI).
В зависимости от того, какой контент используется (текст или элементы списка) указываем значение для атрибута data-showmore:
<div data-showmore="items" class="block">
<ul data-showmore-content class="block__content">
<li>Пункт №1</li>
<li>Пункт №2</li>
<li>Пункт №3</li>
<li>Пункт №4</li>
<li>Пункт №5</li>
</ul>
<button hidden data-showmore-button type="button" class="block__more">
<span>Показать еще</span>
<span>Скыть</span>
</button>
</div>
В зависимости от того, какой тип выбран, указываем значение для атрибута data-showmore-content :
<div data-showmore class="block">
<div data-showmore-content="200" class="block__content">
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Blanditiis explicabo
voluptates magni culpa, perferendis vel quam consequuntur possimus,
vero placeat quo enim obcaecati quas, veritatis magnam non. Architecto,
porro voluptatum?
</div>
<button hidden data-showmore-button type="button" class="block__more">
<span>Показать еще</span>
<span>Скыть</span>
</button>
</div>
Если контента будет меньше чем указанное ограничение, кнопка «Показать ещё» не будет показана. В противном случае, контент ограничится по высоте либо по количеству элементов и при клике на кнопку будет показан полностью, также, к элементу с атрибутом data-showmore добавится класс _showmore-active (первый спан в кнопке будет скрыт а второй показан). Повторный клик вернет ограничение. Есть возможность управлять скоростью разворачивания контента, для этого следует указать значение атрибуту data-showmore-button в миллисекундах (по умолчанию 500):
<div data-showmore class="block">
<div data-showmore-content="200" class="block__content">
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Blanditiis explicabo
voluptates magni culpa, perferendis vel quam consequuntur possimus,
vero placeat quo enim obcaecati quas, veritatis magnam non. Architecto,
porro voluptatum?
</div>
<button hidden data-showmore-button="1000" type="button" class="block__more">
<span>Показать еще</span>
<span>Скыть</span>
</button>
</div>
Для того чтобы использовать функционал на определенной ширине экрана, к объекту с атрибутом data-showmore добавляем атрибут data-showmore-media где, через запятую, указываем нужную ширину, а также тип:
<div data-showmore data-showmore-media="768,min" class="block">
<div data-showmore-content="200" class="block__content">
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Blanditiis explicabo
voluptates magni culpa, perferendis vel quam consequuntur possimus,
vero placeat quo enim obcaecati quas, veritatis magnam non. Architecto,
porro voluptatum?
</div>
<button hidden data-showmore-button="1000" type="button" class="block__more">
<span>Показать еще</span>
<span>Скыть</span>
</button>
</div>
Функционал находится в js/files/functions.js. Название функции showMore()
Табы — это заголовки и соответствующие им блоки. Как правило, по умолчанию открыт только один блок остальные скрыты. При клике на заголовок показывается соответствующий ему блок.
[HTML] В нужном месте вызвать сниппет tabs (классы можно заменить на нужные). Либо вручную создать структуру с соответствующими дата-атрибутами. Обратите внимание, что добавление класса _tab-active для заголовка таба сделает таб активным (открытым)
<div data-tabs class="tabs">
<nav data-tabs-titles class="tabs__navigation">
<button type="button" class="tabs__title _tab-active">Таб №1</button>
<button type="button" class="tabs__title">Таб №2</button>
<button type="button" class="tabs__title">Таб №3</button>
</nav>
<div data-tabs-body class="tabs__content">
<div class="tabs__body">
Содержимое первого таба
</div>
<div class="tabs__body">
Содержимое второго таба
</div>
<div class="tabs__body">
Содержимое третьего таба
</div>
</div>
</div>
[JS] В файле js/app.js раскомментировать строку flsFunctions.tabs();
[SCSS] (не обязательно) Если вы хотите сразу посмотреть на работу табов и оставили классы предложенные сниппетом, вы можете раскомментировать строку @import «base/tabs»; в файле src/scss/base.scss — это подключит базовые стили, их можно отредактировать под свои нужды.
Для того, чтобы табы превращались в спойлеры, необходимо для элемента с атрибутом data-tabs указать значение ширины экрана ниже которой произойдет превращение:
<div data-tabs="768" class="tabs">
</div>
В момент превращения, к объекту с атрибутом data-tabs добавится класс _tab-spoller, по которому можно изменить стили для нового представления табов-спойлеров.
Если есть необходимость открывать конкретный таб в конкретном блоке табов при открытии страницы по хешу, необходимо, для элемента с атрибутом data-tabs, добавить атрибут data-tabs-hash:
<div data-tabs data-tabs-hash class="tabs">
</div>
Теперь, при клике на заголовки табов, к адресу страницы будет добавляться хеш вида: #tab-0-1, где 0 — это идентификатор блока с табами, а 1 — идентификатор таба в этом блоке.
Соответственно, перейдя на страницу с хешем #tab-0-1 откроется второй таб в первом блоке с табами. При #tab-2-0 откроется первый таб в третьем блоке с табами и т.д.
Для того, чтобы табы открывались плавно, необходимо объекту с атрибутом data-tabs, добавить атрибут data-tabs-animate, а в качестве значения указать количество миллисекунд за которые откроется таб (по умолчанию 500).
<div data-tabs data-tabs-animate="1000" class="tabs">
</div>
Функционал находится в js/files/functions.js. Название функции tabs()
Спойлер — это заголовок, при клике на который под ним разворачивается некий контент.
[HTML] В нужном месте вызвать сниппет spollers (классы можно заменить на нужные). Либо вручную создать структуру с соответствующими дата-атрибутами. Обратите внимание, что добавление класса _spoller-active для элемента с атрибутом data-spoller сделает спойлер активным (открытым).
<div data-spollers class="spollers">
<div class="spollers__item">
<button type="button" data-spoller class="spollers__title">
Заголовок спойлера №1
</button>
<div class="spollers__body">Контент спойлера №1</div>
</div>
<div class="spollers__item">
<button type="button" data-spoller class="spollers__title">
Заголовок спойлера №2
</button>
<div class="spollers__body">Контент спойлера №2</div>
</div>
</div>
[JS] В файле js/app.js раскомментировать строку flsFunctions.spollers();
[SCSS] (не обязательно) Если вы хотите сразу посмотреть на работу спойлеров и оставили классы предложенные сниппетом, вы можете раскомментировать строку @import «base/spollers»; в файле src/scss/base.scss — это подключит базовые стили, их можно отредактировать под свои нужды.
В момент инициализации (включения) функционала спойлера, контент будет скрыт, а к элементу с атрибутом data-spollers будет добавлен класс _spoller-init
Для того, чтобы отключить/включить функционал спойлера на определенной ширине экрана, необходимо для атрибута data-spollers через запятую указать нужную ширину экрана а также тип:
<div data-spollers="768,min" class="spollers">
</div>
Для того, чтобы включить режим «аккордеон», необходимо для элемента с атрибутом data-spollers добавить атрибут data-one-spoller
<div data-spollers data-one-spoller class="spollers">
</div>
Для того, чтобы управлять временем анимации открытия/закрытия спойлера, необходимо для элемента с атрибутом data-spollers добавить атрибут data-spollers-speed , а в качестве значения указать время анимации в миллисекундах (по умолчанию 500).
<div data-spollers data-spollers-speed="1000" class="spollers">
</div>
Если необходимо закрывать спойлер(ы) при клике вне блока («на пустом месте»), то следует добавить нужному заголовку(кам) атрибут data-spoller-close
<div data-spollers class="spollers">
<div class="spollers__item">
<button type="button" data-spoller data-spoller-close class="spollers__title">Заголовок спойлера</button>
<div class="spollers__body">Контент спойлера</div>
</div>
</div>
Функционал находится в js/files/functions.js. Название функции spollers()
Модуль «Ленивая подгрузка» позволяет подгружать изображения, а также содержимое тегов iframe video audio только при доскролливании к элементу. Это существенно повышает скорость загрузки страницы.
[HTML] Для подключения картинки с ленивой подгрузкой, в нужном месте следйет вызвать сниппет imgl, что выведет тег <img> но вместо атрибута src будет атрибут data-src.
При выводе других тегов (iframe video audio) также следует заменить src на data-src.
<img data-src="img/cover.jpg" alt="">
Во время режима продакшн, система распознает data-src и изменит для подключаемого webp-файла атрибут на data-srcset
[JS] В файле js/app.js раскомментировать строку import ‘./files/scroll/lazyload.js’;
В момент доскроливания до объекта с атрибутом data-src либо data-srcset модуль подгрузит данные (переместит подключение в атрибут src/srcset), а также добавит к объекту класс _lazy-loaded и атрибут data-ll-status со значением loaded
<img data-src="img/cover.jpg" alt="" loading="lazy" src="img/cover.jpg" data-ll-status="loaded" class="_lazy-loaded">
Модуль работает на основе плагина vanilla-lazyload.js . Подключение и настройки плагина находится в js/files/scroll/lazyload.js. Для более тонких настроек читайте полную документацию плагина.
[HTML] Существует два сниппета для построения HTML-структуры слайдера:
[JS] В файле js/app.js раскомментировать строку import «./files/sliders.js»;
В файле js/files/sliders.js выполняется подключение самого слайдера «Swiper» из NPM пакета (подключено по умолчанию)
import Swiper, { Navigation } from 'swiper';
При необходимости, можно подключить больше нужных модулей:
import Swiper, { Navigation, Pagination, Lazy, Autoplay } from 'swiper';
Полный список модулей — тут
Также, ниже по коду, есть пример-подготовка для создания конкретного слайдера (функция initSliders();) Тут мы создаем и настраиваем нужные нам слайдеры, не забываем указывать модули для конкретного слайдера:
new Swiper('.swiper', { modules: [Navigation, Autoplay], }
[SCSS] По умолчанию, в файле js/files/sliders.js подключены базовые, минимально необходимые для работы, стили слайдера import «../../scss/base/swiper.scss»; (для более опытных). Также есть возможность подключить (расскоментировав строку) полные стили слайдера из файла scss/libs/swiper.scss или из пакета import ‘swiper/css’; (для начинающих)
В этом документе описан общий функционал работы с полями, плейсхолдерами, валидацией, вариантами отправки форм и т.д. В отдельных разделах будет описан функционал конкретных элементов форм, таких как:
Для того чтобы подключить общий функционал для работы с полями форм необходимо раскомментировать функцию flsForms.formFieldsInit({…}) в файле js/app.js:
flsForms.formFieldsInit({ viewPass: false, });
viewPass — позволяет включить функционал «Показать пароль» . true — включено, false — выключено (по умолчанию).
По умолчанию, после подключения flsForms.formFieldsInit({…}), значение добавленного полю HTML-атрибута placeholder копируется в созданный скриптом атрибут data-placeholder, что позволит скрывать плейсхолдер при фокусе на поле. Если нам нужно отключить скрытие для конкретного поля, ему следует добавить атрибут data-placeholder-nohide
По умолчанию, после подключения flsForms.formFieldsInit({…}), при возникновении фокуса, к полю а также к его непосредственному родительскому элементу, добавится класс _form-focus. Если нам нужно отключить добавление классов для конкретного поля, ему следует добавить атрибут data-no-focus-classes
Для того чтобы скрипт начал вызывать функционал валидации поля в момент потери им фокуса, следует добавить полю атрибут data-validate.
Стоит добавить, что функционал работы с полями форм также удалит ошибку добавленную к полю валидатором при получении им фокуса. Подробнее о функционале валидации полей смотри далее в этом документе.
Функционал «Показать пароль», позволяет отображать зашифрованное значение поля с типом password при клике на объект с классом содержащим строку «__viewpass» который находится вместе с полем в одном родителе:
<form class="form" action="#">
<div class="form__line">
<input autocomplete="off" type="password" name="form[]" value="123456">
<button class="form__viewpass" type="button">Показать пароль</button>
</div>
<button type="submit" class="button">Отправить</button>
</form>
В момент клика на объект с классом содержащим строку «__viewpass» в нему добавляется класс , а тип поля ввода меняется на text. Повторное нажатие выполняет обратные действия.
Напомню, для того чтобы включить функционал «Показать пароль» следует указать true для параметра viewPass при подключении функционала в файле js/app.js.
Для того чтобы элемент формы начал проходить валидацию, ему следует добавить атрибут data-required. Теперь при отправке формы (если включена валидация), а также если элементу добавлен атрибут data-validate, он будет проверяться на предмет заполнения.
Для того чтобы включить особые правила валидации поля, атрибуту следует добавить одно из значений:
<input data-required="email" type="text" name="form[]">
Если элемент заполнен не верно, к нему, а также к его родителю добавится класс _form-error. Если мы хотим дополнительно вывести произвольный текст ошибки, нам следует указать его в атрибуте data-error и добавить к полю:
<input data-error="Введен не верный E-mail" data-required="email" type="text" name="form[]">
Теперь, при возникновении ошибки валидации, под элементом добавится объект с классом form__error содержащий ваш текст ошибки.
Напомню, что функционал работы с полями удалит классы ошибок и объект с классом form__error при получении полем фокуса.
Для включения функционала следует раскомментировать функцию flsForms.formSubmit(); в файле js/app.js
По умолчанию, при отправке формы, поля отмеченные data-required/data-required=’…’ будут проходить валидацию. Для отключения валидации элементов конкретной формы, ей следует добавить атрибут data-no-validate
Для включения режима AJAX отправки достаточно добавить форме атрибут data-ajax, а если нужен режим имитации отправки добавляем атрибут data-dev.
<form data-ajax class="form" method="POST" action="sendmail.php"></form>
Бывает, что форма очень большая и, при возникновении ошибки валидации, хорошо бы показать элемент с ошибкой пользователю. Для этих целей есть функционал «прокрутка к элементу с ошибкой». Для включения, достаточно добавить форме атрибут data-goto-error
<form data-goto-error class="form" action="#"></form>
Если необходимо, после отправки формы, показать попап добавляем к форме атрибут data-popup-message и в качестве значения указываем селектор попапа
Только для режимов data-ajax или data-dev. Функционал попапов также должен быть подключен
<form data-dev data-popup-message="#form-message" class="form" action="#"></form>
После каждой отправки формы срабатывает событие formSent, его можно отловить в любой части кода:
document.addEventListener("formSent", function (e) {
// Форма
const currentForm= e.detail.form;
});
Функции formFieldsInit(), formSubmit() а также объект formValidate находятся в файле js/files/forms/form.js
Модуль позволяет как угодно стилизовать стандартный элемент форы SELECT и его пункты OPTION, а также реализует дополнительные возможности.
[HTML] В нужном месте вызвать сниппет sel, отредактировать HTML-код селекта под свои нужды
[SCSS] Раскомментировать строку @import «select»; в файле src/scss/base/forms/forms.scss — это подключит базовые стили селекта, отредактировать под свои нужды
[JS] Раскомментировать строку import ‘./libs/select.js’ в файле js/app.js
Для подключения того или иного функционала модуля используются различные HTML-атрибуты
<select data-submit data-scroll name="form[]" class="form">
<option value="" selected>Плейсхолдер</option>
<option value="2">Пункт</option>
<option data-href="about.html" value="3">Пункт ссылка</option>
<option value="4">Пункт</option>
</select>
После каждого выбора элементы селекта срабатывает событие strongselectCallback, его можно отловить в любой части кода:
document.addEventListener("selectCallback", function (e) {
// Селект
const currentSelect = e.detail.select;
});
Класс SelectConstructor находится в файле js/libs/select.js
Функционал подключает галерею (LightGallery) . При клике на превью картинки полное изображение открывается с возможностью слайд-шоу. Можно создавать как встроенные, так и лайтбокс-галереи ( в правом углу располагается ряд кнопок (настраиваемо) для расширенных функций. Например: «Закрыть слайд-шоу», «Загрузка изображения» и пр. Галерея, поддерживает как простые изображения, так и видео или фреймы.
Для работы галереи необходимы изображения (видеофайлы) в двух форматах: миниатюры – изображения небольшого размера которые используются для предварительного просмотра и изображения полного размера – необходимые для детального просмотра.
[JS] В файле js/app.js раскомментировать строку import «./files/gallery.js»;
[HTML] К тегу родителя объектов галереи, добавляем HTML-атрибут data-gallery.
<div data-gallery class="gallery"</div>
Сам объект галереи состоят из такой конструкции (тег для изображения полного размера и внутри тег для превью). Например, можно использовать такую разметку:
<div data-gallery class="gallery">
<a href="iimg-full-1.jpg" class="gallery__image">
<img alt="Превью" src="iimg-thumb-1.jpg" class="gallery__preview">
</a>
<a href="iimg-full-2.jpg" class="gallery__image">
<img alt="Превью" src="iimg-thumb-2.jpg" class="gallery__preview">
</a>
</div>
Функционал находится в js/files/gallery.js
Подробная документация по работе с самим плагином на сайте галереи https://www.lightgalleryjs.com/docs/
Для этого следует скопировать отдельные SVG иконки в папку src/svgicons (если такой папки нет, нужно её создать). Далее запускаем команду в терминале npm run sprite
Создавать SVG-спрайт следует до вызова команды npm run dev
После выполнения команды отдельные SVG иконки соберутся в единый файл (спрайт) simg/icons/icons.svg
Если набор отдельных иконок в папке src/svgicons изменился, следует повторить команду npm run sprite
Каждой иконке в общем файле (спрайте) будет присвоен уникальный ID состоящий из строки svg-имя-файла-иконки. Например, если имя файла отдельной иконки было list.svg то ID будет svg-list. Следовательно, вывести необходимую иконку в нужном месте можно с помощью кода:
<svg><use xlink:href="img/icons/icons.svg#svg-list"></use></svg>