Я пытаюсь, чтобы мои карты загорались всякий раз, когда я наводил указатель мыши на булавку на карте, которая соответствует карте (очень похоже на то, что у них есть на веб-сайте airbnb), но я не могу заставить ее работать .
Может быть, вы можете мне помочь. У меня есть ошибка в моем коде JS, и я пытаюсь ее отладить. В приложении RoR о ресторанах и на странице указателей я перечисляю рестораны с карточками и на большой карте, наклеенной рядом с булавками, показывающими расположение ресторанов. Есть 2 вещи, с которыми я хочу справиться в JS. Во-первых, когда я наведу курсор мыши на карточку ресторана, булавка, соответствующая ресторану, должна открыть информационное окно с названием и адресом ресторана (это работает). Второе - наоборот, когда всякий раз, когда я наводю указатель мыши на булавку на карте, карта, соответствующая этому булавке, должна менять свой фон, чтобы вы могли видеть, какой это. С этой частью у меня возникли трудности.
Это код JS, с которым я работаю:
import 'mapbox-gl/dist/mapbox-gl.css'
import mapboxgl from 'mapbox-gl/dist/mapbox-gl.js';
const initMapbox = () => {
const mapElement = document.getElementById('map');
if (mapElement) { // only build a map if there's a div#map to inject into
mapboxgl.accessToken = mapElement.dataset.mapboxApiKey;
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v10'
});
const markers = JSON.parse(mapElement.dataset.markers);
// Here we store map markers in an array
const mapMarkers = []
markers.forEach((marker) => {
const popup = new mapboxgl.Popup().setHTML(marker.infoWindow.content);
const newMarker = new mapboxgl.Marker()
.setLngLat([marker.lng, marker.lat])
.setPopup(popup)
.addTo(map);
mapMarkers.push(newMarker)
// We use the "getElement" funtion provided by mapbox-gl to access to the marker's HTML an set an id
newMarker.getElement().dataset.markerId = marker.id;
// Put a microphone on the new marker listening for a mouseenter event
newMarker.getElement().addEventListener('mouseenter', (e) => toggleCardHighlighting(e) );
// We put a microphone on listening for a mouseleave event
newMarker.getElement().addEventListener('mouseleave', (e) => toggleCardHighlighting(e) );
});
fitMapToMarkers(map, markers);
// We give the array of marker to a new function called "openInfoWindow"
openInfoWindow(mapMarkers);
}
};
const toggleCardHighlighting = (event) => {
// We select the card corresponding to the marker's id
const card = document.querySelector(`[data-restaurant-id="${event.currentTarget.dataset.markerId}"]`);
// Then we toggle the class "highlight" to the card
card.classList.toggle('highlight');
}
const fitMapToMarkers = (map, markers) => {
const bounds = new mapboxgl.LngLatBounds();
markers.forEach(marker => bounds.extend([ marker.lng, marker.lat ]));
map.fitBounds(bounds, { padding: 70, maxZoom: 15 });
};
const openInfoWindow = (markers) => {
const cards = document.querySelectorAll('.card');
cards.forEach((card, index) => {
card.addEventListener('mouseenter', () => {
markers[index].togglePopup();
});
card.addEventListener('mouseleave', () => {
markers[index].togglePopup();
});
});
}
const addressInput = document.getElementById('restaurant_address');
if (addressInput) {
const places = require('places.js');
const placesAutocomplete = places({
container: addressInput
});
}
const fullAddressInput = document.getElementById('restaurant_full_address');
if (fullAddressInput) {
const places = require('places.js');
const placesAutocomplete = places({
container: fullAddressInput
});
}
export { initMapbox };
Я получаю эту ошибку в консоли Chrome:
Uncaught TypeError: Cannot read property 'classList' of null
at toggleCardHighlighting (init_mapbox.js:64)
at HTMLDivElement.<anonymous> (init_mapbox.js:31)
Строка 60-65 содержит эту функцию:
const toggleCardHighlighting = (event) => {
// We select the card corresponding to the marker's id
const card = document.querySelector(`[data-restaurant-id="${event.currentTarget.dataset.markerId}"]`);
// Then we toggle the class "highlight" to the card
card.classList.toggle('highlight');
}
Ошибка происходит в строке 65:
card.classList.toggle('highlight');
HTML-код отдельной карты выглядит так:
<div class="card index-card" style="background-image: linear-gradient(rgba(0,0,0,0.3), rgba(0,0,0,0.2)),url('https://kitt.lewagon.com/placeholder/cities/shanghai');" data-restaurant-id="532">
<div class="card-body">
<h2>Restaurant Example</h2>
<p>Mediterranean cuisine. Specialising in paella, fresh fish and sangria.</p>
<p>moderate, Ibiza, Restaurant</p>
<a href="/restaurants/532">See more</a>
<p>
<a href="/tagged?tag=mediterranean">mediterranean</a>
</p>
<a class="card-star" rel="nofollow" data-method="put" href="/restaurants/532/vote">
<img alt="favorite-vote" src="/assets/favorite-vote-1d5203cb3cbd136f67e5a32ece417f9707c6f6ad38946c5c9de44146f6ed4e9a.png">
</a> </div>
</div>
Внутри отладчика Chrome, когда я делаю это, я получаю null
, где я ожидаю, что у него будет div карты ресторана:
document.querySelector(`[data-restaurant-id="${event.currentTarget.dataset.markerId}"]`)
null
Эта строка дает мне undefined
:
const card = document.querySelector(`[data-restaurant-id="${event.currentTarget.dataset.markerId}"]`)
undefined
- Когда я делаю только это, я получаю правильное свойство:
[data-restaurant-id="${event.currentTarget.dataset.markerId}"]`
"[data-restaurant-id="532"]"
- Но когда я делаю это, я получаю
null
:
document.querySelector(`[data-restaurant-
id="${event.currentTarget.dataset.markerId}"]`)
null
Так что, когда в этой части что-то идет не так, но я не могу объяснить, как это сделать document.querySelector