(function () {
function initNLPTBookingBar() {
const bar = document.querySelector('.nlpt-mobile-bookingbar');
const target = document.querySelector('#tour-booking');
if (!bar || !target) {
return;
}
/* Evitar inicializar dos veces */
if (bar.dataset.nlptBookingInit === '1') {
return;
}
bar.dataset.nlptBookingInit = '1';
const mq = window.matchMedia('(max-width: 1024px)');
function targetIsVisible() {
const rect = target.getBoundingClientRect();
const viewportHeight =
window.innerHeight ||
document.documentElement.clientHeight;
/*
* Consideramos que el formulario está visible
* cuando ocupa alguna parte útil del viewport.
*/
return (
rect.bottom > viewportHeight * 0.12 &&
rect.top < viewportHeight * 0.88
);
}
function updateBar() {
/*
* Desktop:
* nunca mostrar.
*/
if (!mq.matches) {
bar.classList.remove('is-visible');
return;
}
/*
* Tablet / mobile:
* formulario visible = ocultar barra.
* formulario fuera = mostrar barra.
*/
if (targetIsVisible()) {
bar.classList.remove('is-visible');
} else {
bar.classList.add('is-visible');
}
}
/* =================================================
IntersectionObserver
================================================= */
if ('IntersectionObserver' in window) {
const observer = new IntersectionObserver(
function () {
updateBar();
},
{
root: null,
rootMargin:
'-12% 0px -12% 0px',
threshold:
0
}
);
observer.observe(target);
}
/*
* Fallback + sincronización.
* requestAnimationFrame evita ejecutar cálculos
* excesivamente durante scroll.
*/
let ticking = false;
function requestUpdate() {
if (ticking) {
return;
}
ticking = true;
requestAnimationFrame(function () {
updateBar();
ticking = false;
});
}
window.addEventListener(
'scroll',
requestUpdate,
{
passive: true
}
);
window.addEventListener(
'resize',
requestUpdate
);
/* =================================================
CLICK RESERVAR
================================================= */
const button =
bar.querySelector(
'a[href="#tour-booking"]'
);
if (button) {
button.addEventListener(
'click',
function (event) {
event.preventDefault();
/*
* Oculta inmediatamente.
*/
bar.classList.remove(
'is-visible'
);
/*
* Scroll a formulario.
*/
target.scrollIntoView({
behavior: 'smooth',
block: 'start'
});
}
);
}
/*
* Estado inicial.
*/
updateBar();
}
/*
* IMPORTANTE:
* Esto funciona tanto si Elementor ejecuta
* el widget antes como después de DOMContentLoaded.
*/
if (document.readyState === 'loading') {
document.addEventListener(
'DOMContentLoaded',
initNLPTBookingBar
);
} else {
initNLPTBookingBar();
}
})();
From