Tag Archives: sell

5 Things to Know About Selling Your Boston Condo

Boston’s real estate market is beyond competitive, but that doesn’t mean simply listing your property guarantees an easy sale. Every type of home, from single-family houses to triple-deckers, has a unique set of challenges and selling points to consider. And while selling your condominium may seem like a breeze, there are several things to keep […]

/* =============================================== JAVASCRIPT EFECTOS INTERACTIVOS - URBANO.COM.CO Copiar en: Theme Options > Advanced > Custom JS =============================================== */ (function($) { 'use strict'; // ============================================ // 1. CONTADOR ANIMADO DE NÚMEROS // ============================================ function animateCounter(element, start, end, duration) { let startTimestamp = null; const step = (timestamp) => { if (!startTimestamp) startTimestamp = timestamp; const progress = Math.min((timestamp - startTimestamp) / duration, 1); const value = Math.floor(progress * (end - start) + start); element.innerHTML = value + (element.dataset.suffix || ''); if (progress < 1) { window.requestAnimationFrame(step); } }; window.requestAnimationFrame(step); } // Activar contadores cuando estén visibles const observerOptions = { threshold: 0.5, rootMargin: '0px' }; const statsObserver = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting && !entry.target.classList.contains('counted')) { entry.target.classList.add('counted'); // Stats section if (entry.target.classList.contains('stat-item')) { const numberElement = entry.target.querySelector('h3'); const targetNumber = parseInt(numberElement.textContent.replace(/\D/g, '')); animateCounter(numberElement, 0, targetNumber, 2000); } // Trust bar if (entry.target.classList.contains('trust-item')) { const numberElement = entry.target.querySelector('strong'); const targetNumber = parseInt(numberElement.textContent.replace(/\D/g, '')); animateCounter(numberElement, 0, targetNumber, 1500); } // Stats en sección Propiedad Horizontal if (entry.target.classList.contains('ph-stat')) { const numberElement = entry.target.querySelector('strong'); const targetNumber = parseInt(numberElement.textContent.replace(/\D/g, '')); animateCounter(numberElement, 0, targetNumber, 1500); } } }); }, observerOptions); // Observar elementos document.addEventListener('DOMContentLoaded', function() { document.querySelectorAll('.stat-item, .trust-item, .ph-stat').forEach(el => { statsObserver.observe(el); }); }); // ============================================ // 2. SCROLL REVEAL - ANIMACIÓN AL HACER SCROLL // ============================================ const revealObserver = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.classList.add('revealed'); revealObserver.unobserve(entry.target); } }); }, { threshold: 0.15, rootMargin: '0px 0px -100px 0px' }); $(document).ready(function() { // Agregar clase scroll-reveal a elementos $('.service-main-card, .project-card, .testimonial-card, .process-step, .featured_box').each(function() { $(this).addClass('scroll-reveal'); revealObserver.observe(this); }); }); // ============================================ // 3. PARALLAX SUAVE EN HERO // ============================================ $(window).on('scroll', function() { const scrolled = $(window).scrollTop(); // Parallax en hero $('.hero-section').css('transform', 'translateY(' + (scrolled * 0.5) + 'px)'); // Fade out hero al hacer scroll const heroOpacity = 1 - (scrolled / 500); $('.hero-content').css('opacity', Math.max(heroOpacity, 0)); }); // ============================================ // 4. PROGRESO DE SCROLL (Barra superior) // ============================================ $(window).on('scroll', function() { const winScroll = document.body.scrollTop || document.documentElement.scrollTop; const height = document.documentElement.scrollHeight - document.documentElement.clientHeight; const scrolled = (winScroll / height) * 100; // Actualizar variable CSS document.documentElement.style.setProperty('--scroll', scrolled + '%'); }); // ============================================ // 5. SMOOTH SCROLL PARA ANCLAS // ============================================ $('a[href^="#"]').on('click', function(e) { const target = $(this.getAttribute('href')); if(target.length) { e.preventDefault(); $('html, body').stop().animate({ scrollTop: target.offset().top - 100 }, 1000, 'easeInOutExpo'); } }); // ============================================ // 6. FORMULARIO - VALIDACIÓN MEJORADA // ============================================ $('.wpcf7-form input, .wpcf7-form textarea, .wpcf7-form select').on('focus', function() { $(this).parent().addClass('focused'); }); $('.wpcf7-form input, .wpcf7-form textarea, .wpcf7-form select').on('blur', function() { if (!$(this).val()) { $(this).parent().removeClass('focused'); } }); // Animación al enviar formulario document.addEventListener('wpcf7submit', function(event) { const form = event.target; // Éxito if (event.detail.status === 'mail_sent') { // Confetti effect (opcional) if (typeof confetti !== 'undefined') { confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } }); } // Scroll a mensaje de éxito setTimeout(function() { const responseOutput = $(form).find('.wpcf7-response-output'); $('html, body').animate({ scrollTop: responseOutput.offset().top - 100 }, 500); }, 100); } }); // ============================================ // 7. LAZY LOAD MEJORADO PARA IMÁGENES // ============================================ if ('loading' in HTMLImageElement.prototype) { // Navegador soporta lazy loading nativo const images = document.querySelectorAll('img[loading="lazy"]'); images.forEach(img => { img.addEventListener('load', function() { this.classList.add('loaded'); }); }); } else { // Fallback con IntersectionObserver const imageObserver = new IntersectionObserver((entries, observer) => { entries.forEach(entry => { if (entry.isIntersecting) { const img = entry.target; img.src = img.dataset.src; img.classList.add('loaded'); imageObserver.unobserve(img); } }); }); document.querySelectorAll('img[data-src]').forEach(img => { imageObserver.observe(img); }); } // ============================================ // 8. CURSOR PERSONALIZADO (Opcional - Premium) // ============================================ const cursor = $('
'); const cursorFollower = $('
'); // Solo en desktop if ($(window).width() > 1024) { $('body').append(cursor, cursorFollower); $(document).on('mousemove', function(e) { cursor.css({ left: e.clientX, top: e.clientY }); setTimeout(function() { cursorFollower.css({ left: e.clientX, top: e.clientY }); }, 100); }); // Efecto al hacer hover en elementos clickeables $('a, button, .button').on('mouseenter', function() { cursor.addClass('active'); cursorFollower.addClass('active'); }).on('mouseleave', function() { cursor.removeClass('active'); cursorFollower.removeClass('active'); }); } // ============================================ // 9. BOTÓN WHATSAPP - MOSTRAR/OCULTAR // ============================================ $(window).on('scroll', function() { if ($(this).scrollTop() > 300) { $('.whatsapp-float, .ai-chat-button').fadeIn(300); } else { $('.whatsapp-float, .ai-chat-button').fadeOut(300); } }); // ============================================ // 10. TESTIMONIOS - AUTO ROTATE (Opcional) // ============================================ let currentTestimonial = 0; const testimonials = $('.testimonial-card'); const testimonialCount = testimonials.length; function rotateTestimonials() { testimonials.removeClass('active'); testimonials.eq(currentTestimonial).addClass('active'); currentTestimonial = (currentTestimonial + 1) % testimonialCount; } // Auto-rotate cada 5 segundos (comentar si no quieres auto-rotate) // setInterval(rotateTestimonials, 5000); // ============================================ // 11. FAQ - ACORDEÓN PERSONALIZADO // ============================================ $('.accordion-title').on('click', function() { const item = $(this).parent(); const wasActive = item.hasClass('active'); // Cerrar todos $('.accordion-item').removeClass('active'); $('.accordion-inner').slideUp(300); // Abrir el clickeado si no estaba activo if (!wasActive) { item.addClass('active'); item.find('.accordion-inner').slideDown(300); } }); // ============================================ // 12. HEADER STICKY - EFECTO CAMBIO COLOR // ============================================ $(window).on('scroll', function() { if ($(this).scrollTop() > 100) { $('header, .header-wrapper').addClass('scrolled'); } else { $('header, .header-wrapper').removeClass('scrolled'); } }); // ============================================ // 13. PRELOADER (Opcional) // ============================================ $(window).on('load', function() { $('.preloader').fadeOut(500, function() { $(this).remove(); }); }); // ============================================ // 14. MODAL POPUP PARA PROYECTOS // ============================================ $('.project-card').on('click', function(e) { if (!$(e.target).is('a')) { const projectId = $(this).data('project-id'); // Abrir modal o lightbox con detalles del proyecto // Implementar según necesidades } }); // ============================================ // 15. BOTÓN "VOLVER ARRIBA" // ============================================ const backToTop = $(''); $('body').append(backToTop); $(window).on('scroll', function() { if ($(this).scrollTop() > 500) { backToTop.addClass('visible'); } else { backToTop.removeClass('visible'); } }); backToTop.on('click', function() { $('html, body').animate({ scrollTop: 0 }, 800); }); // ============================================ // 16. COOKIE CONSENT (GDPR) // ============================================ if (!localStorage.getItem('cookieConsent')) { const cookieBanner = ` `; $('body').append(cookieBanner); $('.accept-cookies').on('click', function() { localStorage.setItem('cookieConsent', 'true'); $('.cookie-consent').fadeOut(300, function() { $(this).remove(); }); }); } // ============================================ // 17. TRACKING DE EVENTOS PARA ANALYTICS // ============================================ // Click en botones CTA $('.button, .btn-primary').on('click', function() { const buttonText = $(this).text(); if (typeof gtag !== 'undefined') { gtag('event', 'cta_click', { 'button_text': buttonText, 'button_location': $(this).closest('section').attr('class') }); } }); // Click en teléfono $('a[href^="tel:"]').on('click', function() { if (typeof gtag !== 'undefined') { gtag('event', 'phone_click', { 'phone_number': $(this).attr('href') }); } }); // Click en WhatsApp $('.whatsapp-float').on('click', function() { if (typeof gtag !== 'undefined') { gtag('event', 'whatsapp_click', { 'action': 'open_chat' }); } }); // Click en servicios $('.service-main-card a').on('click', function() { const serviceName = $(this).closest('.service-main-card').find('h3').text(); if (typeof gtag !== 'undefined') { gtag('event', 'service_view', { 'service_name': serviceName }); } }); // ============================================ // 18. DETECCIÓN DE AD BLOCKER // ============================================ function detectAdBlocker() { const testAd = document.createElement('div'); testAd.innerHTML = ' '; testAd.className = 'adsbox'; document.body.appendChild(testAd); setTimeout(function() { if (testAd.offsetHeight === 0) { console.log('AdBlocker detectado'); // Mostrar mensaje opcional } testAd.remove(); }, 100); } detectAdBlocker(); // ============================================ // 19. PERFORMANCE - LAZY LOAD VIDEOS // ============================================ const videoObserver = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { const video = entry.target; video.src = video.dataset.src; video.load(); videoObserver.unobserve(video); } }); }); document.querySelectorAll('video[data-src]').forEach(video => { videoObserver.observe(video); }); // ============================================ // 20. MOBILE MENU - MEJORAS // ============================================ // Cerrar menú al hacer click en link $('.mobile-nav a').on('click', function() { $('.mobile-nav').removeClass('active'); $('body').removeClass('mobile-nav-open'); }); // Cerrar menú al hacer scroll let lastScroll = 0; $(window).on('scroll', function() { const currentScroll = $(this).scrollTop(); if (currentScroll > lastScroll && currentScroll > 100) { $('.mobile-nav').removeClass('active'); } lastScroll = currentScroll; }); // ============================================ // 21. EASTER EGG (Opcional - Diversión) // ============================================ let konamiCode = []; const pattern = ['ArrowUp', 'ArrowUp', 'ArrowDown', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'ArrowLeft', 'ArrowRight', 'b', 'a']; $(document).on('keydown', function(e) { konamiCode.push(e.key); konamiCode = konamiCode.slice(-10); if (konamiCode.join('') === pattern.join('')) { console.log('¡Código Konami activado!'); // Agregar efecto especial $('body').addClass('konami-mode'); setTimeout(() => $('body').removeClass('konami-mode'), 5000); } }); // ============================================ // 22. OPTIMIZACIÓN - DEBOUNCE & THROTTLE // ============================================ function debounce(func, wait) { let timeout; return function executedFunction(...args) { const later = () => { clearTimeout(timeout); func(...args); }; clearTimeout(timeout); timeout = setTimeout(later, wait); }; } function throttle(func, limit) { let inThrottle; return function() { const args = arguments; const context = this; if (!inThrottle) { func.apply(context, args); inThrottle = true; setTimeout(() => inThrottle = false, limit); } }; } // Aplicar a eventos de resize y scroll const handleResize = debounce(function() { console.log('Resize finalizado'); // Acciones al cambiar tamaño }, 250); const handleScroll = throttle(function() { // Acciones al hacer scroll (optimizado) }, 100); $(window).on('resize', handleResize); $(window).on('scroll', handleScroll); // ============================================ // INICIALIZACIÓN FINAL // ============================================ console.log('🚀 Urbano.com.co - Scripts cargados correctamente'); })(jQuery); // ============================================ // STYLES CSS ADICIONALES PARA JS // ============================================ /* Agregar estos estilos en el CSS también */ /* .custom-cursor { width: 10px; height: 10px; background: #E31E24; border-radius: 50%; position: fixed; pointer-events: none; z-index: 9999; transition: transform 0.15s ease; } .custom-cursor.active { transform: scale(2); } .custom-cursor-follower { width: 30px; height: 30px; border: 2px solid #E31E24; border-radius: 50%; position: fixed; pointer-events: none; z-index: 9998; transition: all 0.15s ease; } .custom-cursor-follower.active { transform: scale(1.5); } .back-to-top { position: fixed; bottom: 120px; right: 40px; width: 50px; height: 50px; background: #E31E24; color: white; border: none; border-radius: 50%; font-size: 20px; cursor: pointer; opacity: 0; visibility: hidden; transition: all 0.3s ease; z-index: 98; } .back-to-top.visible { opacity: 1; visibility: visible; } .back-to-top:hover { transform: translateY(-5px); box-shadow: 0 5px 15px rgba(227, 30, 36, 0.4); } .cookie-consent { position: fixed; bottom: 0; left: 0; right: 0; background: #1a1a1a; color: white; padding: 20px; z-index: 9999; animation: slideInUp 0.5s ease-out; } .cookie-content { max-width: 1200px; margin: 0 auto; display: flex; align-items: center; justify-content: space-between; gap: 20px; } .cookie-content p { margin: 0; flex: 1; } .accept-cookies { background: #E31E24; color: white; border: none; padding: 10px 25px; border-radius: 4px; cursor: pointer; font-weight: 600; } .accept-cookies:hover { background: #c01a1f; } @keyframes slideInUp { from { transform: translateY(100%); } to { transform: translateY(0); } } .preloader { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: white; display: flex; align-items: center; justify-content: center; z-index: 99999; } .preloader::after { content: ''; width: 50px; height: 50px; border: 5px solid #f3f3f3; border-top: 5px solid #E31E24; border-radius: 50%; animation: spin 1s linear infinite; } */