如何解决围绕添加附加部分使 javascript 站点动态化
我在使用 mapbox api 的当前阶段: https://codepen.io/helpplsty/pen/WNRRPOK
/* This will let you use the .remove() function later on */
if (!('remove' in Element.prototype)) {
Element.prototype.remove = function () {
if (this.parentNode) {
this.parentNode.removeChild(this);
}
};
}
mapboxgl.accessToken = 'pk.eyJ1Ijoib3dlbmNveWxlMjEiLCJhIjoiY2tsc2p3MWgyMGF5dDJwbnh3M3E0Z2s2ayJ9.GAKLti4vJ81ac_bctZRxaw';
/**
* Add the map to the page
*/
var map = new mapboxgl.Map({
container: 'map',style: 'mapbox://styles/mapbox/light-v10',center: [-77.034084142948,38.909671288923],zoom: 13,scrollZoom: false
});
var stores = {
'type': 'FeatureCollection','features': [
{
'type': 'Feature','geometry': {
'type': 'Point','coordinates': [-77.034084142948,38.909671288923]
},'properties': {
'phoneFormatted': '(202) 234-7336','phone': '2022347336','address': '1471 P St NW','city': 'Washington DC','country': 'United States','crossStreet': 'at 15th St NW','postalCode': '20005','state': 'D.C.'
}
},{
'type': 'Feature','coordinates': [-77.049766,38.900772]
},'properties': {
'phoneFormatted': '(202) 507-8357','phone': '2025078357','address': '2221 I St NW','crossStreet': 'at 22nd St NW','postalCode': '20037','coordinates': [-77.043929,38.910525]
},'properties': {
'phoneFormatted': '(202) 387-9338','phone': '2023879338','address': '1512 Connecticut Ave NW','crossStreet': 'at Dupont Circle','postalCode': '20036','coordinates': [-77.0672,38.90516896]
},'properties': {
'phoneFormatted': '(202) 337-9338','phone': '2023379338','address': '3333 M St NW','crossStreet': 'at 34th St NW','postalCode': '20007','coordinates': [-77.002583742142,38.887041080933]
},'properties': {
'phoneFormatted': '(202) 547-9338','phone': '2025479338','address': '221 Pennsylvania Ave SE','crossStreet': 'btwn 2nd & 3rd Sts. SE','postalCode': '20003','coordinates': [-76.933492720127,38.99225245786]
},'properties': {
'address': '8204 Baltimore Ave','city': 'College Park','postalCode': '20740','state': 'MD'
}
},'coordinates': [-77.097083330154,38.980979]
},'properties': {
'phoneFormatted': '(301) 654-7336','phone': '3016547336','address': '4831 Bethesda Ave','cc': 'US','city': 'Bethesda','postalCode': '20814','coordinates': [-77.359425054188,38.958058116661]
},'properties': {
'phoneFormatted': '(571) 203-0082','phone': '5712030082','address': '11935 Democracy Dr','city': 'Reston','crossStreet': 'btw Explorer & Library','postalCode': '20190','state': 'VA'
}
},'coordinates': [-77.10853099823,38.880100922392]
},'properties': {
'phoneFormatted': '(703) 522-2016','phone': '7035222016','address': '4075 Wilson Blvd','city': 'Arlington','crossStreet': 'at N Randolph St.','postalCode': '22203','coordinates': [-75.28784,40.008008]
},'properties': {
'phoneFormatted': '(610) 642-9400','phone': '6106429400','address': '68 Coulter Ave','city': 'Ardmore','postalCode': '19003','state': 'PA'
}
},'coordinates': [-75.20121216774,39.954030175164]
},'properties': {
'phoneFormatted': '(215) 386-1365','phone': '2153861365','address': '3925 Walnut St','city': 'Philadelphia','postalCode': '19104','coordinates': [-77.043959498405,38.903883387232]
},'properties': {
'phoneFormatted': '(202) 331-3355','phone': '2023313355','address': '1901 L St. NW','crossStreet': 'at 19th St','state': 'D.C.'
}
}
]
};
/**
* Assign a unique id to each store. You'll use this `id`
* later to associate each point on the map with a listing
* in the sidebar.
*/
stores.features.forEach(function (store,i) {
store.properties.id = i;
});
/**
* Wait until the map loads to make changes to the map.
*/
map.on('load',function (e) {
/**
* This is where your '.addLayer()' used to be,instead
* add only the source without styling a layer
*/
map.addSource('places',{
'type': 'geojson','data': stores
});
/**
* Add all the things to the page:
* - The location listings on the side of the page
* - The markers onto the map
*/
buildLocationList(stores);
addMarkers();
});
/**
* Add a marker to the map for every store listing.
**/
function addMarkers() {
/* For each feature in the GeoJSON object above: */
stores.features.forEach(function (marker) {
/* Create a div element for the marker. */
var el = document.createElement('div');
/* Assign a unique `id` to the marker. */
el.id = 'marker-' + marker.properties.id;
/* Assign the `marker` class to each marker for styling. */
el.className = 'marker';
/**
* Create a marker using the div element
* defined above and add it to the map.
**/
new mapboxgl.Marker(el,{ offset: [0,-23] })
.setLngLat(marker.geometry.coordinates)
.addTo(map);
/**
* Listen to the element and when it is clicked,do three things:
* 1. Fly to the point
* 2. Close all other popups and display popup for clicked store
* 3. Highlight listing in sidebar (and remove highlight for all other listings)
**/
el.addEventListener('click',function (e) {
/* Fly to the point */
flyToStore(marker);
/* Close all other popups and display popup for clicked store */
createPopUp(marker);
/* Highlight listing in sidebar */
var activeItem = document.getElementsByClassName('active');
e.stopPropagation();
if (activeItem[0]) {
activeItem[0].classList.remove('active');
}
var listing = document.getElementById(
'listing-' + marker.properties.id
);
listing.classList.add('active');
});
});
}
/**
* Add a listing for each store to the sidebar.
**/
function buildLocationList(data) {
data.features.forEach(function (store,i) {
/**
* Create a shortcut for `store.properties`,* which will be used several times below.
**/
var prop = store.properties;
/* Add a new listing section to the sidebar. */
var listings = document.getElementById('listings');
var listing = listings.appendChild(document.createElement('div'));
/* Assign a unique `id` to the listing. */
listing.id = 'listing-' + prop.id;
/* Assign the `item` class to each listing for styling. */
listing.className = 'item';
/* Add the link to the individual listing created above. */
var link = listing.appendChild(document.createElement('a'));
link.href = '#';
link.className = 'title';
link.id = 'link-' + prop.id;
link.innerHTML = prop.address;
/* Add details to the individual listing. */
var details = listing.appendChild(document.createElement('div'));
details.innerHTML = prop.city;
if (prop.phone) {
details.innerHTML += ' · ' + prop.phoneFormatted;
}
/**
* Listen to the element and when it is clicked,do four things:
* 1. Update the `currentFeature` to the store associated with the clicked link
* 2. Fly to the point
* 3. Close all other popups and display popup for clicked store
* 4. Highlight listing in sidebar (and remove highlight for all other listings)
**/
link.addEventListener('click',function (e) {
for (var i = 0; i < data.features.length; i++) {
if (this.id === 'link-' + data.features[i].properties.id) {
var clickedListing = data.features[i];
flyToStore(clickedListing);
createPopUp(clickedListing);
}
}
var activeItem = document.getElementsByClassName('active');
if (activeItem[0]) {
activeItem[0].classList.remove('active');
}
this.parentNode.classList.add('active');
});
});
}
/**
* Use Mapbox GL JS's `flyTo` to move the camera smoothly
* a given center point.
**/
function flyToStore(currentFeature) {
map.flyTo({
center: currentFeature.geometry.coordinates,zoom: 15
});
}
/**
* Create a Mapbox GL JS `Popup`.
**/
function createPopUp(currentFeature) {
var popUps = document.getElementsByClassName('mapboxgl-popup');
if (popUps[0]) popUps[0].remove();
var popup = new mapboxgl.Popup({ closeOnClick: false })
.setLngLat(currentFeature.geometry.coordinates)
.setHTML(
'<h3>Sweetgreen</h3>' +
'<h4>' +
currentFeature.properties.address +
'</h4>'
)
.addTo(map);
}
body {
color: #404040;
font: 400 15px/22px 'Source Sans Pro','Helvetica Neue',Sans-serif;
margin: 0;
padding: 0;
-webkit-font-smoothing: antialiased;
}
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.sidebar {
position: absolute;
width: 33.3333%;
height: 100%;
top: 0;
left: 0;
overflow: hidden;
border-right: 1px solid rgba(0,0.25);
}
.map {
position: absolute;
left: 33.3333%;
width: 66.6666%;
top: 0;
bottom: 0;
}
h1 {
font-size: 22px;
margin: 0;
font-weight: 400;
line-height: 20px;
padding: 20px 2px;
}
a {
color: #404040;
text-decoration: none;
}
a:hover {
color: #101010;
}
.heading {
background: #fff;
border-bottom: 1px solid #eee;
min-height: 60px;
line-height: 60px;
padding: 0 10px;
background-color: #00853e;
color: #fff;
}
.listings {
height: 100%;
overflow: auto;
padding-bottom: 60px;
}
.listings .item {
display: block;
border-bottom: 1px solid #eee;
padding: 10px;
text-decoration: none;
}
.listings .item:last-child {
border-bottom: none;
}
.listings .item .title {
display: block;
color: #00853e;
font-weight: 700;
}
.listings .item .title small {
font-weight: 400;
}
.listings .item.active .title,.listings .item .title:hover {
color: #8cc63f;
}
.listings .item.active {
background-color: #f8f8f8;
}
::-webkit-scrollbar {
width: 3px;
height: 3px;
border-left: 0;
background: rgba(0,0.1);
}
::-webkit-scrollbar-track {
background: none;
}
::-webkit-scrollbar-thumb {
background: #00853e;
border-radius: 0;
}
.marker {
border: none;
cursor: pointer;
height: 56px;
width: 56px;
background-image: url(https://docs.mapbox.com/help/demos/building-a-store-locator/marker.png);
background-color: rgba(0,0);
}
.clearfix {
display: block;
}
.clearfix:after {
content: '.';
display: block;
height: 0;
clear: both;
visibility: hidden;
}
/* Marker tweaks */
.mapboxgl-popup {
padding-bottom: 50px;
}
.mapboxgl-popup-close-button {
display: none;
}
.mapboxgl-popup-content {
font: 400 15px/22px 'Source Sans Pro',Sans-serif;
padding: 0;
width: 180px;
}
.mapboxgl-popup-content-wrapper {
padding: 1%;
}
.mapboxgl-popup-content h3 {
background: #91c949;
color: #fff;
margin: 0;
display: block;
padding: 10px;
border-radius: 3px 3px 0 0;
font-weight: 700;
margin-top: -15px;
}
.mapboxgl-popup-content h4 {
margin: 0;
display: block;
padding: 10px 10px 10px 10px;
font-weight: 400;
}
.mapboxgl-popup-content div {
padding: 10px;
}
.mapboxgl-container .leaflet-marker-icon {
cursor: pointer;
}
.mapboxgl-popup-anchor-top > .mapboxgl-popup-content {
margin-top: 15px;
}
.mapboxgl-popup-anchor-top > .mapboxgl-popup-tip {
border-bottom-color: #91c949;
}
<link href="https://api.tiles.mapbox.com/mapbox-gl-js/v2.2.0/mapbox-gl.css" rel="stylesheet"/>
<script src="https://api.tiles.mapbox.com/mapbox-gl-js/v2.2.0/mapbox-gl.js"></script>
<div class="sidebar">
<div class="heading">
<h1>Our locations</h1>
</div>
<div id="listings" class="listings"></div>
</div>
<div id="map" class="map"></div>
这是他们发布的关于生成标记的教程。我现在的问题是我希望能够添加标记的其他部分,例如商店。我发现 api 可供我使用,但我不确定使这种动态化和最佳实践的最佳方法。我的意思是在单击按钮时加载 API 数据的最佳做法是什么?或者当页面加载时,加载标记的所有部分?
我让它动态化的想法是一个包含大部分现有 javascript 的函数,当点击一个新部分时,它会运行。然后,这将传入单击的部分的 ID(如 中),但例如传入“sweetgreen”或“supermakerts”作为 id,这在 switch 案例中用于定义 api 以调用标记。
我的问题是原始代码似乎没有预见到添加额外的标记部分,我只是想在这方面得到一些指导。
谢谢
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。