Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #11 (permalink)  
Старый 12.04.2023, 03:16
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,492

showModal скорее всего проявляет окно не сразу, а с какой-нить анимацией, а потому если сразу пытаться получить кнопку - её ещё нет. Надо смотреть что там в showModal происходит: может оно принимает коллбэк, может возвращает промис, может вообще возвращает контрольный объект со всем нужным...

Способы отловить "что-то когда-то" есть, но это хрень.
__________________
29375, 35
Ответить с цитированием
  #12 (permalink)  
Старый 12.04.2023, 07:28
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,704

Сообщение от Aetae
Способы отловить "что-то когда-то" есть, но это хрень.
Просто в отладчике пройти эту функцию.
Ответить с цитированием
  #13 (permalink)  
Старый 12.04.2023, 09:17
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,704

Ну функция showModal проста и ужасна
function showModal(target) {
    var opt = {
        type: 'ajax',
        scrolling: 'visible',
        wrapCSS: 'get-modal'
    };
    if (typeof target === 'object') {
        opt = $.extend(opt, target);
    }
    else {
        opt.href = target;
    }
    $.fancybox(opt);
}

Она ничего не возвращает, поэтому мы не узнаем, когда открылась модальное окно, что бы обратиться к его кнопке закрытия.
Тут три варианта действий.
- Глубже изучить библиотеку fancybox в надежде, что у нее есть какие то события. Может есть событие открытия окна и тогда к кнопке обращаться только внутри этого события.

- Сделать после вызова showModal цикл с таймером и каждые, скажем, 100 мс проверять появилась эта кнопка или нет. Когда появится выполнить необходимые действия. Недостаток - если что то пошло не так, и fancybox не смог считать ресурс мы попадаем в бесконечный цикл. Но можно ограничить цикл, например, 8 секундами, и если через 8 сек кнопка не появилась, сказать, что произошла ошибка и сервер не отвечает.

- Перед вызовом showModal повесить на body MutationObserver и пусть он ждет, когда среди его дочерних элементов появится кнопка с заданным классом. Как появится - выполнить с ней необходимые действия.

Еще. При клике на эту кнопку задается

modalwin.style.display="none";

Не уверен, что это правильно. У fancybox скорее всего есть свой обработчик этой кнопки, который полностью убирает окно. Если он сработает первым, то окно уже не будет существовать. И это может вызвать ошибку.
Ответить с цитированием
  #14 (permalink)  
Старый 12.04.2023, 10:02
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,704

Если есть возможность переписать showModal, то сделайте его так
function showModal(target, callback) {
    var opt = {
        type: 'ajax',
        scrolling: 'visible',
        wrapCSS: 'get-modal'
    };
    if (typeof target === 'object') {
        opt = $.extend(opt, target);
    }
    else {
        opt.href = target;
    }
    if (callback) {
		opt.opts = {};
		opt.opts.onComplete = callback;
    }
    $.fancybox(opt);
}


А ваш код вызова
document.addEventListener('DOMContentLoaded', function() {
    let mcookie = getCookie("mcookie");
    if (mcookie != "no") {
        setTimeout(function() {
            showModal("obratnyij-zvonok/", () => {
                    document.querySelector(".fancybox-close")
						.addEventListener("click", function() {
							if ('modalwin' in window) { // Не уверен, что это нужно
								modalwin.style.display = "none";
							}
 
							// записываем cookie на 1 день, с которой мы не показываем окно
							let date = new Date;
							date.setDate(date.getDate() + 1);
							document.cookie = "mcookie=no; path=/; expires=" + date.toUTCString();
						})
			});
        }, 1000);
    }
});

Последний раз редактировалось voraa, 12.04.2023 в 10:04.
Ответить с цитированием
  #15 (permalink)  
Старый 12.04.2023, 22:38
Аспирант
Отправить личное сообщение для Timurkin Посмотреть профиль Найти все сообщения от Timurkin
 
Регистрация: 12.08.2017
Сообщений: 44

Решил проблему, добавив таймер в 1 секунду после вызова showModal:
function getCookie(name) {
    let matches = document.cookie.match(new RegExp(
        "(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"
    ));
    return matches ? decodeURIComponent(matches[1]) : undefined;
}
document.addEventListener('DOMContentLoaded', function() {
    let mcookie = getCookie("mcookie");
    if (mcookie != "no") {
        setTimeout(function() {
            showModal("obratnyij-zvonok/");
            setTimeout(() => { 
                document.querySelector(".fancybox-close").addEventListener("click", async function() {
                    if ('modalwin' in window) {
                        modalwin.style.display = "none";
                    }
                    // записываем cookie на 1 день, с которой мы не показываем окно
                    let date = new Date;
                    date.setDate(date.getDate() + 1);
                    document.cookie = "mcookie=no; path=/; expires=" + date.toUTCString();
                });
            }, 1000);
        }, 15000);
    }
});


Всем спасибо за помощь и подсказки!
Ответить с цитированием
  #16 (permalink)  
Старый 13.04.2023, 07:19
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,704

Так себе решение.
А если на сервере запор, а в сети пробки, и за секунду ответ не пришел?
Опять ошибка будет.

Так попробуйте
function getCookie(name) {
    let matches = document.cookie.match(new RegExp(
        "(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"
    ));
    return matches ? decodeURIComponent(matches[1]) : undefined;
}

function closeListener (tbeg) {
	const closeButton = document.querySelector(".fancybox-close")
	if (closeButton) {
		closeButton.addEventListener("click", function() {
			if ('modalwin' in window) {
				modalwin.style.display = "none";
			}
			// записываем cookie на 1 день, с которой мы не показываем окно
			let date = new Date;
			date.setDate(date.getDate() + 1);
			document.cookie = "mcookie=no; path=/; expires=" + date.toUTCString();
		});
	} else {
		if (Date.now() - tbeg > 8000)  {
			console.error('Сервер не отвечает')
			return;
		}
		setTimeout (closeListener, 100, tbeg);
	}
}

document.addEventListener('DOMContentLoaded', function() {
    let mcookie = getCookie("mcookie");
    if (mcookie != "no") {
        setTimeout(function() {
            showModal("obratnyij-zvonok/");
            closeListener(Date.now())
        }, 15000);
    }
});

Последний раз редактировалось voraa, 13.04.2023 в 09:24.
Ответить с цитированием
  #17 (permalink)  
Старый 13.04.2023, 09:37
Аспирант
Отправить личное сообщение для Timurkin Посмотреть профиль Найти все сообщения от Timurkin
 
Регистрация: 12.08.2017
Сообщений: 44

voraa, работает, спасибо!
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как-то странно работает код. Не выполняется целиком функция Yuriy-155 jQuery 7 22.11.2019 16:14
Непредсказуемая функция. Rora_ Node.JS 3 07.11.2017 08:34
Почему не определяется функция? Batyabest AJAX и COMET 4 13.10.2014 15:42
AJAX функция для новых html-элементов broadcast77 AJAX и COMET 25 03.03.2014 14:01
Функция при отсутсвии событий. nechervonez Элементы интерфейса 5 21.04.2010 13:14