Це проєкт лендінг сторінки-магазину товарів. Приклад того, як можна продавати свої товари, не маючи повноцінного сайту інтернет-магазину, а тільки лендінг сторінку з основними товарами, та форму замовлення, яка відправляє інформацію на сервер, де буде оброблятись замовлення клієнта. Програмна частина цього проєкту використовує Jquery та кілька додаткових бібліотек на основі нього: jquery.maskedinput, jQuery Validation Plugin, також бібліотеки на нативному js: tiny-slider, wow.js. Розглянемо основні складові, які дозволяють взаємодіяти зі сторінкою.
Функція додає прослуховувачі на кнопки перемикання додаткового опису та кнопки назад, яка приховує додатковий опис товару.
Функція у собі ініціалізує тимчасовий екземпляр валідатора, та валідує передану форму. Повертає результат валідації.
$('[data-modal=consultation]').on('click', function() {
$('.overlay, #consultation').fadeIn('slow');
});
Прослуховується клік на кнопку "Замовити дзвінок", відкривається вікно з формою консультації.
$('.modal__close').on('click', function() {
$('.overlay, #consultation, #buy-done, #buy').fadeOut('slow');
});
Прослуховується клік на хрестик для закриття вікна та закривається вікно.
$('.button_product-card').each(function(i) {
$(this).on('click', function() {
$('#buy .modal__subtitle').text($('.product-card__title').eq(i).text());
$('.overlay, #buy').fadeIn('slow');
})
});
Для кожної кнопки "Купити" у карточці товару додається прослуховування кліку. Після кліку, у вікно з формою замовлення консультації додається назва товару, який хочуть купити, та відкривається це вікно.
$('ul.catalog__tabs-list').on('click', 'li:not(.catalog__tab-active)', function() {
$(this)
.addClass('catalog__tab-active').siblings().removeClass('catalog__tab-active')
.closest('div.catalog__tabs').find('div.catalog__tabs-content').removeClass('catalog__tabs-content-active').eq($(this).index()).addClass('catalog__tabs-content-active');
});
Прослуховується клік на елементи табів, окрім активного табу. Закривається\відкривається відповідний список карточок товарів, який відноситься до того, чи іншого табу.
$("input[name=telephone]").mask("+380 (99)-999-99-99");
До інпуту input[name=telephone]
застосовується метод для форматування номера телефона за українським національним форматом "+380 (99)-999-99-99". Це не прослуховування подій у звичному розумінні цього терміну. Але за характером роботи бібліотеки jquery.maskedinput, здається, всередині себе вона прослуховує введення в інпут, для форматування номера, тому я відніс це до прослуховувачів подій.
document.querySelector('.slider__prev-button').addEventListener('click', function () {
slider.goTo('prev');
});
document.querySelector('.slider__next-button').addEventListener('click', function () {
slider.goTo('next');
});
Прослуховуються кнопки для перемикання слайдеру "наступний слайд" та "минулий слайд", переключаються слайди у відповідному напрямку.
$(window).scroll(function() {
if ($(this).scrollTop() > 1600) {
$('.to-top').fadeIn();
} else {
$('.to-top').fadeOut();
}
});
Перевірка позиції області перегляду на сторінці, якщо перегляд сторінки підходить до кінця, то з'являється кнопка прокрутки сторінки до початку, якщо ні - кнопка зникає.
$("form").submit(function (e) {
e.preventDefault();
if(validateForm(this) === true) {
$('.client-form__loading').fadeIn();
$.ajax({
type: "POST",
url: "mailer/smart.php",
data: $(this).serialize()
}).done(function () {
$(this).find("input").val("");
$("form").trigger("reset");
$('.client-form__loading').fadeOut();
$(".overlay .modal").fadeOut('slow');
$(".overlay, #buy-done").fadeIn('slow');
})
}
return false;
});
При підтвердженні відправки форми валідуються дані користувача, якщо все добре, то дані серіалізуються, та відправляються на сервер. Форма скидається, зникає вікно з формою, та з'являється вікно, що замовлення відбулось успішно.
$("a").click(function(){
const _href = $(this).attr("href");
$("html, body").animate({scrollTop: $(_href).offset().top+"px"});
return false;
});
Прослуховується клік на усіх посиланнях, якщо посилання веде до певного елементу на сторінці, то перехід до нього анімується плавною прокруткою на позицію до цього елементу.
function advantagesImgAnim (entries, observer) {
entries.forEach((entry)=>{
if(entry.isIntersecting) {
advantagesImgs.forEach((elem)=>{
if(elem.className !== 'viewed') {
elem.classList.add('viewed');
}
});
}
});
}
const advantagesSect = document.querySelector('.advantages');
const advantagesImgs = document.querySelectorAll('.advantages img');
const observer = new IntersectionObserver(advantagesImgAnim, {
threshold: 0.8,
});
observer.observe(advantagesSect);
@keyframes run {
from {
transform: translate(0px, 0px);
}
33% {
transform: translate(-10px, 15px);
}
66% {
transform: translate(20px, 15px);
}
to {
transform: translate(0px, 0px);
}
}
&:nth-child(3) {
.viewed {
animation: run 1s 4;
}
}
Завдяки Intersection Observer API ми обробляємо подію, коли секцію .advantages
бачить користувач, та додаємо класи перегляду усім іконкам, запускаючи анімацію саме тоді, коли користувач бачить іконки. Анімація іконок реалізована завдяки CSS3. Вище наводжу приклад анімації іконки з бігучим кросівком.
new WOW().init();
Ініціалізація бібліотеки wow.js.
<div class="product-card wow animate__animated animate__fadeInLeft"> ... </div>
<div class="reviews__review-block wow animate__fadeInUp animate__animated"> ... </div>
Застосування бібліотеки до елементів сторінки. Таким чином, анімуємо появу певних елементів, зазначеним чином.
This is a landing page project for selling goods. It demonstrates how to sell products without a full-fledged e-commerce website, using only a landing page with essential products and an order form. The software part of this project uses jQuery and several additional libraries based on it: jquery.maskedinput, jQuery Validation Plugin, as well as native JS libraries: tiny-slider, wow.js. Let's explore the main components that allow interaction with the page.
This function adds event listeners to toggle additional description buttons and back buttons that hide the additional product description.
This function initializes a temporary validator instance and validates the passed form. It returns the validation result.
$('[data-modal=consultation]').on('click', function() {
$('.overlay, #consultation').fadeIn('slow');
});
Listens for a click on the "Order a Call" button and opens the consultation form window.
$('.modal__close').on('click', function() {
$('.overlay, #consultation, #buy-done, #buy').fadeOut('slow');
});
Listens for a click on the close button ('X') and closes the window.
$('.button_product-card').each(function(i) {
$(this).on('click', function() {
$('#buy .modal__subtitle').text($('.product-card__title').eq(i).text());
$('.overlay, #buy').fadeIn('slow');
})
});
For each "Buy" button in the product card, adds a click event listener. After clicking, adds the name of the product the user wants to buy to the consultation order form window and opens the window.
$('ul.catalog__tabs-list').on('click', 'li:not(.catalog__tab-active)', function() {
$(this)
.addClass('catalog__tab-active').siblings().removeClass('catalog__tab-active')
.closest('div.catalog__tabs').find('div.catalog__tabs-content').removeClass('catalog__tabs-content-active').eq($(this).index()).addClass('catalog__tabs-content-active');
});
Listens for clicks on tab elements (except the active tab). Closes/opens the corresponding product card list associated with that tab.
$("input[name=telephone]").mask("+380 (99)-999-99-99");
Applies a method to format the phone number in the input[name=telephone]
according to the Ukrainian national format "+380 (99)-999-99-99". While not traditional event listening, it uses the nature of the jquery.maskedinput library to format the input as users type.
document.querySelector('.slider__prev-button').addEventListener('click', function () {
slider.goTo('prev');
});
document.querySelector('.slider__next-button').addEventListener('click', function () {
slider.goTo('next');
});
Listens for clicks on the "previous slide" and "next slide" buttons and switches slides accordingly.
$(window).scroll(function() {
if ($(this).scrollTop() > 1600) {
$('.to-top').fadeIn();
} else {
$('.to-top').fadeOut();
}
});
Checks the scroll position on the page. If the scroll position is past 1600 pixels, the scroll-to-top button appears; otherwise, it disappears.
$("form").submit(function (e) {
e.preventDefault();
if(validateForm(this) === true) {
$('.client-form__loading').fadeIn();
$.ajax({
type: "POST",
url: "mailer/smart.php",
data: $(this).serialize()
}).done(function () {
$(this).find("input").val("");
$("form").trigger("reset");
$('.client-form__loading').fadeOut();
$(".overlay .modal").fadeOut('slow');
$(".overlay, #buy-done").fadeIn('slow');
})
}
return false;
});
When the form submission is confirmed, it validates user data. If successful, it serializes the data and sends it to the server. The form resets, the form window disappears, and a success window appears.
$("a").click(function(){
const _href = $(this).attr("href");
$("html, body").animate({scrollTop: $(_href).offset().top+"px"});
return false;
});
Listens for clicks on all links. If a link leads to a specific element on the page, it animates a smooth scroll to that element.
function advantagesImgAnim (entries, observer) {
entries.forEach((entry)=>{
if(entry.isIntersecting) {
advantagesImgs.forEach((elem)=>{
if(elem.className !== 'viewed') {
elem.classList.add('viewed');
}
});
}
});
}
const advantagesSect = document.querySelector('.advantages');
const advantagesImgs = document.querySelectorAll('.advantages img');
const observer = new IntersectionObserver(advantagesImgAnim, {
threshold: 0.8,
});
observer.observe(advantagesSect);
@keyframes run {
from {
transform: translate(0px, 0px);
}
33% {
transform: translate(-10px, 15px);
}
66% {
transform: translate(20px, 15px);
}
to {
transform: translate(0px, 0px);
}
}
&:nth-child(3) {
.viewed {
animation: run 1s 4;
}
}
Uses the Intersection Observer API to handle the event when the user sees the .advantages
section. Adds viewing classes to all icons, triggering the animation when the user sees the icons. Icon animation is implemented using CSS3. The CSS snippet provides an example of an animated icon with a running shoe.
new WOW().init();
Initializes the wow.js library.
<div class="product-card wow animate__animated animate__fadeInLeft"> ... </div>
<div class="reviews__review-block wow animate__fadeInUp animate__animated"> ... </div>
Applies the library to page elements, animating the appearance of certain elements as specified.