DOM 完全加载后,我如何获得到 运行 函数的 turbolinks?
How do I get turbolinks to run a function once the DOM is completely loaded?
document.addEventListener('turbolinks:load', () => {});
未按预期工作。 Mapbox 抛出以下错误:Uncaught Error: Container 'map' not found.
并且地图只有在我重新加载页面后才能正确显示。
下面是一些有助于更好理解的代码。
Javascript 用于 mapbox 导入和设置:
// app/javascript/plugins/init_mapbox.js
import mapboxgl from 'mapbox-gl';
const mapElement = document.getElementById('map');
const buildMap = () => {
mapboxgl.accessToken = mapElement.dataset.mapboxApiKey;
return new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v10'
});
};
const addMarkersToMap = (map, markers) => {
markers.forEach((marker) => {
new mapboxgl.Marker()
.setLngLat([ marker.lng, marker.lat ])
.addTo(map);
});
};
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 initMapbox = () => {
if (mapElement) {
const map = buildMap();
const markers = JSON.parse(mapElement.dataset.markers);
console.log(markers)
addMarkersToMap(map, markers);
fitMapToMarkers(map, markers);
}
};
export { initMapbox };
在 application.js 中导入:
// app/javascript/packs/application.js
import { initMapbox } from '../plugins/init_mapbox';
[...]
document.addEventListener('turbolinks:load', () => {
initMapbox();
});
HTML:
<!-- app/views/spaces/index.html.erb -->
[...]
<div id="map"
style="width: 100%; height: 600px;"
data-markers="<%= @markers.to_json %>"
data-mapbox-api-key="<%= ENV['MAPBOX_API_KEY'] %>">
</div>
[...]
我完全迷失在这一点上。有任何想法吗?有人让这个工作吗?
问题是您在导入文件时分配 mapElement
。不是在 DOM 准备就绪或 turbolinks 执行页面访问时。
如果您只是重写此代码,以便您的函数将一个元素作为参数,而不是依赖外部作用域中的变量,那么解决它就很简单了:
import mapboxgl from 'mapbox-gl';
const buildMap = (mapElement) => {
mapboxgl.accessToken = mapElement.dataset.mapboxApiKey;
return new mapboxgl.Map({
container: mapElement,
style: 'mapbox://styles/mapbox/streets-v10'
});
};
const addMarkersToMap = (map, markers) => {
markers.forEach((marker) => {
new mapboxgl.Marker()
.setLngLat([ marker.lng, marker.lat ])
.addTo(map);
});
};
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 initMapbox = (mapElement) => {
const map = buildMap(mapElement);
const markers = JSON.parse(mapElement.dataset.markers);
console.log(markers)
addMarkersToMap(map, markers);
fitMapToMarkers(map, markers);
};
然后您在回调函数中查询 DOM:
document.addEventListener('turbolinks:load', () => {
const mapElement = document.getElementById('map');
if (mapElement) {
initMapbox(mapElement);
}
});
此外,我不知道这是否是复制粘贴问题,但您的 HTML 也缺少 <div id="map">
中的括号。
document.addEventListener('turbolinks:load', () => {});
未按预期工作。 Mapbox 抛出以下错误:Uncaught Error: Container 'map' not found.
并且地图只有在我重新加载页面后才能正确显示。
下面是一些有助于更好理解的代码。
Javascript 用于 mapbox 导入和设置:
// app/javascript/plugins/init_mapbox.js
import mapboxgl from 'mapbox-gl';
const mapElement = document.getElementById('map');
const buildMap = () => {
mapboxgl.accessToken = mapElement.dataset.mapboxApiKey;
return new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v10'
});
};
const addMarkersToMap = (map, markers) => {
markers.forEach((marker) => {
new mapboxgl.Marker()
.setLngLat([ marker.lng, marker.lat ])
.addTo(map);
});
};
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 initMapbox = () => {
if (mapElement) {
const map = buildMap();
const markers = JSON.parse(mapElement.dataset.markers);
console.log(markers)
addMarkersToMap(map, markers);
fitMapToMarkers(map, markers);
}
};
export { initMapbox };
在 application.js 中导入:
// app/javascript/packs/application.js
import { initMapbox } from '../plugins/init_mapbox';
[...]
document.addEventListener('turbolinks:load', () => {
initMapbox();
});
HTML:
<!-- app/views/spaces/index.html.erb -->
[...]
<div id="map"
style="width: 100%; height: 600px;"
data-markers="<%= @markers.to_json %>"
data-mapbox-api-key="<%= ENV['MAPBOX_API_KEY'] %>">
</div>
[...]
我完全迷失在这一点上。有任何想法吗?有人让这个工作吗?
问题是您在导入文件时分配 mapElement
。不是在 DOM 准备就绪或 turbolinks 执行页面访问时。
如果您只是重写此代码,以便您的函数将一个元素作为参数,而不是依赖外部作用域中的变量,那么解决它就很简单了:
import mapboxgl from 'mapbox-gl';
const buildMap = (mapElement) => {
mapboxgl.accessToken = mapElement.dataset.mapboxApiKey;
return new mapboxgl.Map({
container: mapElement,
style: 'mapbox://styles/mapbox/streets-v10'
});
};
const addMarkersToMap = (map, markers) => {
markers.forEach((marker) => {
new mapboxgl.Marker()
.setLngLat([ marker.lng, marker.lat ])
.addTo(map);
});
};
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 initMapbox = (mapElement) => {
const map = buildMap(mapElement);
const markers = JSON.parse(mapElement.dataset.markers);
console.log(markers)
addMarkersToMap(map, markers);
fitMapToMarkers(map, markers);
};
然后您在回调函数中查询 DOM:
document.addEventListener('turbolinks:load', () => {
const mapElement = document.getElementById('map');
if (mapElement) {
initMapbox(mapElement);
}
});
此外,我不知道这是否是复制粘贴问题,但您的 HTML 也缺少 <div id="map">
中的括号。