Unterkünfte suchen

Unterkünfte in Costa Blanca, 2 Gäste. 107 Unterkünfte

Moraira

Villa zur Miete in El Portet de Moraira, SAN VICENTE, 50 m vom Wasser und privatem Pool.

Personen 12 Pers. Betten 6 Zi. Strand 0,1 km Sterne 4.61

Ab 368,00 € /Nacht

Calpe / Calp

Villa zur Miete in Calpe BELLISSIMA 14 pax und privatem Pool

Personen 14 Pers. Betten 7 Zi. Strand 1,9 km Sterne 4.93

Ab 10,00 € /Nacht

Calpe / Calp

Ferienhaus in Calpe GRANDIOSA

Personen 14 Pers. Betten 7 Zi. Strand 1,9 km Sterne 4.66

Ab 10,00 € /Nacht

Moraira

Ferienhausvermietung in Moraira ANDURINA

Personen 10 Pers. Betten 6 Zi. Strand 0,7 km Sterne 4.54

Ab 163,00 € /Nacht

Benissa

Villa zur Miete in Benissa ARC für 12, privater Pool und Meerblick

Personen 12 Pers. Betten 6 Zi. Strand 2,7 km Sterne 5

Ab 352,00 € /Nacht

Benissa

Ferienhäuse in Benissa, MARIO

Personen 12 Pers. Betten 6 Zi. Strand 1,5 km Sterne 4.78

Ab 253,00 € /Nacht

Calpe / Calp

Ferienhausvermietung in Calpe STEFKA

Personen 16 Pers. Betten 8 Zi. Strand 1,7 km Sterne 4.59

Ab 246,00 € /Nacht

Calpe / Calp

Ferienhaus in Calpe, SENIETA

Personen 10 Pers. Betten 5 Zi. Strand 1,5 km Sterne 4.88

Ab 276,00 € /Nacht

Moraira

Ferienhaus in Moraira, FLORIDA.

Personen 12 Pers. Betten 6 Zi. Strand 1,7 km Sterne 4.61

Ab 336,00 € /Nacht

Calpe / Calp

XENIA, Villa zur Miete in Calpe für 12 Personen mit privatem Pool

Personen 12 Pers. Betten 6 Zi. Strand 1,7 km Sterne 4.84

Ab 312,00 € /Nacht

Calpe / Calp

Ferienvermietung von Villa IFACH

Personen 12 Pers. Betten 6 Zi. Strand 2,0 km Sterne 4.67

Ab 241,00 € /Nacht

Benissa

RAPHAEL, Schöne Villa für 6 pax mit spektakulärem Meerblick in Benissa.free wifi

Personen 6 Pers. Betten 3 Zi. Strand 1,0 km Sterne 4.75

Ab 209,00 € /Nacht

link.href === href); if (existing) { resolve(); return; } const link = document.createElement('link'); link.rel = 'stylesheet'; link.href = href; link.onload = resolve; link.onerror = reject; document.head.appendChild(link); }); }, highlightMarker(accommodationId) { // Primero limpiar todos los marcadores para evitar estados inconsistentes this.markers.forEach(m => { const el = m.getElement(); const priceEl = el.querySelector('.simple-price-marker'); if (priceEl) { priceEl.classList.remove('highlighted'); } // Restaurar z-index original if (el.dataset.originalZindex !== undefined) { el.style.zIndex = el.dataset.originalZindex; } else { el.style.zIndex = ''; } el.classList.remove('marker-highlighted'); }); // Ahora destacar el marcador específico const marker = this.markers.find(m => { const el = m.getElement(); return el && String(el.getAttribute('data-accommodation-id')) === String(accommodationId); }); if (marker) { const el = marker.getElement(); const priceEl = el.querySelector('.simple-price-marker'); if (priceEl) { priceEl.classList.add('highlighted'); } // Guardar z-index original si no está guardado if (!el.dataset.originalZindex) { el.dataset.originalZindex = el.style.zIndex || ''; } el.style.zIndex = '9999'; el.classList.add('marker-highlighted'); // Mover la cámara del mapa hasta el marcador manteniendo el zoom actual const lngLat = marker.getLngLat(); this.map.flyTo({ center: [lngLat.lng, lngLat.lat], duration: 1000, // Duración de la animación en ms essential: true // Esta animación es considerada esencial }); } }, unhighlightMarker(accommodationId) { const marker = this.markers.find(m => { const el = m.getElement(); return el && String(el.getAttribute('data-accommodation-id')) === String(accommodationId); }); if (marker) { const el = marker.getElement(); const priceEl = el.querySelector('.simple-price-marker'); if (priceEl) { // Limpiar todas las clases relacionadas con el estado de hover priceEl.classList.remove('highlighted'); // También limpiar cualquier estado de hover nativo que pueda haber quedado priceEl.classList.remove('show-price'); // Solo restaurar el texto si no está en estado clicked if (!priceEl.classList.contains('clicked')) { // Para marcadores con precio oculto, limpiar el texto if (priceEl.classList.contains('hidden-price')) { priceEl.textContent = ''; } } } // Restaurar z-index original if (el.dataset.originalZindex !== undefined) { el.style.zIndex = el.dataset.originalZindex; } else { el.style.zIndex = ''; } el.classList.remove('marker-highlighted'); } }, updateMarkers(accommodations) { // Verificar que el mapa esté inicializado if (!this.map || !this.mapInitialized) { return; } // Limpiar marcadores existentes this.markers.forEach(marker => marker.remove()); this.markers = []; accommodations.forEach(accommodation => { const lat = accommodation.lat; const lng = accommodation.lng; const price = accommodation.totalPrice; const shouldDisplayPrice = accommodation.display === true; const el = document.createElement('div'); // Aplicar clase condicional basada en la propiedad display const markerClass = shouldDisplayPrice ? 'simple-price-marker' : 'simple-price-marker hidden-price'; const displayText = shouldDisplayPrice ? price : ''; el.innerHTML = `
${displayText}
`; try { // Usar la URL ya construida desde PHP que incluye todos los parámetros necesarios const accommodationUrl = accommodation.url; // Crear el popup const fromLabel = 'Von'; const popupContent = document.createElement('div'); popupContent.className = 'card card--map'; const link = document.createElement('a'); link.href = accommodationUrl; link.className = 'card__link'; popupContent.appendChild(link); if (accommodation.picture) { const img = document.createElement('img'); img.src = accommodation.picture; img.className = 'card__image'; img.alt = accommodation.name || 'Alojamiento'; img.addEventListener('error', () => { img.style.display = 'none'; }); popupContent.appendChild(img); } const content = document.createElement('div'); content.className = 'card__content'; const title = document.createElement('h3'); title.className = 'card__title'; title.textContent = accommodation.name || 'Alojamiento'; content.appendChild(title); const priceWrap = document.createElement('div'); priceWrap.className = 'card__price'; priceWrap.appendChild(document.createTextNode(fromLabel + ' ')); const priceMoney = document.createElement('span'); priceMoney.className = 'card__price-money'; priceMoney.textContent = price; priceWrap.appendChild(priceMoney); priceWrap.appendChild(document.createTextNode(' ' + (accommodation.priceSuffix || ''))); content.appendChild(priceWrap); popupContent.appendChild(content); const popup = new mapboxgl.Popup({ offset: 45, closeButton: true }); if (typeof popup.setDOMContent === 'function') { popup.setDOMContent(popupContent); } else { popup.setHTML(popupContent.outerHTML); } // Crear el marcador const marker = new mapboxgl.Marker(el) .setLngLat([lng, lat]) .setPopup(popup) .addTo(this.map); // Asignar el atributo al contenedor real del marker const markerElement = marker.getElement(); markerElement.setAttribute('data-accommodation-id', accommodation.id); // Añadir listeners para hover y click const priceEl = el.querySelector('.simple-price-marker'); if (priceEl) { // Funcionalidad estándar de hover para todos los marcadores priceEl.addEventListener('mouseenter', () => { markerElement.dataset.originalZindex = markerElement.style.zIndex || ''; markerElement.style.zIndex = '99999'; markerElement.classList.add('marker-highlighted'); }); priceEl.addEventListener('mouseleave', () => { markerElement.style.zIndex = markerElement.dataset.originalZindex || ''; markerElement.classList.remove('marker-highlighted'); }); // Funcionalidad especial para marcadores con precio oculto if (!shouldDisplayPrice) { // Mostrar precio al hacer hover priceEl.addEventListener('mouseenter', () => { priceEl.classList.add('show-price'); priceEl.textContent = price; }); priceEl.addEventListener('mouseleave', () => { if (!priceEl.classList.contains('clicked')) { priceEl.classList.remove('show-price'); priceEl.textContent = ''; } }); // Manejar click en marcadores ocultos priceEl.addEventListener('click', (e) => { // No prevenir la propagación para permitir que el popup se abra // Remover clase clicked de todos los otros marcadores this.markers.forEach(otherMarker => { const otherPriceEl = otherMarker.getElement().querySelector('.simple-price-marker'); if (otherPriceEl && otherPriceEl !== priceEl) { otherPriceEl.classList.remove('clicked', 'show-price'); otherPriceEl.textContent = ''; } }); // Toggle del estado clicked en el marcador actual if (priceEl.classList.contains('clicked')) { priceEl.classList.remove('clicked', 'show-price'); priceEl.textContent = ''; } else { priceEl.classList.add('clicked', 'show-price'); priceEl.textContent = price; } }); } } this.markers.push(marker); } catch (e) { console.error('Error creating marker element:', e); } }); // Solo ajustar bounds automáticamente si: // 1. Hay marcadores // 2. No ha habido interacción del usuario // 3. Es la primera carga (no hay centro inicial establecido por alojamientos) if (this.markers.length > 0 && !this.userAct) { const bounds = new mapboxgl.LngLatBounds(); this.markers.forEach(marker => bounds.extend(marker.getLngLat())); // Solo hacer fitBounds si no hay un alojamiento específico como centro inicial const hasSpecificCenter = this.accommodations && this.accommodations.length > 0 && this.accommodations[0].lat && this.accommodations[0].lng && this.accommodations[0].lat !== 0 && this.accommodations[0].lng !== 0; if (!hasSpecificCenter) { this.map.fitBounds(bounds, { padding: 100, maxZoom: 15 }); } } } }">
Karte wird aktualisiert...
100% zuverlässige Unterkünfte

100% zuverlässige Unterkünfte

Registriert beim Tourismusamt mit Nr. EGVT-183A, verifiziert und lokal.
Sie wissen, wo Sie ankommen und wer Sie erwartet!

Registriert beim Tourismusamt mit Nr. EGVT-183A, verifiziert und lokal. Sie wissen, wo Sie ankommen und wer Sie erwartet!

Kostenlose Stornierung

Kostenlose Stornierung

Wir wissen, dass sich Pläne ändern.
Hier können Sie ohne Kosten oder versteckte Bedingungen stornieren.

Wir wissen, dass sich Pläne ändern. Hier können Sie ohne Kosten oder versteckte Bedingungen stornieren.

Reservierung ohne Kaution

Reservierung ohne Kaution

Vertrauen steht an erster Stelle, deshalb blockieren wir kein Geld auf Ihrer Karte und verlangen keine Kautionen.

Vertrauen steht an erster Stelle, deshalb blockieren wir kein Geld auf Ihrer Karte und verlangen keine Kautionen.

Filtros Filter Mapa Karte Listado Liste