传单弹出循环
Leaflet Popup Loop
我最近一直在玩 Leaflet,并将其集成到 WordPress 自定义 post 类型中。我向城市的自定义 post 类型添加了一个字段。然后将其编码为 JavaScript 并发送到 Mapbox 获取坐标。然后将坐标发送到显示标记的函数。那部分效果很好。我遇到的问题是让标题正确循环并显示在弹出对话框中。当我查看源代码时,我发现名称和城市都被正确编码了。代码如下。谢谢!
// Loops through CPT and puts both city and name into array
// TODO: Rename hometown to something more relevant
while ($loop->have_posts()) : $loop->the_post();
$post_meta = get_post_meta($post->ID, 'hometown', true);
$title = get_the_title($post->ID);
if ( !empty ( $post_meta ) || !empty ( $title ) ) {
$hometown[] = array(
'city' => $post_meta,
'name' => $title
);
}
endwhile;
<script>
var hometown = <?php echo wp_json_encode($hometown); ?>;
var map = L.map('map').setView([40, 0], 2);
L.mapbox.accessToken = 'myToken';
var geocoder = L.mapbox.geocoder('mapbox.places');
for ( var i = 0; i < hometown.length; i++ )
{
geocoder.query(hometown[i].city, showLoc);
}
L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=myToken', {
maxZoom: 18,
attribution: 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, ' +
'<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
'Imagery © <a href="http://mapbox.com">Mapbox</a>',
id: 'mapbox.streets'
}).addTo(map);
function showLoc(err, data) {
L.marker([data.latlng[0], data.latlng[1]], 2)
.bindPopup(hometown[0].name)
.addTo ( map );
}
</script>
例如,我们有以下数组:
var homes = [{
name: 'Jane Doe',
city: 'Denver, Colorado'
},{
name: 'John Doe',
city: 'Houston, Texas'
}];
我们将遍历数组的项目并从 Mapbox 的地理编码器服务中查询每个城市 属性:
for (var i = 0; i < homes.length; i++) {
geocoder.query(homes[i].city, callback);
}
实际上将按此顺序执行以下操作:
geocoder.query('Denver, Colorado', callback);
geocoder.query('Houston, Texas', callback);
当这些请求完成后,它将为每个查询执行 callback
方法:
function callback (err, data) {
// do stuff
}
问题是请求是 asynchronous,我们无法确定它们是否会按照我们请求的顺序完成。所以在 callback
方法内部我们无法直接知道结果来自哪个项目:
function callback (err, data) {
// Who's data is this?
}
幸运的是,callback
方法提供的 data
对象保存了 data.results.query
属性:
中的原始查询
function callback (err, data) {
console.log(data.results.query);
}
这会将 ['denver', 'colorado']
或 ['houston', 'texas']
记录到您的控制台,具体取决于它来自哪个查询。现在您可以在 homes
数组中搜索城市和 return 名称:
function callback (err, data) {
// join the query array so we get the same string as we've queried
var city = data.results.query.join(', ');
// iterate over the homes array
for (var i = 0; i < homes.length; i++) {
// compare cities in lowercase (result returns in lowercase)
if (homes[i].city.toLowerCase() === city) {
// found match, do stuff
}
}
}
对于您的解决方案,它看起来像这样:
function callback (err, data) {
var city = data.results.query.join(', ');
for (var i = 0; i < homes.length; i++) {
if (homes[i].city.toLowerCase() === city) {
new L.Marker([data.latlng[0], data.latlng[1]])
.bindPopup(homes[i].name)
.addTo(map);
}
}
}
您可以在这里尝试一下:http://jsfiddle.net/73hg2L4y/(使用您自己的令牌)
希望对你有所帮助,祝你好运!
注意:一旦您有两个同一个城市的名字,您就会 运行 遇到麻烦,因此最好确保所有地址都是唯一的。
我最近一直在玩 Leaflet,并将其集成到 WordPress 自定义 post 类型中。我向城市的自定义 post 类型添加了一个字段。然后将其编码为 JavaScript 并发送到 Mapbox 获取坐标。然后将坐标发送到显示标记的函数。那部分效果很好。我遇到的问题是让标题正确循环并显示在弹出对话框中。当我查看源代码时,我发现名称和城市都被正确编码了。代码如下。谢谢!
// Loops through CPT and puts both city and name into array
// TODO: Rename hometown to something more relevant
while ($loop->have_posts()) : $loop->the_post();
$post_meta = get_post_meta($post->ID, 'hometown', true);
$title = get_the_title($post->ID);
if ( !empty ( $post_meta ) || !empty ( $title ) ) {
$hometown[] = array(
'city' => $post_meta,
'name' => $title
);
}
endwhile;
<script>
var hometown = <?php echo wp_json_encode($hometown); ?>;
var map = L.map('map').setView([40, 0], 2);
L.mapbox.accessToken = 'myToken';
var geocoder = L.mapbox.geocoder('mapbox.places');
for ( var i = 0; i < hometown.length; i++ )
{
geocoder.query(hometown[i].city, showLoc);
}
L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=myToken', {
maxZoom: 18,
attribution: 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, ' +
'<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
'Imagery © <a href="http://mapbox.com">Mapbox</a>',
id: 'mapbox.streets'
}).addTo(map);
function showLoc(err, data) {
L.marker([data.latlng[0], data.latlng[1]], 2)
.bindPopup(hometown[0].name)
.addTo ( map );
}
</script>
例如,我们有以下数组:
var homes = [{
name: 'Jane Doe',
city: 'Denver, Colorado'
},{
name: 'John Doe',
city: 'Houston, Texas'
}];
我们将遍历数组的项目并从 Mapbox 的地理编码器服务中查询每个城市 属性:
for (var i = 0; i < homes.length; i++) {
geocoder.query(homes[i].city, callback);
}
实际上将按此顺序执行以下操作:
geocoder.query('Denver, Colorado', callback);
geocoder.query('Houston, Texas', callback);
当这些请求完成后,它将为每个查询执行 callback
方法:
function callback (err, data) {
// do stuff
}
问题是请求是 asynchronous,我们无法确定它们是否会按照我们请求的顺序完成。所以在 callback
方法内部我们无法直接知道结果来自哪个项目:
function callback (err, data) {
// Who's data is this?
}
幸运的是,callback
方法提供的 data
对象保存了 data.results.query
属性:
function callback (err, data) {
console.log(data.results.query);
}
这会将 ['denver', 'colorado']
或 ['houston', 'texas']
记录到您的控制台,具体取决于它来自哪个查询。现在您可以在 homes
数组中搜索城市和 return 名称:
function callback (err, data) {
// join the query array so we get the same string as we've queried
var city = data.results.query.join(', ');
// iterate over the homes array
for (var i = 0; i < homes.length; i++) {
// compare cities in lowercase (result returns in lowercase)
if (homes[i].city.toLowerCase() === city) {
// found match, do stuff
}
}
}
对于您的解决方案,它看起来像这样:
function callback (err, data) {
var city = data.results.query.join(', ');
for (var i = 0; i < homes.length; i++) {
if (homes[i].city.toLowerCase() === city) {
new L.Marker([data.latlng[0], data.latlng[1]])
.bindPopup(homes[i].name)
.addTo(map);
}
}
}
您可以在这里尝试一下:http://jsfiddle.net/73hg2L4y/(使用您自己的令牌)
希望对你有所帮助,祝你好运!
注意:一旦您有两个同一个城市的名字,您就会 运行 遇到麻烦,因此最好确保所有地址都是唯一的。