diff --git a/app/Classes/RusDate.php b/app/Classes/RusDate.php
index 5af75c6..0f30a59 100644
--- a/app/Classes/RusDate.php
+++ b/app/Classes/RusDate.php
@@ -4,6 +4,8 @@
namespace App\Classes;
+use DateTime;
+
class RusDate
{
public static function russian_date($date = null){
@@ -72,4 +74,46 @@ class RusDate
unset($_COOKIE['favorite_house']);
//print_r($_COOKIE['arr']);
}
+
+ public static function interval_month($date) {
+ $now = new DateTime();
+ $date = new DateTime($date); //::createFromFormat("Y-m-d H:i", $date);
+ $interval = $now->diff($date);
+ $y = $interval->y;
+ $d = $interval->d;
+ $h = $interval->h;
+ $i = $interval->i;
+
+ if ($d > 30)
+ return true;
+ else
+ return false;
+ }
+
+ public static function interval_day($date) {
+ $now = new DateTime();
+ $date = new DateTime($date); //::createFromFormat("Y-m-d H:i", $date);
+ $interval = $now->diff($date);
+ $y = $interval->y;
+ $d = $interval->d;
+ $h = $interval->h;
+ $i = $interval->i;
+
+ if (($h > 24) || ($d > 0) || ($y > 0))
+ return true;
+ else
+ return false;
+ }
+
+ public static function ip_addr_client() {
+ $client = @$_SERVER['HTTP_CLIENT_IP'];
+ $forward = @$_SERVER['HTTP_X_FORWARDED_FOR'];
+ $remote = @$_SERVER['REMOTE_ADDR'];
+
+ if(filter_var($client, FILTER_VALIDATE_IP)) $ip = $client;
+ elseif(filter_var($forward, FILTER_VALIDATE_IP)) $ip = $forward;
+ else $ip = $remote;
+
+ return $ip;
+ }
}
diff --git a/app/Http/Controllers/MainController.php b/app/Http/Controllers/MainController.php
index 83efe80..931149a 100644
--- a/app/Http/Controllers/MainController.php
+++ b/app/Http/Controllers/MainController.php
@@ -10,11 +10,13 @@ use App\Models\format_area;
use App\Models\House;
use App\Models\ModelMailFeedback;
use App\Models\News;
+use App\Models\Page;
use App\Models\Partners;
use App\Models\type_area;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
use App\Classes\RusDate;
+use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;
use PhpParser\Node\Stmt\Switch_;
use Illuminate\Support\Facades\Response;
@@ -732,13 +734,46 @@ class MainController extends Controller
/*
* Посмотр конктретного предложение офиса
*/
- public function Offer(House $house) {
+ public function Offer(House $house, Request $request) {
$houses = House::with('areas');
$houses = $houses->where('type_area_id', '=', $house->typearea->id);
$houses = $houses->where('format_house', '=', $house->format_house);
$houses = $houses->orderByDesc('created_at')->limit(8)->get();
- return view('house.post', compact('house', 'houses'));
+ //получение адреса страницы
+ $url = $request->url();
+ // получение ip-адреса клиента
+ $ip = RusDate::ip_addr_client();
+
+ //получение выборки данных из базы данных по данной странице
+ $page_ = Page::query()->where('url', '=', "$url")->
+ orderBy('created_at')->limit(1)->get();
+
+ //если интервал времени больше суток, то обнуляем счетчик
+ if ($page_->count()) {
+ $result = RusDate::interval_day($page_[0]->created_at);
+ if ($result) {
+ DB::table('pages')->where('url', '=', "$url")->delete();
+ }
+ }
+ // проверяем если в базе данных данный ip-адрес
+ $count_user = DB::table('pages')->where('ipaddress', '=', "$ip")->
+ where('url', '=', "$url")->get();
+ // если есть, то обновляем дату просмотра
+ if ($count_user->count() > 0) {
+ DB::table('pages')->where('ipaddress', '=', "$ip")->
+ where('url', '=', "$url")->update(['created_at' => date('Y-m-d H:i')]);
+ } else {
+ // в противном случае добавляем новый ip В бд
+ $page = new Page();
+ $page->ipaddress = $ip;
+ $page->url = $url;
+ $page->save();
+ }
+
+ // выводим количество пользователей гостей данной страницы
+ $count_user = DB::table('pages')->where('url', '=', "$url")->get();
+ return view('house.post', compact('house', 'houses', 'count_user'));
}
/*
diff --git a/app/Models/Page.php b/app/Models/Page.php
new file mode 100644
index 0000000..3efdf5b
--- /dev/null
+++ b/app/Models/Page.php
@@ -0,0 +1,11 @@
+id();
+ $table->string('ipaddress', 100);
+ $table->string('url', 255);
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::dropIfExists('pages');
+ }
+};
diff --git a/public/js/main_main.js b/public/js/main_main.js
new file mode 100644
index 0000000..629c2b1
--- /dev/null
+++ b/public/js/main_main.js
@@ -0,0 +1,1508 @@
+// управляющий класс App с методом init(), в котором собраны все используемые методы с комментариями о том, что конкретно делает каждый метод
+
+class App {
+
+ constructor() {
+ this.patternPhone = /^(\+7|7|8)?[\s\-]?\(?[489][0-9]{2}\)?[\s\-]?[0-9]{3}[\s\-]?[0-9]{2}[\s\-]?[0-9]{2}$/; // рег. выражение для поля 'телефон';
+ this.patternEmail = /^[a-zA-Z0-9._%+-\.]+@[a-z0-9.-]+\.[a-z]{2,}$/i; // рег. выражение для поля 'электронная почта';
+ }
+
+ init() {
+
+ console.log('init');
+
+ this.stickyHeader(); // липкий хедер;
+ this.controlBurgerMenu(); // бургер-меню;
+ this.smoothScroll(); // плавный скролл к якорю (smooth scroll);
+ this.scrollUp(); // кнопка наверх;
+ this.addToFavorites(); // добавить в избранное (звёздочка);
+ this.initTypicalSlider(); // типовые слайдеры;
+ this.initPartnerslSlider(); // слайдер с партнёрами;
+ this.controlFilters(); // фильтры на главном экране;
+ this.controlPopups(); // открытие/закрытие поп-апов;
+ this.controlContactUsPopup(); // открытие/закрытие поп-апа 'обратный звонок';
+
+ this.sendForm('.js_popup_feedback_form', '[data-popup="success"]'); // отправка формы в поп-апе обратной связи;
+ this.sendForm('.js_popup_viewing_form', '[data-popup="success"]'); // отправка формы в поп-апе 'записаться на просмотр';
+ this.sendForm('.js_footer_feedback_form', '[data-popup="success"]'); // отправка формы в футере;
+ this.sendForm('.js_contacts_form', '.js_contacts_success'); // отправка формы на странице контакты;
+ this.sendForm('.js_popup_sending_form_', '[data-popup="success"]');
+ //this.sendOffer(); //отправка предложения по e-mail;
+
+ //this.setGeneralMap(); // карта на странице карт;
+ //this.setComplexMap('complex-map', [55.726591050908745, 37.57244549999999], 'ЖК Садовые кварталы'); // карта на странице 'ЖК';
+ //this.setComplexMap('offer-map', [55.70851106903402, 37.65864349999999], 'Аренда торгового помещения 321,6 м2'); // карта на странице 'Предложение';
+ this.setCatalogSorts(); // сортировка на странице 'каталог';
+ this.initIntroSlider(); // слайдер на странице жк и на странице предложения;
+ this.setTabs('.js_offer_side_tab', '.js_offer_side_item'); // табы с планами объекат и этажа на странице предложения;
+ this.setTabs('.js_offer_side_popup_tab', '.js_offer_side_popup_item'); // табы с планами объекат и этажа в поп-апе на странице предложения;
+ this.sontrolOfferSidePopup(); // логика открытия нужного таба при открытии поп-апа с планами объекат и этажа на странице предложения;
+ this.setCustomGallery(); // галлерея;
+ this.setCookies() // куки;
+ this.setFooterSpoilers() // аккордеон в футере;
+
+ }
+
+ // фиксация
+ fixBodyPosition() {
+
+ setTimeout(function () {
+ // ставим необходимую задержку, чтобы не было «конфликта» в случае, если функция фиксации вызывается сразу после расфиксации (расфиксация отменяет действия расфиксации из-за одновременного действия)
+
+ if (!document.body.hasAttribute('data-body-scroll-fix')) {
+
+ // получаем позицию прокрутки
+ let scrollPosition = window.pageYOffset || document.documentElement.scrollTop;
+
+ // ставим нужные стили
+ document.body.setAttribute('data-body-scroll-fix', scrollPosition); // Cтавим атрибут со значением прокрутки
+ document.body.style.overflow = 'hidden';
+ document.body.style.position = 'fixed';
+ document.body.style.top = '-' + scrollPosition + 'px';
+ document.body.style.left = '0';
+ document.body.style.width = '100%';
+
+ if (window.innerWidth >= 1200) {
+ document.body.style.paddingRight = '8px';
+ }
+ }
+
+ }, 15); // можно задержку ещё меньше, но работает хорошо именно с этим значением на всех устройствах и браузерах
+
+ }
+
+
+ // расфиксация
+ unfixBodyPosition() {
+
+ if (document.body.hasAttribute('data-body-scroll-fix')) {
+
+ // получаем позицию прокрутки из атрибута
+ let scrollPosition = document.body.getAttribute('data-body-scroll-fix');
+
+ // удаляем атрибут
+ document.body.removeAttribute('data-body-scroll-fix');
+
+ // удаляем ненужные стили
+ document.body.style.overflow = '';
+ document.body.style.position = '';
+ document.body.style.top = '';
+ document.body.style.left = '';
+ document.body.style.width = '';
+ document.body.style.paddingRight = '';
+
+ // прокручиваем страницу на полученное из атрибута значение
+ window.scroll(0, scrollPosition);
+
+ }
+
+ }
+
+
+ // бургер-меню
+ controlBurgerMenu() {
+
+ const headerBurger = document.querySelector('.js_header_burger');
+
+ if (headerBurger) {
+
+ const menu = document.querySelector('.js_menu');
+ const menuClose = menu.querySelector('.js_menu_close');
+
+ headerBurger.addEventListener('click', () => {
+ menu.classList.add('active');
+ this.fixBodyPosition();
+ });
+
+ menu.addEventListener('click', (e) => {
+
+ if (e.target == menu) {
+ menu.classList.remove('active');
+ this.unfixBodyPosition();
+ }
+
+ });
+
+ menuClose.addEventListener('click', () => {
+ menu.classList.remove('active');
+ this.unfixBodyPosition();
+ });
+
+ }
+
+ }
+
+
+ // липкий хедер
+ stickyHeader() {
+
+ const header = document.querySelector('.js_header');
+
+ if (header) {
+
+ window.addEventListener('scroll', () => {
+
+ if (window.scrollY > 200) {
+ header.classList.add('fixed');
+ } else {
+ header.classList.remove('fixed');
+ }
+
+ });
+
+ };
+
+ }
+
+
+ // плавный скролл к якорю (smooth scroll)
+ smoothScroll() {
+
+ const smoothLinks = document.querySelectorAll('.js_smooth_link');
+
+ if (smoothLinks.length) {
+
+ smoothLinks.forEach(link => {
+
+ link.addEventListener('click', function (e) {
+
+ e.preventDefault();
+
+ let href = this.getAttribute('href').substring(1);
+
+ const scrollTarget = document.getElementById(href);
+
+ // const topOffset = document.querySelector('.header').offsetHeight;
+ const topOffset = 0; // если не нужен отступ сверху
+ const elementPosition = scrollTarget.getBoundingClientRect().top;
+ const offsetPosition = elementPosition - topOffset;
+
+ window.scrollBy({
+ top: offsetPosition,
+ behavior: 'smooth'
+ });
+
+ });
+
+ });
+
+ }
+
+ }
+
+
+ // кнопка наверх
+ scrollUp() {
+
+ const toTopBtn = document.querySelector('.js_btn_up');
+
+ if (toTopBtn) {
+
+ toTopBtn.addEventListener('click', function () {
+
+ window.scrollTo({
+ top: 0,
+ behavior: 'smooth'
+ });
+
+ });
+
+ }
+
+ }
+
+
+ // добавить в избранное (звёздочка)
+ addToFavorites() {
+
+ const cardFavorites = document.querySelectorAll('.js_card_favorites');
+
+ if (cardFavorites.length) {
+
+ cardFavorites.forEach(item => {
+
+ item.addEventListener('click', (e) => {
+ e.preventDefault();
+ item.classList.toggle('active');
+ });
+
+ });
+
+ }
+
+ }
+
+
+ // типовые слайдеры
+ initTypicalSlider() {
+
+ const slidersWraps = document.querySelectorAll('.slider__wrap');
+
+ if (slidersWraps.length) {
+
+ slidersWraps.forEach(wrap => {
+
+ const slider = wrap.querySelector('.swiper');
+ const prev = wrap.querySelector('.swiper-button-prev');
+ const next = wrap.querySelector('.swiper-button-next');
+ const pagination = wrap.querySelector('.swiper-pagination');
+
+ let swiper1 = new Swiper(slider, {
+ navigation: {
+ nextEl: next,
+ prevEl: prev,
+ },
+ pagination: {
+ el: pagination,
+ clickable: true,
+ },
+ slidesPerView: 1,
+ spaceBetween: 20,
+ observer: true,
+ observeParents: true,
+ observeSlideChildren: true,
+ breakpoints: {
+ 480: {
+ slidesPerView: 1.5,
+ },
+ 640: {
+ slidesPerView: 2,
+ },
+ 780: {
+ slidesPerView: 2.5,
+ },
+ 920: {
+ slidesPerView: 3,
+ },
+ 1024: {
+ slidesPerView: 3.4
+ },
+ 1200: {
+ slidesPerView: 4,
+ }
+ }
+ });
+
+ });
+
+ }
+
+ }
+
+
+ // метод, делающий число удобночитаемым (добавляет пробел справа через каждые 3 цифры)
+ prettify(num) {
+ const withoutSpace = num.replace(/[^\d]/g, ''); //убирает все символы;
+ return withoutSpace.replace(/(?!^)(?=(?:\d{3})+(?:\.|$))/gm, ' '); //ставит пробелы;
+ }
+
+
+ // фильтры на главном экране
+ controlFilters() {
+
+ const heroFilters = document.querySelectorAll('.js_hero_filter');
+ const heroSearchBtns = document.querySelectorAll('.js_hero_search_btn');
+
+ if (heroFilters.length) {
+
+ heroFilters.forEach(filter => {
+
+ const heroFilterInput = filter.querySelector('.js_hero_filter_input');
+ const heroFilterCurrent = filter.querySelector('.js_hero_filter_current');
+ const heroFilterItems = filter.querySelectorAll('.hero-filter__item');
+ const heroFilterFields = filter.querySelectorAll('.js_hero_filter_field');
+ const heroFilterFrom = filter.querySelector('.js_hero_filter_from');
+ const heroFilterTo = filter.querySelector('.js_hero_filter_to');
+ const heroFilterReset = filter.querySelector('.js_hero_filter_reset');
+
+ heroFilterCurrent.addEventListener('click', () => {
+
+ if (filter.classList.contains('active')) {
+
+ filter.classList.remove('active');
+
+ heroSearchBtns.forEach(btn => {
+ btn.disabled = false;
+ });
+
+ } else {
+
+ heroFilters.forEach(filter => {
+ filter.classList.remove('active');
+ });
+
+ filter.classList.add('active');
+
+ heroSearchBtns.forEach(btn => {
+ btn.disabled = true;
+ });
+
+ }
+
+ });
+
+ if (heroFilterItems.length) {
+
+ heroFilterItems.forEach(item => {
+
+ item.addEventListener('click', () => {
+
+ heroFilterCurrent.textContent = item.textContent;
+ heroFilterInput.value = item.dataset.val;
+ filter.classList.remove('active');
+
+ heroSearchBtns.forEach(btn => {
+ btn.disabled = false;
+ });
+
+ });
+
+ });
+
+ }
+
+ if (heroFilterFields.length) {
+
+ const heroFilterMin = heroFilterFrom.dataset.min;
+ const heroFilterMax = heroFilterTo.dataset.max;
+
+ let heroFilterFromVal;
+ let heroFilterToVal;
+
+ heroFilterFields.forEach(field => {
+
+ field.addEventListener('input', () => {
+
+ field.value = this.prettify(field.value);
+
+ heroFilterReset.classList.remove('active');
+
+ heroFilterFields.forEach(field => {
+
+ if (field.value != "") {
+ heroFilterReset.classList.add('active');
+ }
+
+ });
+
+ });
+
+ });
+
+ heroFilterFrom.addEventListener('change', () => {
+
+ heroFilterFromVal = +heroFilterFrom.value.replace(/\s/g, '');
+ heroFilterToVal = +heroFilterTo.value.replace(/\s/g, '');
+
+ if (heroFilterToVal != '' && heroFilterFromVal > heroFilterToVal) {
+
+ heroFilterFrom.value = heroFilterTo.value;
+
+ } else if (heroFilterFromVal < +heroFilterMin) {
+
+ heroFilterFrom.value = this.prettify(heroFilterMin);
+
+ } else if (heroFilterFromVal > +heroFilterMax) {
+
+ heroFilterFrom.value = this.prettify(heroFilterMax);
+
+ }
+
+ });
+
+ heroFilterTo.addEventListener('change', () => {
+
+ heroFilterFromVal = +heroFilterFrom.value.replace(/\s/g, '');
+ heroFilterToVal = +heroFilterTo.value.replace(/\s/g, '');
+
+ if (heroFilterFromVal != '' && heroFilterToVal < heroFilterFromVal) {
+
+ heroFilterTo.value = heroFilterFrom.value;
+
+ } else if (heroFilterToVal < +heroFilterMin) {
+
+ heroFilterTo.value = this.prettify(heroFilterMax);
+
+ } else if (heroFilterToVal > +heroFilterMax) {
+
+ heroFilterTo.value = this.prettify(heroFilterMax);
+
+ }
+
+ });
+
+ heroFilterReset.addEventListener('click', () => {
+
+ heroFilterFields.forEach(field => {
+ field.value = '';
+ });
+
+ heroFilterReset.classList.remove('active');
+
+ });
+ }
+
+ });
+
+ document.addEventListener('click', (e) => {
+
+ if (!e.target.closest('.js_hero_filter_dropdown') && !e.target.closest('.js_hero_filter_current')) {
+
+ heroFilters.forEach(filter => {
+ filter.classList.remove('active');
+ });
+
+ heroSearchBtns.forEach(btn => {
+ btn.disabled = false;
+ });
+
+ }
+
+ });
+
+ }
+
+ }
+
+
+ // открытие/закрытие типовых поп-апов
+ controlPopups() {
+
+ const popupShowBtns = document.querySelectorAll('[data-btn]');
+ const popups = document.querySelectorAll('[data-popup]');
+
+ if (popupShowBtns.length) {
+
+ popupShowBtns.forEach(btn => {
+
+ btn.addEventListener('click', (e) => {
+
+ e.preventDefault();
+
+ popups.forEach(popup => {
+
+ popup.classList.remove('active'); // если какойто поп-ап открыт, то закрываем его;
+ this.unfixBodyPosition();
+
+ if (btn.dataset.btn == popup.dataset.popup) {
+ popup.classList.add('active');
+ this.fixBodyPosition();
+ }
+
+ });
+
+
+ });
+
+ });
+
+ popups.forEach(popup => {
+
+ const popupCloseBtns = popup.querySelectorAll('.js_popup_close');
+
+ popupCloseBtns.forEach(btn => {
+
+ btn.addEventListener('click', (e) => {
+ e.preventDefault();
+ popup.classList.remove('active');
+ this.unfixBodyPosition();
+ });
+
+ });
+
+ popup.addEventListener('click', (e) => {
+
+ if (e.target == popup) {
+
+ popup.classList.remove('active');
+ this.unfixBodyPosition();
+ }
+
+ });
+
+ });
+
+ }
+ }
+
+
+ // открытие/закрытие поп-апа 'обратный звонок'
+ controlContactUsPopup() {
+
+ const contactUsBtn = document.querySelector('.js_btn_contact_us');
+ const contactUsPopup = document.querySelector('.js_contact_us');
+
+ if (contactUsPopup) {
+
+ const contactUsPopupCloseBtns = contactUsPopup.querySelectorAll('.js_contact_us_close');
+
+ contactUsBtn.addEventListener('click', (e) => {
+
+ e.preventDefault();
+
+ if (contactUsPopup.classList.contains('active')) {
+ contactUsPopup.classList.remove('active');
+ } else {
+ contactUsPopup.classList.add('active');
+ }
+
+ });
+
+ contactUsPopupCloseBtns.forEach(btn => {
+ btn.addEventListener('click', () => {
+ contactUsPopup.classList.remove('active');
+ });
+ });
+
+
+ document.addEventListener('click', (e) => {
+
+ if (!e.target.closest('.js_contact_us') && !e.target.closest('.js_btn_contact_us')) {
+ contactUsPopup.classList.remove('active');
+ }
+
+ });
+
+ }
+
+ }
+
+
+ // валидатор форм
+ validateForm(input) {
+
+ // функция добавления ошибки
+ const createError = (text) => {
+
+ input.classList.add('error');
+ input.classList.remove('no-error');
+
+ if (input.closest('label').querySelector('span.error')) {
+ input.closest('label').querySelector('span.error').remove();
+ input.closest('label').insertAdjacentHTML('beforeend', `${text}`);
+ } else {
+ input.closest('label').insertAdjacentHTML('beforeend', `${text}`);
+ }
+
+ }
+
+ // функция удаления ошибки
+ const removeError = () => {
+
+ input.classList.remove('error');
+ input.classList.add('no-error');
+
+ if (input.closest('label').querySelector('span.error')) {
+ input.closest('label').querySelector('span.error').remove();
+ }
+
+ }
+
+ // проверяем на правильность заполнения поля 'Телефон'
+ if (input.classList.contains('js_input_phone') && input.value == "") {
+ createError('Заполните, пожалуйста, поле');
+ } else if (input.classList.contains('js_input_phone') && input.value.search(this.patternPhone) == 0) {
+ removeError();
+ } else if (input.classList.contains('js_input_phone')) {
+ createError('Укажите, пожалуйста, корректный телефон');
+ }
+
+ // проверяем правильность заполнения поля 'Электронная почта'
+ if (input.classList.contains('js_input_email') && input.value == "") {
+ createError('Заполните, пожалуйста, поле');
+ } else if (input.classList.contains('js_input_email') && input.value.search(this.patternEmail) == 0) {
+ removeError();
+ } else if (input.classList.contains('js_input_email')) {
+ createError('Укажите, пожалуйста, корректный e-mail');
+ }
+
+ }
+
+
+ // отправка форм
+ sendForm(formEl, success) {
+
+ const form = document.querySelector(formEl);
+
+ if (form) {
+
+ form.addEventListener('submit', async (e) => {
+
+ e.preventDefault();
+
+ const formInputs = form.querySelectorAll('input');
+ const formBtn = form.querySelector('.js_form_btn');
+
+ formInputs.forEach(input => { // перебираем все инпуты в форме;
+
+ this.validateForm(input);
+
+ input.addEventListener('input', () => {
+ this.validateForm(input);
+ });
+
+ });
+
+ if (!form.querySelector('.error')) { //проверяем, чтоб все инпуты прошли валидацию (чтоб не было в форме ни одного элемента с класссом error);
+
+ // сюда пишем команды, которые должны сработать после успешной валидации;
+
+ console.log('validate');
+ formBtn.classList.add('btn-animate');
+ formBtn.disabled = true;
+
+ const formData = new FormData(form);
+
+ console.log(...formData);
+
+ const response = await fetch(e.target.action, {
+ method: e.target.method,
+ body: formData
+ });
+
+ if (response.ok) {
+
+ setTimeout(() => { // имитация отправки, когда отправка будет настроена, нужно достать всё из setTimeout() и удалить его;
+
+ console.log('Отправлено');
+ formBtn.classList.remove('btn-animate');
+ formBtn.disabled = false;
+ if (document.querySelector('[data-popup="feedback"]')) {
+ document.querySelector('[data-popup="feedback"]').classList.remove('active');
+ }
+ if (document.querySelector('[data-popup="viewing"]')) {
+ document.querySelector('[data-popup="viewing"]').classList.remove('active');
+ }
+ document.querySelector(success).classList.add('active');
+ this.fixBodyPosition();
+ form.reset();
+
+ formInputs.forEach(input => {
+ input.classList.remove('no-error');
+ });
+
+ }, 2000)
+
+ } else {
+ formBtn.classList.remove('btn-animate');
+ formBtn.disabled = false;
+ alert('Ошибка');
+ }
+
+ } else {
+ console.log('no-validate');
+ form.querySelector('.error').focus(); //фокус к полю с ошибкой;
+ }
+
+ });
+
+ }
+
+ }
+
+ //отправка предложения по e-mail
+ sendOffer() {
+
+ const form = document.querySelector('.js_popup_sending_form');
+
+ if (form) {
+
+ form.addEventListener('submit', async (e) => {
+
+ e.preventDefault();
+
+ const formInputs = form.querySelectorAll('input');
+ const formBtn = form.querySelector('.js_form_btn');
+
+ formInputs.forEach(input => { // перебираем все инпуты в форме;
+
+ this.validateForm(input);
+
+ input.addEventListener('input', () => {
+ this.validateForm(input);
+ });
+
+ });
+
+ if (!form.querySelector('.error')) { //проверяем, чтоб все инпуты прошли валидацию (чтоб не было в форме ни одного элемента с класссом error);
+
+ // сюда пишем команды, которые должны сработать после успешной валидации;
+
+ console.log('validate');
+ formBtn.classList.add('btn-animate');
+ formBtn.disabled = true;
+
+ const formData = new FormData(form);
+
+ console.log(...formData);
+
+ const response = await fetch(e.target.action, {
+ method: e.target.method,
+ body: formData
+ });
+
+ if (response.ok) {
+
+ setTimeout(() => { // имитация отправки, когда отправка будет настроена, нужно достать всё из setTimeout() и удалить его;
+
+ console.log('Отправлено');
+ formBtn.classList.remove('btn-animate');
+ formBtn.disabled = false;
+ if (document.querySelector('[data-popup="sending"]')) {
+ document.querySelector('[data-popup="sending"]').classList.remove('active');
+ }
+ this.fixBodyPosition();
+ form.reset();
+
+ formInputs.forEach(input => {
+ input.classList.remove('no-error');
+ });
+
+ }, 2000)
+
+ } else {
+ formBtn.classList.remove('btn-animate');
+ formBtn.disabled = false;
+ alert('Ошибка');
+ }
+
+ } else {
+ console.log('no-validate');
+ form.querySelector('.error').focus(); //фокус к полю с ошибкой;
+ }
+
+ });
+
+ }
+
+ }
+
+
+ // карта на странице 'ЖК'
+/* setComplexMap(id, coords, caption) {
+
+ if (document.querySelector('#' + id)) {
+
+ // Дождёмся загрузки API и готовности DOM.
+ ymaps.ready(init);
+
+ function init() {
+ const map = new ymaps.Map(id, {
+ // При инициализации карты обязательно нужно указать её центр и коэффициент масштабирования.
+ center: coords,
+ zoom: 16,
+ controls: []
+ });
+
+ // Создаём макет содержимого.
+ const MyIconContentLayout = ymaps.templateLayoutFactory.createClass(
+ '$[properties.iconContent]
'
+ );
+
+ // Создание макета содержимого хинта.
+ // Макет создается через фабрику макетов с помощью текстового шаблона.
+ const HintLayout = ymaps.templateLayoutFactory.createClass("" +
+ "{{ properties.object }}" + "
", {
+ // Определяем метод getShape, который
+ // будет возвращать размеры макета хинта.
+ // Это необходимо для того, чтобы хинт автоматически
+ // сдвигал позицию при выходе за пределы карты.
+ getShape: function () {
+ let el = this.getElement(),
+ result = null;
+ if (el) {
+ var firstChild = el.firstChild;
+ result = new ymaps.shape.Rectangle(
+ new ymaps.geometry.pixel.Rectangle([
+ [0, 0],
+ [firstChild.offsetWidth, firstChild.offsetHeight]
+ ])
+ );
+ }
+ return result;
+ }
+ }
+ );
+
+ // метка
+ const placemark = new ymaps.Placemark(coords, {
+ // hintContent: caption,
+ // balloonContent: caption,
+ iconContent: '1',
+ // address: caption,
+ object: caption
+ }, {
+ iconLayout: 'default#imageWithContent',
+ iconImageHref: 'images/mark-complex.svg',
+ iconImageSize: [52, 67],
+ iconImageOffset: [-26, -67],
+ iconContentOffset: [0, 17],
+ iconContentLayout: MyIconContentLayout,
+ hintLayout: HintLayout
+ });
+
+ map.geoObjects.add(placemark);
+
+ }
+
+ }
+
+ }
+*/
+
+ // фильтры и сортировка на странице 'каталог'
+ setCatalogSorts() {
+
+ const sortGroups = document.querySelectorAll('.js_sort_group');
+
+ if (sortGroups.length) {
+
+ sortGroups.forEach(group => {
+
+ const sortGroupInput = group.querySelector('.js_sort_group_input');
+ const sortGroupCurrent = group.querySelector('.js_sort_group_current');
+ const sortGroupList = group.querySelector('.js_sort_group_list');
+ const sortGroupItems = group.querySelectorAll('.js_sort_group_item');
+
+ const sendRequest = () => {
+
+ const spinner = document.querySelector('.spinner'); // спиннер;
+
+ spinner.classList.add('active');
+ document.body.classList.add('overlay');
+ /*this.fixBodyPosition();
+
+ fetch('test.json')
+ .then(response => response.json())
+ .then(data => {
+
+ console.log()
+
+ setTimeout(() => { //имитация ответа сервера
+
+ spinner.classList.remove('active');
+ document.body.classList.remove('overlay');
+ this.unfixBodyPosition();
+
+ }, 3000);
+
+ })
+ .catch(err => {
+ console.log(err);
+ });
+
+ */
+ spinner.classList.remove('active');
+ document.body.classList.remove('overlay');
+
+
+ };
+
+ sortGroupCurrent.addEventListener('click', () => {
+
+ if (group.classList.contains('active')) {
+
+ group.classList.remove('active');
+
+ } else {
+
+ sortGroups.forEach(group => {
+ group.classList.remove('active');
+ });
+
+ group.classList.add('active');
+
+ }
+
+ });
+
+ sortGroupItems.forEach(item => {
+
+ item.addEventListener('click', () => {
+
+ sortGroupItems.forEach(item => {
+ item.classList.remove('active');
+ });
+
+ item.classList.add('active');
+ sortGroupCurrent.textContent = item.textContent;
+ sortGroupInput.value = item.dataset.val;
+ group.classList.remove('active');
+
+ sendRequest();
+
+ });
+
+ });
+
+ });
+
+ document.addEventListener('click', (e) => {
+
+ if (!e.target.closest('.js_sort_group_list') && !e.target.closest('.js_sort_group_current')) {
+
+ sortGroups.forEach(group => {
+ group.classList.remove('active');
+ });
+
+ }
+
+ });
+
+ }
+
+ }
+
+
+ // слайдер на странице жк и на странице предложения
+ initIntroSlider() {
+
+ let swiper3 = new Swiper('.intro__swiper', {
+ navigation: {
+ nextEl: '.swiper-button-next',
+ prevEl: '.swiper-button-prev',
+ },
+ pagination: {
+ el: '.swiper-pagination',
+ clickable: true,
+ },
+ slidesPerView: 1.1,
+ spaceBetween: 20,
+ breakpoints: {
+ 480: {
+ slidesPerView: 1.5,
+ },
+ 640: {
+ slidesPerView: 1.75,
+ },
+ 780: {
+ slidesPerView: 2.15,
+ },
+ 1024: {
+ slidesPerView: 3.5,
+ },
+ 1200: {
+ slidesPerView: 1,
+ }
+ }
+ });
+
+ }
+
+
+ // табы на странице предложения
+ setTabs(tabs, items) {
+
+ const offerSideTabs = document.querySelectorAll(tabs);
+ const offerSideItems = document.querySelectorAll(items);
+
+ if (offerSideTabs) {
+
+ offerSideTabs.forEach(tab => {
+
+ tab.addEventListener('click', () => {
+
+ offerSideTabs.forEach(tab => {
+ tab.classList.remove('active');
+ });
+
+ tab.classList.add('active');
+
+ offerSideItems.forEach(item => {
+
+ item.classList.remove('active', 'fade');
+
+ if (tab.dataset.tab == item.dataset.item) {
+ item.classList.add('active', 'fade');
+ }
+
+ });
+
+ });
+
+ });
+
+ }
+
+ }
+
+
+ // логика открытия нужного таба при открытии поп-апа с планами объекат и этажа на странице предложения
+ sontrolOfferSidePopup() {
+
+ const offerSideItems = document.querySelectorAll('.js_offer_side_item');
+ const offerSidePopupTabs = document.querySelectorAll('.js_offer_side_popup_tab');
+ const offerSidePopupItems = document.querySelectorAll('.js_offer_side_popup_item');
+
+ if (offerSideItems) {
+
+ offerSideItems.forEach(item => {
+
+ const offerSideItemBtn = item.querySelector('.js_offer_side_item_btn');
+
+ offerSideItemBtn.addEventListener('click', (e) => {
+
+ e.preventDefault();
+
+ offerSidePopupTabs.forEach(tab => {
+
+ tab.classList.remove('active');
+
+ if (item.dataset.item == tab.dataset.tab) {
+ tab.classList.add('active');
+ }
+
+ });
+
+ offerSidePopupItems.forEach(el => {
+
+ el.classList.remove('active', 'fade');
+
+ if (item.dataset.item == el.dataset.item) {
+ el.classList.add('active', 'fade');
+ }
+
+ });
+
+ });
+
+ });
+
+ }
+
+ }
+
+
+ // галлерея
+ setCustomGallery() {
+
+ let swiper4 = new Swiper(".img-viewer__thumbs-swiper", {
+ slidesPerView: 3,
+ spaceBetween: 8,
+ // freeMode: true,
+ observer: true,
+ observeParents: true,
+ observeSlideChildren: true,
+ breakpoints: {
+ 640: {
+ spaceBetween: 10,
+ },
+ },
+ });
+
+ let swiper5 = new Swiper(".img-viewer__slider .swiper", {
+ navigation: {
+ nextEl: ".img-viewer__slider .swiper-button-next",
+ prevEl: ".img-viewer__slider .swiper-button-prev",
+ },
+ slidesPerView: 1,
+ spaceBetween: 20,
+ thumbs: {
+ swiper: swiper4
+ },
+ observer: true,
+ observeParents: true,
+ observeSlideChildren: true,
+ });
+
+ if (document.querySelector('.js_intro_item_btn')) {
+
+ const imgViewer = document.querySelector('.js_img_viewer');
+ const imgViewerCloses = imgViewer.querySelectorAll('.js_img_viewer_close');
+ const imgViewerCaption = imgViewer.querySelector('.js_img_viewer_caption');
+
+ const imgViewerSliderSwiper = imgViewer.querySelector('.js_img_viewer_slider_swiper');
+ const imgViewerSliderSwiperWrap = imgViewerSliderSwiper.querySelector('.js_img_viewer_slider_swiper .swiper-wrapper');
+
+ const imgViewerThumbsSwiper = imgViewer.querySelector('.js_img_viewer_thumbs_swiper');
+ const imgViewerThumbsSwiperWrap = imgViewerThumbsSwiper.querySelector('.js_img_viewer_thumbs_swiper .swiper-wrapper');
+
+ const introItemBtns = document.querySelectorAll('.js_intro_item_btn');
+
+ introItemBtns.forEach((btn, i) => {
+
+ btn.addEventListener('click', (e) => {
+
+ e.preventDefault();
+
+ imgViewer.classList.add('active');
+ this.fixBodyPosition();
+
+ imgViewerSliderSwiperWrap.innerHTML = '';
+ imgViewerThumbsSwiperWrap.innerHTML = '';
+ imgViewerCaption.textContent = '';
+
+
+ introItemBtns.forEach(btn => {
+
+ imgViewerSliderSwiperWrap.insertAdjacentHTML('beforeend', `
+
+
+
`
+ );
+
+ imgViewerThumbsSwiperWrap.insertAdjacentHTML('beforeend', `
+
+
+
`
+ );
+
+ });
+
+ swiper4.update();
+ swiper5.update();
+ swiper5.slideTo(i);
+ imgViewerCaption.textContent = btn.dataset.caption;
+
+ });
+
+ });
+
+ swiper5.on('slideChange', function () {
+ imgViewerCaption.textContent = introItemBtns[swiper5.realIndex].dataset.caption;
+ });
+
+ imgViewerCloses.forEach(close => {
+
+ close.addEventListener('click', () => {
+
+ imgViewer.classList.remove('active');
+ this.unfixBodyPosition();
+
+ });
+
+ });
+
+ }
+
+ }
+
+
+ // куки
+ setCookies() {
+
+ const cookies = document.querySelector('.js_cookies');
+ const cookiesBtn = document.querySelector('.js_cookies_confirm');
+ const cookiesTrigger = document.querySelector('.js_btn_cookies');
+
+ if (cookiesTrigger) {
+
+ cookiesTrigger.addEventListener('click', () => {
+ cookies.classList.add('active');
+ });
+
+ };
+
+ if (cookies) {
+
+ cookiesBtn.addEventListener('click', () => {
+ cookies.classList.remove('active');
+ });
+
+ };
+
+ }
+
+
+ // карта на странице карт;
+ /*
+ //setGeneralMap() {
+
+ if (document.querySelector('#general-map')) {
+
+ ymaps.ready(init); // Дождёмся загрузки API и готовности DOM;
+
+ function init() {
+
+ const myMap = new ymaps.Map('general-map', { // Создание экземпляра карты и его привязка к контейнеру с заданным id;
+ center: [55.752933963675126, 37.52233749962665], // При инициализации карты обязательно нужно указать её центр и коэффициент масштабирования;
+ zoom: 10,
+ controls: [] // Скрываем элементы управления на карте;
+ });
+
+ // Создаём макет содержимого.
+ const MyIconContentLayout = ymaps.templateLayoutFactory.createClass(
+ '$[properties.iconContent]
'
+ );
+
+ let collection = new ymaps.GeoObjectCollection(null, { // Создаём коллекцию, в которую будемпомещать метки (что-то типа массива);
+ // preset: 'islands#yellowIcon'
+ });
+
+ let collectionCoords = [ // Создаём массив с координатами (координаты должны располагаться в том же порядке, что и адреса в списке на сайте);
+ [55.867783219108354, 37.392867499999916],
+ [55.728043075486504, 37.73937949999994],
+ [55.72624100423305, 37.476078499999964],
+ [55.80751105044832, 37.449622999999974],
+ [55.601783098948836, 37.36700499999998],
+ [55.86086502152225, 37.540348999999964],
+ [55.784961528728715, 37.56188599999996],
+ [55.63910010399773, 37.319407999999996],
+ [55.55819256767507, 37.55711549999994],
+ [55.79829252928473, 37.52063549999999],
+ ];
+
+ for (let i = 0, l = collectionCoords.length; i < l; i++) { // C помощью цикла добавляем все метки в коллекцию;
+ collection.add(new ymaps.Placemark(collectionCoords[i]));
+ collection.get(i).properties.set('iconContent', `${i + 1}`); // Добавляем каждой метке порядковый номер, записываем его в свойство 'iconContent';
+ }
+
+ myMap.geoObjects.add(collection); // Добавляем коллекцию с метками на карту;
+
+ collection.options.set('iconLayout', 'default#imageWithContent'); // Необходимо указать данный тип макета;
+ collection.options.set('iconImageHref', 'images/mark-complex.svg'); // Своё изображение иконки метки;
+ collection.options.set('iconImageSize', [52, 67]); // Размеры метки;
+ collection.options.set('iconImageOffset', [-26, -67]); // Смещение левого верхнего угла иконки относительно её "ножки" (точки привязки);
+ collection.options.set('iconContentOffset', [0, 17]);
+ collection.options.set('iconContentLayout', MyIconContentLayout); // Смещение левого верхнего угла иконки относительно её "ножки" (точки привязки);
+
+ const pageMapBar = document.querySelector('.js_page_map_bar');
+ const pageMapBarBtn = pageMapBar.querySelector('.js_page_map_bar_btn');
+ const pageMapBarList = pageMapBar.querySelector('.js_page_map_bar_list');
+ const pageMapBarCards = pageMapBar.querySelectorAll('.card-news');
+
+ const showCard = (i) => {
+
+ pageMapBarCards.forEach((card, k) => {
+
+ card.classList.remove('active');
+
+ if (i == k) {
+ card.classList.add('active');
+ }
+
+ });
+
+ };
+
+ const hidecard = () => {
+
+ pageMapBarCards.forEach(card => {
+ card.classList.remove('active');
+ });
+
+ }
+
+ let pageMapBarItems;
+
+ pageMapBarBtn.addEventListener('click', () => {
+ pageMapBar.classList.toggle('active');
+ });
+
+ pageMapBarList.addEventListener('click', (e) => {
+
+ if (e.target.closest('.page-map-bar__item')) {
+
+ pageMapBarItems = pageMapBarList.querySelectorAll('.page-map-bar__item');
+
+ pageMapBarItems.forEach((item, i) => {
+
+ if (e.target == item && e.target.classList.contains('active')) {
+
+ item.classList.remove('active');
+
+ hidecard();
+
+ } else if (e.target == item) {
+
+ pageMapBarItems.forEach(item => {
+ item.classList.remove('active');
+ });
+
+ item.classList.add('active');
+
+ let offsetCoords = collection.get(i).geometry.getCoordinates();
+
+ offsetCoords = [
+ offsetCoords[0] - 0.0025,
+ offsetCoords[1]
+ ];
+
+ myMap.setZoom(16);
+ // myMap.setCenter(collection.get(i).geometry.getCoordinates());
+ myMap.setCenter(offsetCoords);
+
+ showCard(i);
+
+ }
+
+ });
+ }
+
+ });
+
+ collection.events.add('click', function (e) {
+
+ for (let i = 0, l = collection.getLength(); i < l; i++) {
+
+ if (e.get('target') == collection.get(i)) {
+
+ pageMapBarItems = pageMapBarList.querySelectorAll('.page-map-bar__item');
+
+ pageMapBarItems.forEach((item) => {
+ pageMapBar.classList.add('active');
+ item.classList.remove('active');
+ });
+
+ pageMapBarItems[i].classList.add('active');
+
+ showCard(i);
+
+ }
+
+ }
+
+ });
+
+ }
+
+ }
+
+ };*/
+
+
+ // аккордеон в футере
+ setFooterSpoilers() {
+
+ const items = document.querySelectorAll('.js_footer_col');
+
+ items.forEach(item => {
+
+ const itemTitle = item.querySelector('.js_footer_caption');
+ const itemContent = item.querySelector('.js_footer_block');
+
+ const blockToggle = (block, duration) => {
+
+ if (window.getComputedStyle(block).display == "none" && !block.classList.contains('smooth')) {
+
+ block.style.display = "block";
+
+ const blockHeight = block.offsetHeight;
+
+ block.style.height = 0;
+ block.style.overflow = "hidden";
+ block.style.transition = `height ${duration}ms ease`;
+ block.classList.add('smooth');
+ block.offsetHeight;
+ block.style.height = `${blockHeight}px`;
+
+ setTimeout(() => {
+
+ block.classList.remove('smooth');
+ block.style.height = '';
+ block.style.transition = '';
+ block.style.overflow = '';
+
+ }, duration);
+
+ } else if (!block.classList.contains('smooth')) {
+
+ block.style.height = `${block.offsetHeight}px`;
+ block.offsetHeight;
+ block.style.height = 0;
+ block.style.overflow = "hidden";
+ block.style.transition = `height ${duration}ms ease`;
+ block.classList.add('smooth');
+
+ setTimeout(() => {
+
+ block.classList.remove('smooth');
+ block.style.display = "none";
+ block.style.height = '';
+ block.style.transition = '';
+ block.style.overflow = '';
+
+ }, duration);
+
+ }
+
+ };
+
+ itemTitle.addEventListener('click', (e) => {
+ itemTitle.classList.toggle('active');
+ blockToggle(itemContent, 300);
+ });
+
+ });
+
+ }
+
+
+ // слайдер с партнёрами;
+ initPartnerslSlider() {
+
+ const slider = document.querySelector('.partners__swiper');
+
+ if (slider) {
+
+ let swiper6;
+
+ const initSlider = () => {
+
+ swiper6 = new Swiper(slider, {
+ // scrollbar: {
+ // el: '.swiper-scrollbar',
+ // draggable: true,
+ // },
+ slidesPerView: 0.275,
+ loop: true,
+ spaceBetween: 20,
+ freeMode: true,
+ allowTouchMove: true,
+ breakpoints: {
+ 480: {
+ slidesPerView: 0.4,
+ },
+ 640: {
+ slidesPerView: 0.65,
+ },
+ 780: {
+ slidesPerView: 0.65,
+ },
+ 1024: {
+ slidesPerView: 0.8,
+ },
+ 1200: {
+ slidesPerView: 1,
+ loop: false,
+ allowTouchMove: false,
+ }
+ }
+ });
+
+ };
+
+ initSlider();
+
+ const updateSlider = () => {
+ swiper6.destroy();
+ initSlider();
+ }
+
+ window.addEventListener('resize', () => {
+
+ if (window.innerWidth <= 1200 && slider.dataset.mobile == 'false') {
+ slider.dataset.mobile = 'true';
+ updateSlider();
+ }
+
+ if (window.innerWidth > 1200 && slider.dataset.mobile == 'true') {
+ slider.dataset.mobile = 'false';
+ updateSlider();
+ }
+
+ });
+
+ }
+
+ }
+
+}
+
+
+document.addEventListener('DOMContentLoaded', () => {
+
+ const app = new App();
+ app.init();
+
+});
diff --git a/public/js/main_new.js b/public/js/main_new.js
deleted file mode 100644
index 6e31ea9..0000000
--- a/public/js/main_new.js
+++ /dev/null
@@ -1,1508 +0,0 @@
-// управляющий класс App с методом init(), в котором собраны все используемые методы с комментариями о том, что конкретно делает каждый метод
-
-class App {
-
- constructor() {
- this.patternPhone = /^(\+7|7|8)?[\s\-]?\(?[489][0-9]{2}\)?[\s\-]?[0-9]{3}[\s\-]?[0-9]{2}[\s\-]?[0-9]{2}$/; // рег. выражение для поля 'телефон';
- this.patternEmail = /^[a-zA-Z0-9._%+-\.]+@[a-z0-9.-]+\.[a-z]{2,}$/i; // рег. выражение для поля 'электронная почта';
- }
-
- init() {
-
- console.log('init');
-
- this.stickyHeader(); // липкий хедер;
- this.controlBurgerMenu(); // бургер-меню;
- this.smoothScroll(); // плавный скролл к якорю (smooth scroll);
- this.scrollUp(); // кнопка наверх;
- this.addToFavorites(); // добавить в избранное (звёздочка);
- this.initTypicalSlider(); // типовые слайдеры;
- this.initPartnerslSlider(); // слайдер с партнёрами;
- this.controlFilters(); // фильтры на главном экране;
- this.controlPopups(); // открытие/закрытие поп-апов;
- this.controlContactUsPopup(); // открытие/закрытие поп-апа 'обратный звонок';
-
- this.sendForm('.js_popup_feedback_form', '[data-popup="success"]'); // отправка формы в поп-апе обратной связи;
- this.sendForm('.js_popup_viewing_form', '[data-popup="success"]'); // отправка формы в поп-апе 'записаться на просмотр';
- this.sendForm('.js_footer_feedback_form', '[data-popup="success"]'); // отправка формы в футере;
- this.sendForm('.js_contacts_form', '.js_contacts_success'); // отправка формы на странице контакты;
- this.sendForm('.js_popup_sending_form_', '[data-popup="success"]');
- //this.sendOffer(); //отправка предложения по e-mail;
-
- //this.setGeneralMap(); // карта на странице карт;
- this.setComplexMap('complex-map', [55.726591050908745, 37.57244549999999], 'ЖК Садовые кварталы'); // карта на странице 'ЖК';
- this.setComplexMap('offer-map', [55.70851106903402, 37.65864349999999], 'Аренда торгового помещения 321,6 м2'); // карта на странице 'Предложение';
- this.setCatalogSorts(); // сортировка на странице 'каталог';
- this.initIntroSlider(); // слайдер на странице жк и на странице предложения;
- this.setTabs('.js_offer_side_tab', '.js_offer_side_item'); // табы с планами объекат и этажа на странице предложения;
- this.setTabs('.js_offer_side_popup_tab', '.js_offer_side_popup_item'); // табы с планами объекат и этажа в поп-апе на странице предложения;
- this.sontrolOfferSidePopup(); // логика открытия нужного таба при открытии поп-апа с планами объекат и этажа на странице предложения;
- this.setCustomGallery(); // галлерея;
- this.setCookies() // куки;
- this.setFooterSpoilers() // аккордеон в футере;
-
- }
-
- // фиксация
- fixBodyPosition() {
-
- setTimeout(function () {
- // ставим необходимую задержку, чтобы не было «конфликта» в случае, если функция фиксации вызывается сразу после расфиксации (расфиксация отменяет действия расфиксации из-за одновременного действия)
-
- if (!document.body.hasAttribute('data-body-scroll-fix')) {
-
- // получаем позицию прокрутки
- let scrollPosition = window.pageYOffset || document.documentElement.scrollTop;
-
- // ставим нужные стили
- document.body.setAttribute('data-body-scroll-fix', scrollPosition); // Cтавим атрибут со значением прокрутки
- document.body.style.overflow = 'hidden';
- document.body.style.position = 'fixed';
- document.body.style.top = '-' + scrollPosition + 'px';
- document.body.style.left = '0';
- document.body.style.width = '100%';
-
- if (window.innerWidth >= 1200) {
- document.body.style.paddingRight = '8px';
- }
- }
-
- }, 15); // можно задержку ещё меньше, но работает хорошо именно с этим значением на всех устройствах и браузерах
-
- }
-
-
- // расфиксация
- unfixBodyPosition() {
-
- if (document.body.hasAttribute('data-body-scroll-fix')) {
-
- // получаем позицию прокрутки из атрибута
- let scrollPosition = document.body.getAttribute('data-body-scroll-fix');
-
- // удаляем атрибут
- document.body.removeAttribute('data-body-scroll-fix');
-
- // удаляем ненужные стили
- document.body.style.overflow = '';
- document.body.style.position = '';
- document.body.style.top = '';
- document.body.style.left = '';
- document.body.style.width = '';
- document.body.style.paddingRight = '';
-
- // прокручиваем страницу на полученное из атрибута значение
- window.scroll(0, scrollPosition);
-
- }
-
- }
-
-
- // бургер-меню
- controlBurgerMenu() {
-
- const headerBurger = document.querySelector('.js_header_burger');
-
- if (headerBurger) {
-
- const menu = document.querySelector('.js_menu');
- const menuClose = menu.querySelector('.js_menu_close');
-
- headerBurger.addEventListener('click', () => {
- menu.classList.add('active');
- this.fixBodyPosition();
- });
-
- menu.addEventListener('click', (e) => {
-
- if (e.target == menu) {
- menu.classList.remove('active');
- this.unfixBodyPosition();
- }
-
- });
-
- menuClose.addEventListener('click', () => {
- menu.classList.remove('active');
- this.unfixBodyPosition();
- });
-
- }
-
- }
-
-
- // липкий хедер
- stickyHeader() {
-
- const header = document.querySelector('.js_header');
-
- if (header) {
-
- window.addEventListener('scroll', () => {
-
- if (window.scrollY > 200) {
- header.classList.add('fixed');
- } else {
- header.classList.remove('fixed');
- }
-
- });
-
- };
-
- }
-
-
- // плавный скролл к якорю (smooth scroll)
- smoothScroll() {
-
- const smoothLinks = document.querySelectorAll('.js_smooth_link');
-
- if (smoothLinks.length) {
-
- smoothLinks.forEach(link => {
-
- link.addEventListener('click', function (e) {
-
- e.preventDefault();
-
- let href = this.getAttribute('href').substring(1);
-
- const scrollTarget = document.getElementById(href);
-
- // const topOffset = document.querySelector('.header').offsetHeight;
- const topOffset = 0; // если не нужен отступ сверху
- const elementPosition = scrollTarget.getBoundingClientRect().top;
- const offsetPosition = elementPosition - topOffset;
-
- window.scrollBy({
- top: offsetPosition,
- behavior: 'smooth'
- });
-
- });
-
- });
-
- }
-
- }
-
-
- // кнопка наверх
- scrollUp() {
-
- const toTopBtn = document.querySelector('.js_btn_up');
-
- if (toTopBtn) {
-
- toTopBtn.addEventListener('click', function () {
-
- window.scrollTo({
- top: 0,
- behavior: 'smooth'
- });
-
- });
-
- }
-
- }
-
-
- // добавить в избранное (звёздочка)
- addToFavorites() {
-
- const cardFavorites = document.querySelectorAll('.js_card_favorites');
-
- if (cardFavorites.length) {
-
- cardFavorites.forEach(item => {
-
- item.addEventListener('click', (e) => {
- e.preventDefault();
- item.classList.toggle('active');
- });
-
- });
-
- }
-
- }
-
-
- // типовые слайдеры
- initTypicalSlider() {
-
- const slidersWraps = document.querySelectorAll('.slider__wrap');
-
- if (slidersWraps.length) {
-
- slidersWraps.forEach(wrap => {
-
- const slider = wrap.querySelector('.swiper');
- const prev = wrap.querySelector('.swiper-button-prev');
- const next = wrap.querySelector('.swiper-button-next');
- const pagination = wrap.querySelector('.swiper-pagination');
-
- let swiper1 = new Swiper(slider, {
- navigation: {
- nextEl: next,
- prevEl: prev,
- },
- pagination: {
- el: pagination,
- clickable: true,
- },
- slidesPerView: 1,
- spaceBetween: 20,
- observer: true,
- observeParents: true,
- observeSlideChildren: true,
- breakpoints: {
- 480: {
- slidesPerView: 1.5,
- },
- 640: {
- slidesPerView: 2,
- },
- 780: {
- slidesPerView: 2.5,
- },
- 920: {
- slidesPerView: 3,
- },
- 1024: {
- slidesPerView: 3.4
- },
- 1200: {
- slidesPerView: 4,
- }
- }
- });
-
- });
-
- }
-
- }
-
-
- // метод, делающий число удобночитаемым (добавляет пробел справа через каждые 3 цифры)
- prettify(num) {
- const withoutSpace = num.replace(/[^\d]/g, ''); //убирает все символы;
- return withoutSpace.replace(/(?!^)(?=(?:\d{3})+(?:\.|$))/gm, ' '); //ставит пробелы;
- }
-
-
- // фильтры на главном экране
- controlFilters() {
-
- const heroFilters = document.querySelectorAll('.js_hero_filter');
- const heroSearchBtns = document.querySelectorAll('.js_hero_search_btn');
-
- if (heroFilters.length) {
-
- heroFilters.forEach(filter => {
-
- const heroFilterInput = filter.querySelector('.js_hero_filter_input');
- const heroFilterCurrent = filter.querySelector('.js_hero_filter_current');
- const heroFilterItems = filter.querySelectorAll('.hero-filter__item');
- const heroFilterFields = filter.querySelectorAll('.js_hero_filter_field');
- const heroFilterFrom = filter.querySelector('.js_hero_filter_from');
- const heroFilterTo = filter.querySelector('.js_hero_filter_to');
- const heroFilterReset = filter.querySelector('.js_hero_filter_reset');
-
- heroFilterCurrent.addEventListener('click', () => {
-
- if (filter.classList.contains('active')) {
-
- filter.classList.remove('active');
-
- heroSearchBtns.forEach(btn => {
- btn.disabled = false;
- });
-
- } else {
-
- heroFilters.forEach(filter => {
- filter.classList.remove('active');
- });
-
- filter.classList.add('active');
-
- heroSearchBtns.forEach(btn => {
- btn.disabled = true;
- });
-
- }
-
- });
-
- if (heroFilterItems.length) {
-
- heroFilterItems.forEach(item => {
-
- item.addEventListener('click', () => {
-
- heroFilterCurrent.textContent = item.textContent;
- heroFilterInput.value = item.dataset.val;
- filter.classList.remove('active');
-
- heroSearchBtns.forEach(btn => {
- btn.disabled = false;
- });
-
- });
-
- });
-
- }
-
- if (heroFilterFields.length) {
-
- const heroFilterMin = heroFilterFrom.dataset.min;
- const heroFilterMax = heroFilterTo.dataset.max;
-
- let heroFilterFromVal;
- let heroFilterToVal;
-
- heroFilterFields.forEach(field => {
-
- field.addEventListener('input', () => {
-
- field.value = this.prettify(field.value);
-
- heroFilterReset.classList.remove('active');
-
- heroFilterFields.forEach(field => {
-
- if (field.value != "") {
- heroFilterReset.classList.add('active');
- }
-
- });
-
- });
-
- });
-
- heroFilterFrom.addEventListener('change', () => {
-
- heroFilterFromVal = +heroFilterFrom.value.replace(/\s/g, '');
- heroFilterToVal = +heroFilterTo.value.replace(/\s/g, '');
-
- if (heroFilterToVal != '' && heroFilterFromVal > heroFilterToVal) {
-
- heroFilterFrom.value = heroFilterTo.value;
-
- } else if (heroFilterFromVal < +heroFilterMin) {
-
- heroFilterFrom.value = this.prettify(heroFilterMin);
-
- } else if (heroFilterFromVal > +heroFilterMax) {
-
- heroFilterFrom.value = this.prettify(heroFilterMax);
-
- }
-
- });
-
- heroFilterTo.addEventListener('change', () => {
-
- heroFilterFromVal = +heroFilterFrom.value.replace(/\s/g, '');
- heroFilterToVal = +heroFilterTo.value.replace(/\s/g, '');
-
- if (heroFilterFromVal != '' && heroFilterToVal < heroFilterFromVal) {
-
- heroFilterTo.value = heroFilterFrom.value;
-
- } else if (heroFilterToVal < +heroFilterMin) {
-
- heroFilterTo.value = this.prettify(heroFilterMax);
-
- } else if (heroFilterToVal > +heroFilterMax) {
-
- heroFilterTo.value = this.prettify(heroFilterMax);
-
- }
-
- });
-
- heroFilterReset.addEventListener('click', () => {
-
- heroFilterFields.forEach(field => {
- field.value = '';
- });
-
- heroFilterReset.classList.remove('active');
-
- });
- }
-
- });
-
- document.addEventListener('click', (e) => {
-
- if (!e.target.closest('.js_hero_filter_dropdown') && !e.target.closest('.js_hero_filter_current')) {
-
- heroFilters.forEach(filter => {
- filter.classList.remove('active');
- });
-
- heroSearchBtns.forEach(btn => {
- btn.disabled = false;
- });
-
- }
-
- });
-
- }
-
- }
-
-
- // открытие/закрытие типовых поп-апов
- controlPopups() {
-
- const popupShowBtns = document.querySelectorAll('[data-btn]');
- const popups = document.querySelectorAll('[data-popup]');
-
- if (popupShowBtns.length) {
-
- popupShowBtns.forEach(btn => {
-
- btn.addEventListener('click', (e) => {
-
- e.preventDefault();
-
- popups.forEach(popup => {
-
- popup.classList.remove('active'); // если какойто поп-ап открыт, то закрываем его;
- this.unfixBodyPosition();
-
- if (btn.dataset.btn == popup.dataset.popup) {
- popup.classList.add('active');
- this.fixBodyPosition();
- }
-
- });
-
-
- });
-
- });
-
- popups.forEach(popup => {
-
- const popupCloseBtns = popup.querySelectorAll('.js_popup_close');
-
- popupCloseBtns.forEach(btn => {
-
- btn.addEventListener('click', (e) => {
- e.preventDefault();
- popup.classList.remove('active');
- this.unfixBodyPosition();
- });
-
- });
-
- popup.addEventListener('click', (e) => {
-
- if (e.target == popup) {
-
- popup.classList.remove('active');
- this.unfixBodyPosition();
- }
-
- });
-
- });
-
- }
- }
-
-
- // открытие/закрытие поп-апа 'обратный звонок'
- controlContactUsPopup() {
-
- const contactUsBtn = document.querySelector('.js_btn_contact_us');
- const contactUsPopup = document.querySelector('.js_contact_us');
-
- if (contactUsPopup) {
-
- const contactUsPopupCloseBtns = contactUsPopup.querySelectorAll('.js_contact_us_close');
-
- contactUsBtn.addEventListener('click', (e) => {
-
- e.preventDefault();
-
- if (contactUsPopup.classList.contains('active')) {
- contactUsPopup.classList.remove('active');
- } else {
- contactUsPopup.classList.add('active');
- }
-
- });
-
- contactUsPopupCloseBtns.forEach(btn => {
- btn.addEventListener('click', () => {
- contactUsPopup.classList.remove('active');
- });
- });
-
-
- document.addEventListener('click', (e) => {
-
- if (!e.target.closest('.js_contact_us') && !e.target.closest('.js_btn_contact_us')) {
- contactUsPopup.classList.remove('active');
- }
-
- });
-
- }
-
- }
-
-
- // валидатор форм
- validateForm(input) {
-
- // функция добавления ошибки
- const createError = (text) => {
-
- input.classList.add('error');
- input.classList.remove('no-error');
-
- if (input.closest('label').querySelector('span.error')) {
- input.closest('label').querySelector('span.error').remove();
- input.closest('label').insertAdjacentHTML('beforeend', `${text}`);
- } else {
- input.closest('label').insertAdjacentHTML('beforeend', `${text}`);
- }
-
- }
-
- // функция удаления ошибки
- const removeError = () => {
-
- input.classList.remove('error');
- input.classList.add('no-error');
-
- if (input.closest('label').querySelector('span.error')) {
- input.closest('label').querySelector('span.error').remove();
- }
-
- }
-
- // проверяем на правильность заполнения поля 'Телефон'
- if (input.classList.contains('js_input_phone') && input.value == "") {
- createError('Заполните, пожалуйста, поле');
- } else if (input.classList.contains('js_input_phone') && input.value.search(this.patternPhone) == 0) {
- removeError();
- } else if (input.classList.contains('js_input_phone')) {
- createError('Укажите, пожалуйста, корректный телефон');
- }
-
- // проверяем правильность заполнения поля 'Электронная почта'
- if (input.classList.contains('js_input_email') && input.value == "") {
- createError('Заполните, пожалуйста, поле');
- } else if (input.classList.contains('js_input_email') && input.value.search(this.patternEmail) == 0) {
- removeError();
- } else if (input.classList.contains('js_input_email')) {
- createError('Укажите, пожалуйста, корректный e-mail');
- }
-
- }
-
-
- // отправка форм
- sendForm(formEl, success) {
-
- const form = document.querySelector(formEl);
-
- if (form) {
-
- form.addEventListener('submit', async (e) => {
-
- e.preventDefault();
-
- const formInputs = form.querySelectorAll('input');
- const formBtn = form.querySelector('.js_form_btn');
-
- formInputs.forEach(input => { // перебираем все инпуты в форме;
-
- this.validateForm(input);
-
- input.addEventListener('input', () => {
- this.validateForm(input);
- });
-
- });
-
- if (!form.querySelector('.error')) { //проверяем, чтоб все инпуты прошли валидацию (чтоб не было в форме ни одного элемента с класссом error);
-
- // сюда пишем команды, которые должны сработать после успешной валидации;
-
- console.log('validate');
- formBtn.classList.add('btn-animate');
- formBtn.disabled = true;
-
- const formData = new FormData(form);
-
- console.log(...formData);
-
- const response = await fetch(e.target.action, {
- method: e.target.method,
- body: formData
- });
-
- if (response.ok) {
-
- setTimeout(() => { // имитация отправки, когда отправка будет настроена, нужно достать всё из setTimeout() и удалить его;
-
- console.log('Отправлено');
- formBtn.classList.remove('btn-animate');
- formBtn.disabled = false;
- if (document.querySelector('[data-popup="feedback"]')) {
- document.querySelector('[data-popup="feedback"]').classList.remove('active');
- }
- if (document.querySelector('[data-popup="viewing"]')) {
- document.querySelector('[data-popup="viewing"]').classList.remove('active');
- }
- document.querySelector(success).classList.add('active');
- this.fixBodyPosition();
- form.reset();
-
- formInputs.forEach(input => {
- input.classList.remove('no-error');
- });
-
- }, 2000)
-
- } else {
- formBtn.classList.remove('btn-animate');
- formBtn.disabled = false;
- alert('Ошибка');
- }
-
- } else {
- console.log('no-validate');
- form.querySelector('.error').focus(); //фокус к полю с ошибкой;
- }
-
- });
-
- }
-
- }
-
- //отправка предложения по e-mail
- sendOffer() {
-
- const form = document.querySelector('.js_popup_sending_form');
-
- if (form) {
-
- form.addEventListener('submit', async (e) => {
-
- e.preventDefault();
-
- const formInputs = form.querySelectorAll('input');
- const formBtn = form.querySelector('.js_form_btn');
-
- formInputs.forEach(input => { // перебираем все инпуты в форме;
-
- this.validateForm(input);
-
- input.addEventListener('input', () => {
- this.validateForm(input);
- });
-
- });
-
- if (!form.querySelector('.error')) { //проверяем, чтоб все инпуты прошли валидацию (чтоб не было в форме ни одного элемента с класссом error);
-
- // сюда пишем команды, которые должны сработать после успешной валидации;
-
- console.log('validate');
- formBtn.classList.add('btn-animate');
- formBtn.disabled = true;
-
- const formData = new FormData(form);
-
- console.log(...formData);
-
- const response = await fetch(e.target.action, {
- method: e.target.method,
- body: formData
- });
-
- if (response.ok) {
-
- setTimeout(() => { // имитация отправки, когда отправка будет настроена, нужно достать всё из setTimeout() и удалить его;
-
- console.log('Отправлено');
- formBtn.classList.remove('btn-animate');
- formBtn.disabled = false;
- if (document.querySelector('[data-popup="sending"]')) {
- document.querySelector('[data-popup="sending"]').classList.remove('active');
- }
- this.fixBodyPosition();
- form.reset();
-
- formInputs.forEach(input => {
- input.classList.remove('no-error');
- });
-
- }, 2000)
-
- } else {
- formBtn.classList.remove('btn-animate');
- formBtn.disabled = false;
- alert('Ошибка');
- }
-
- } else {
- console.log('no-validate');
- form.querySelector('.error').focus(); //фокус к полю с ошибкой;
- }
-
- });
-
- }
-
- }
-
-
- // карта на странице 'ЖК'
- setComplexMap(id, coords, caption) {
-
- if (document.querySelector('#' + id)) {
-
- // Дождёмся загрузки API и готовности DOM.
- ymaps.ready(init);
-
- function init() {
- const map = new ymaps.Map(id, {
- // При инициализации карты обязательно нужно указать её центр и коэффициент масштабирования.
- center: coords,
- zoom: 16,
- controls: []
- });
-
- // Создаём макет содержимого.
- const MyIconContentLayout = ymaps.templateLayoutFactory.createClass(
- '$[properties.iconContent]
'
- );
-
- // Создание макета содержимого хинта.
- // Макет создается через фабрику макетов с помощью текстового шаблона.
- const HintLayout = ymaps.templateLayoutFactory.createClass("" +
- "{{ properties.object }}" + "
", {
- // Определяем метод getShape, который
- // будет возвращать размеры макета хинта.
- // Это необходимо для того, чтобы хинт автоматически
- // сдвигал позицию при выходе за пределы карты.
- getShape: function () {
- let el = this.getElement(),
- result = null;
- if (el) {
- var firstChild = el.firstChild;
- result = new ymaps.shape.Rectangle(
- new ymaps.geometry.pixel.Rectangle([
- [0, 0],
- [firstChild.offsetWidth, firstChild.offsetHeight]
- ])
- );
- }
- return result;
- }
- }
- );
-
- // метка
- const placemark = new ymaps.Placemark(coords, {
- // hintContent: caption,
- // balloonContent: caption,
- iconContent: '1',
- // address: caption,
- object: caption
- }, {
- iconLayout: 'default#imageWithContent',
- iconImageHref: 'images/mark-complex.svg',
- iconImageSize: [52, 67],
- iconImageOffset: [-26, -67],
- iconContentOffset: [0, 17],
- iconContentLayout: MyIconContentLayout,
- hintLayout: HintLayout
- });
-
- map.geoObjects.add(placemark);
-
- }
-
- }
-
- }
-
-
- // фильтры и сортировка на странице 'каталог'
- setCatalogSorts() {
-
- const sortGroups = document.querySelectorAll('.js_sort_group');
-
- if (sortGroups.length) {
-
- sortGroups.forEach(group => {
-
- const sortGroupInput = group.querySelector('.js_sort_group_input');
- const sortGroupCurrent = group.querySelector('.js_sort_group_current');
- const sortGroupList = group.querySelector('.js_sort_group_list');
- const sortGroupItems = group.querySelectorAll('.js_sort_group_item');
-
- const sendRequest = () => {
-
- const spinner = document.querySelector('.spinner'); // спиннер;
-
- spinner.classList.add('active');
- document.body.classList.add('overlay');
- /*this.fixBodyPosition();
-
- fetch('test.json')
- .then(response => response.json())
- .then(data => {
-
- console.log()
-
- setTimeout(() => { //имитация ответа сервера
-
- spinner.classList.remove('active');
- document.body.classList.remove('overlay');
- this.unfixBodyPosition();
-
- }, 3000);
-
- })
- .catch(err => {
- console.log(err);
- });
-
- */
- spinner.classList.remove('active');
- document.body.classList.remove('overlay');
-
-
- };
-
- sortGroupCurrent.addEventListener('click', () => {
-
- if (group.classList.contains('active')) {
-
- group.classList.remove('active');
-
- } else {
-
- sortGroups.forEach(group => {
- group.classList.remove('active');
- });
-
- group.classList.add('active');
-
- }
-
- });
-
- sortGroupItems.forEach(item => {
-
- item.addEventListener('click', () => {
-
- sortGroupItems.forEach(item => {
- item.classList.remove('active');
- });
-
- item.classList.add('active');
- sortGroupCurrent.textContent = item.textContent;
- sortGroupInput.value = item.dataset.val;
- group.classList.remove('active');
-
- sendRequest();
-
- });
-
- });
-
- });
-
- document.addEventListener('click', (e) => {
-
- if (!e.target.closest('.js_sort_group_list') && !e.target.closest('.js_sort_group_current')) {
-
- sortGroups.forEach(group => {
- group.classList.remove('active');
- });
-
- }
-
- });
-
- }
-
- }
-
-
- // слайдер на странице жк и на странице предложения
- initIntroSlider() {
-
- let swiper3 = new Swiper('.intro__swiper', {
- navigation: {
- nextEl: '.swiper-button-next',
- prevEl: '.swiper-button-prev',
- },
- pagination: {
- el: '.swiper-pagination',
- clickable: true,
- },
- slidesPerView: 1.1,
- spaceBetween: 20,
- breakpoints: {
- 480: {
- slidesPerView: 1.5,
- },
- 640: {
- slidesPerView: 1.75,
- },
- 780: {
- slidesPerView: 2.15,
- },
- 1024: {
- slidesPerView: 3.5,
- },
- 1200: {
- slidesPerView: 1,
- }
- }
- });
-
- }
-
-
- // табы на странице предложения
- setTabs(tabs, items) {
-
- const offerSideTabs = document.querySelectorAll(tabs);
- const offerSideItems = document.querySelectorAll(items);
-
- if (offerSideTabs) {
-
- offerSideTabs.forEach(tab => {
-
- tab.addEventListener('click', () => {
-
- offerSideTabs.forEach(tab => {
- tab.classList.remove('active');
- });
-
- tab.classList.add('active');
-
- offerSideItems.forEach(item => {
-
- item.classList.remove('active', 'fade');
-
- if (tab.dataset.tab == item.dataset.item) {
- item.classList.add('active', 'fade');
- }
-
- });
-
- });
-
- });
-
- }
-
- }
-
-
- // логика открытия нужного таба при открытии поп-апа с планами объекат и этажа на странице предложения
- sontrolOfferSidePopup() {
-
- const offerSideItems = document.querySelectorAll('.js_offer_side_item');
- const offerSidePopupTabs = document.querySelectorAll('.js_offer_side_popup_tab');
- const offerSidePopupItems = document.querySelectorAll('.js_offer_side_popup_item');
-
- if (offerSideItems) {
-
- offerSideItems.forEach(item => {
-
- const offerSideItemBtn = item.querySelector('.js_offer_side_item_btn');
-
- offerSideItemBtn.addEventListener('click', (e) => {
-
- e.preventDefault();
-
- offerSidePopupTabs.forEach(tab => {
-
- tab.classList.remove('active');
-
- if (item.dataset.item == tab.dataset.tab) {
- tab.classList.add('active');
- }
-
- });
-
- offerSidePopupItems.forEach(el => {
-
- el.classList.remove('active', 'fade');
-
- if (item.dataset.item == el.dataset.item) {
- el.classList.add('active', 'fade');
- }
-
- });
-
- });
-
- });
-
- }
-
- }
-
-
- // галлерея
- setCustomGallery() {
-
- let swiper4 = new Swiper(".img-viewer__thumbs-swiper", {
- slidesPerView: 3,
- spaceBetween: 8,
- // freeMode: true,
- observer: true,
- observeParents: true,
- observeSlideChildren: true,
- breakpoints: {
- 640: {
- spaceBetween: 10,
- },
- },
- });
-
- let swiper5 = new Swiper(".img-viewer__slider .swiper", {
- navigation: {
- nextEl: ".img-viewer__slider .swiper-button-next",
- prevEl: ".img-viewer__slider .swiper-button-prev",
- },
- slidesPerView: 1,
- spaceBetween: 20,
- thumbs: {
- swiper: swiper4
- },
- observer: true,
- observeParents: true,
- observeSlideChildren: true,
- });
-
- if (document.querySelector('.js_intro_item_btn')) {
-
- const imgViewer = document.querySelector('.js_img_viewer');
- const imgViewerCloses = imgViewer.querySelectorAll('.js_img_viewer_close');
- const imgViewerCaption = imgViewer.querySelector('.js_img_viewer_caption');
-
- const imgViewerSliderSwiper = imgViewer.querySelector('.js_img_viewer_slider_swiper');
- const imgViewerSliderSwiperWrap = imgViewerSliderSwiper.querySelector('.js_img_viewer_slider_swiper .swiper-wrapper');
-
- const imgViewerThumbsSwiper = imgViewer.querySelector('.js_img_viewer_thumbs_swiper');
- const imgViewerThumbsSwiperWrap = imgViewerThumbsSwiper.querySelector('.js_img_viewer_thumbs_swiper .swiper-wrapper');
-
- const introItemBtns = document.querySelectorAll('.js_intro_item_btn');
-
- introItemBtns.forEach((btn, i) => {
-
- btn.addEventListener('click', (e) => {
-
- e.preventDefault();
-
- imgViewer.classList.add('active');
- this.fixBodyPosition();
-
- imgViewerSliderSwiperWrap.innerHTML = '';
- imgViewerThumbsSwiperWrap.innerHTML = '';
- imgViewerCaption.textContent = '';
-
-
- introItemBtns.forEach(btn => {
-
- imgViewerSliderSwiperWrap.insertAdjacentHTML('beforeend', `
-
-
-
`
- );
-
- imgViewerThumbsSwiperWrap.insertAdjacentHTML('beforeend', `
-
-
-
`
- );
-
- });
-
- swiper4.update();
- swiper5.update();
- swiper5.slideTo(i);
- imgViewerCaption.textContent = btn.dataset.caption;
-
- });
-
- });
-
- swiper5.on('slideChange', function () {
- imgViewerCaption.textContent = introItemBtns[swiper5.realIndex].dataset.caption;
- });
-
- imgViewerCloses.forEach(close => {
-
- close.addEventListener('click', () => {
-
- imgViewer.classList.remove('active');
- this.unfixBodyPosition();
-
- });
-
- });
-
- }
-
- }
-
-
- // куки
- setCookies() {
-
- const cookies = document.querySelector('.js_cookies');
- const cookiesBtn = document.querySelector('.js_cookies_confirm');
- const cookiesTrigger = document.querySelector('.js_btn_cookies');
-
- if (cookiesTrigger) {
-
- cookiesTrigger.addEventListener('click', () => {
- cookies.classList.add('active');
- });
-
- };
-
- if (cookies) {
-
- cookiesBtn.addEventListener('click', () => {
- cookies.classList.remove('active');
- });
-
- };
-
- }
-
-
- // карта на странице карт;
- /*
- //setGeneralMap() {
-
- if (document.querySelector('#general-map')) {
-
- ymaps.ready(init); // Дождёмся загрузки API и готовности DOM;
-
- function init() {
-
- const myMap = new ymaps.Map('general-map', { // Создание экземпляра карты и его привязка к контейнеру с заданным id;
- center: [55.752933963675126, 37.52233749962665], // При инициализации карты обязательно нужно указать её центр и коэффициент масштабирования;
- zoom: 10,
- controls: [] // Скрываем элементы управления на карте;
- });
-
- // Создаём макет содержимого.
- const MyIconContentLayout = ymaps.templateLayoutFactory.createClass(
- '$[properties.iconContent]
'
- );
-
- let collection = new ymaps.GeoObjectCollection(null, { // Создаём коллекцию, в которую будемпомещать метки (что-то типа массива);
- // preset: 'islands#yellowIcon'
- });
-
- let collectionCoords = [ // Создаём массив с координатами (координаты должны располагаться в том же порядке, что и адреса в списке на сайте);
- [55.867783219108354, 37.392867499999916],
- [55.728043075486504, 37.73937949999994],
- [55.72624100423305, 37.476078499999964],
- [55.80751105044832, 37.449622999999974],
- [55.601783098948836, 37.36700499999998],
- [55.86086502152225, 37.540348999999964],
- [55.784961528728715, 37.56188599999996],
- [55.63910010399773, 37.319407999999996],
- [55.55819256767507, 37.55711549999994],
- [55.79829252928473, 37.52063549999999],
- ];
-
- for (let i = 0, l = collectionCoords.length; i < l; i++) { // C помощью цикла добавляем все метки в коллекцию;
- collection.add(new ymaps.Placemark(collectionCoords[i]));
- collection.get(i).properties.set('iconContent', `${i + 1}`); // Добавляем каждой метке порядковый номер, записываем его в свойство 'iconContent';
- }
-
- myMap.geoObjects.add(collection); // Добавляем коллекцию с метками на карту;
-
- collection.options.set('iconLayout', 'default#imageWithContent'); // Необходимо указать данный тип макета;
- collection.options.set('iconImageHref', 'images/mark-complex.svg'); // Своё изображение иконки метки;
- collection.options.set('iconImageSize', [52, 67]); // Размеры метки;
- collection.options.set('iconImageOffset', [-26, -67]); // Смещение левого верхнего угла иконки относительно её "ножки" (точки привязки);
- collection.options.set('iconContentOffset', [0, 17]);
- collection.options.set('iconContentLayout', MyIconContentLayout); // Смещение левого верхнего угла иконки относительно её "ножки" (точки привязки);
-
- const pageMapBar = document.querySelector('.js_page_map_bar');
- const pageMapBarBtn = pageMapBar.querySelector('.js_page_map_bar_btn');
- const pageMapBarList = pageMapBar.querySelector('.js_page_map_bar_list');
- const pageMapBarCards = pageMapBar.querySelectorAll('.card-news');
-
- const showCard = (i) => {
-
- pageMapBarCards.forEach((card, k) => {
-
- card.classList.remove('active');
-
- if (i == k) {
- card.classList.add('active');
- }
-
- });
-
- };
-
- const hidecard = () => {
-
- pageMapBarCards.forEach(card => {
- card.classList.remove('active');
- });
-
- }
-
- let pageMapBarItems;
-
- pageMapBarBtn.addEventListener('click', () => {
- pageMapBar.classList.toggle('active');
- });
-
- pageMapBarList.addEventListener('click', (e) => {
-
- if (e.target.closest('.page-map-bar__item')) {
-
- pageMapBarItems = pageMapBarList.querySelectorAll('.page-map-bar__item');
-
- pageMapBarItems.forEach((item, i) => {
-
- if (e.target == item && e.target.classList.contains('active')) {
-
- item.classList.remove('active');
-
- hidecard();
-
- } else if (e.target == item) {
-
- pageMapBarItems.forEach(item => {
- item.classList.remove('active');
- });
-
- item.classList.add('active');
-
- let offsetCoords = collection.get(i).geometry.getCoordinates();
-
- offsetCoords = [
- offsetCoords[0] - 0.0025,
- offsetCoords[1]
- ];
-
- myMap.setZoom(16);
- // myMap.setCenter(collection.get(i).geometry.getCoordinates());
- myMap.setCenter(offsetCoords);
-
- showCard(i);
-
- }
-
- });
- }
-
- });
-
- collection.events.add('click', function (e) {
-
- for (let i = 0, l = collection.getLength(); i < l; i++) {
-
- if (e.get('target') == collection.get(i)) {
-
- pageMapBarItems = pageMapBarList.querySelectorAll('.page-map-bar__item');
-
- pageMapBarItems.forEach((item) => {
- pageMapBar.classList.add('active');
- item.classList.remove('active');
- });
-
- pageMapBarItems[i].classList.add('active');
-
- showCard(i);
-
- }
-
- }
-
- });
-
- }
-
- }
-
- };*/
-
-
- // аккордеон в футере
- setFooterSpoilers() {
-
- const items = document.querySelectorAll('.js_footer_col');
-
- items.forEach(item => {
-
- const itemTitle = item.querySelector('.js_footer_caption');
- const itemContent = item.querySelector('.js_footer_block');
-
- const blockToggle = (block, duration) => {
-
- if (window.getComputedStyle(block).display == "none" && !block.classList.contains('smooth')) {
-
- block.style.display = "block";
-
- const blockHeight = block.offsetHeight;
-
- block.style.height = 0;
- block.style.overflow = "hidden";
- block.style.transition = `height ${duration}ms ease`;
- block.classList.add('smooth');
- block.offsetHeight;
- block.style.height = `${blockHeight}px`;
-
- setTimeout(() => {
-
- block.classList.remove('smooth');
- block.style.height = '';
- block.style.transition = '';
- block.style.overflow = '';
-
- }, duration);
-
- } else if (!block.classList.contains('smooth')) {
-
- block.style.height = `${block.offsetHeight}px`;
- block.offsetHeight;
- block.style.height = 0;
- block.style.overflow = "hidden";
- block.style.transition = `height ${duration}ms ease`;
- block.classList.add('smooth');
-
- setTimeout(() => {
-
- block.classList.remove('smooth');
- block.style.display = "none";
- block.style.height = '';
- block.style.transition = '';
- block.style.overflow = '';
-
- }, duration);
-
- }
-
- };
-
- itemTitle.addEventListener('click', (e) => {
- itemTitle.classList.toggle('active');
- blockToggle(itemContent, 300);
- });
-
- });
-
- }
-
-
- // слайдер с партнёрами;
- initPartnerslSlider() {
-
- const slider = document.querySelector('.partners__swiper');
-
- if (slider) {
-
- let swiper6;
-
- const initSlider = () => {
-
- swiper6 = new Swiper(slider, {
- // scrollbar: {
- // el: '.swiper-scrollbar',
- // draggable: true,
- // },
- slidesPerView: 0.275,
- loop: true,
- spaceBetween: 20,
- freeMode: true,
- allowTouchMove: true,
- breakpoints: {
- 480: {
- slidesPerView: 0.4,
- },
- 640: {
- slidesPerView: 0.65,
- },
- 780: {
- slidesPerView: 0.65,
- },
- 1024: {
- slidesPerView: 0.8,
- },
- 1200: {
- slidesPerView: 1,
- loop: false,
- allowTouchMove: false,
- }
- }
- });
-
- };
-
- initSlider();
-
- const updateSlider = () => {
- swiper6.destroy();
- initSlider();
- }
-
- window.addEventListener('resize', () => {
-
- if (window.innerWidth <= 1200 && slider.dataset.mobile == 'false') {
- slider.dataset.mobile = 'true';
- updateSlider();
- }
-
- if (window.innerWidth > 1200 && slider.dataset.mobile == 'true') {
- slider.dataset.mobile = 'false';
- updateSlider();
- }
-
- });
-
- }
-
- }
-
-}
-
-
-document.addEventListener('DOMContentLoaded', () => {
-
- const app = new App();
- app.init();
-
-});
diff --git a/public/pug/templates/scripts.pug b/public/pug/templates/scripts.pug
index a940c8c..d85015e 100644
--- a/public/pug/templates/scripts.pug
+++ b/public/pug/templates/scripts.pug
@@ -2,4 +2,4 @@
script(src="https://api-maps.yandex.ru/2.1/?lang=ru_RU")
script(src="js/swiper-bundle.min.js")
-script(src="js/main_new.js")
+script(src="js/main_main.js")
diff --git a/resources/views/complex.blade.php b/resources/views/complex.blade.php
index 67a8aaa..ceed184 100644
--- a/resources/views/complex.blade.php
+++ b/resources/views/complex.blade.php
@@ -1,6 +1,7 @@
@extends('layout.site', ['title' => $area->name_area])
@section('custom_js')
+ @include('js.maps_js')
@endsection
diff --git a/resources/views/house/post.blade.php b/resources/views/house/post.blade.php
index ad569f4..e52b8be 100644
--- a/resources/views/house/post.blade.php
+++ b/resources/views/house/post.blade.php
@@ -1,4 +1,11 @@
-@extends('layout.site', ['title' => 'Избранное RentTorg'])
+@extends('layout.site', ['title' => $house->title])
+
+@section('custom_js')
+ @include('js.maps_js')
+
+@endsection
@section('content')
@@ -30,7 +37,7 @@
-
+
@yield('custom_js')
diff --git a/resources/views/layout/site.blade.php b/resources/views/layout/site.blade.php
index 1303e69..4994470 100644
--- a/resources/views/layout/site.blade.php
+++ b/resources/views/layout/site.blade.php
@@ -413,7 +413,7 @@
-
+
@yield('custom_js')