单击项目动画并在谷歌地图上显示相关标记的信息窗口



代码说明

1.在视图模型内声明animateMarker函数,参数marker

2.在视图模型内声明populateInfoWindow,其中包含三个参数(标记,信息窗口,元素(,并调用animateMarker函数。

3.在循环中调用populateInfoWindow单击事件侦听器,该侦听器在循环中遍历位置。

4.新增数据绑定:"点击:$root.填充信息窗口"<li data-bind : "click : $root.populateInfoWindow >

错误

无法读取未定义的属性"标题">

此外,标记既没有动画,也没有支付信息。 同时单击列表项。 对于此问题,是否有其他推荐的方法或想法来处理该错误。


应用.js

模型包含有关位置的必需数据

var model = [
{
title: 'Park Ave Penthouse',
latLng: {
lat: 40.7713024,
lng: -73.9632393
}
},
{
title: 'Chelsea Loft',
latLng: {
lat: 40.7444883,
lng: -73.9949465
}
},
{
title: 'Union Square Open Floor Plan',
latLng: {
lat: 40.7347062,
lng: -73.9895759
}
},
{
title: 'East Village Hip Studio',
latLng: {
lat: 40.7281777,
lng: -73.984377
}
},
{
title: 'TriBeCa Artsy Bachelor Pad',
latLng: {
lat: 40.7195264,
lng: -74.0089934
}
},
{
title: 'Chinatown Homey Space',
latLng: {
lat: 40.7180628,
lng: -73.9961237
}
}
];
//declaring global variables 
var infoWindow, map;
function initMap() {
//initialize the map
map = new google.maps.Map(document.getElementById('map'), {
center: model[3].latLng,
zoom: 12
});

myViewModel = new ViewModel();
ko.applyBindings(myViewModel)
};

function ViewModel() {
var self = this;
this.filter = ko.observable();
this.places = ko.observableArray(model);
self.infowindow = new google.maps.InfoWindow();
// self.marker = [];
model.forEach(function(element) {
var position = element.latLng;
var title = element.title;
element.marker = new google.maps.Marker({
position: position,
title: title,
map: map,
animation: google.maps.Animation.DROP,
});
// self.marker.push(element.marker);
element.marker.addListener('click', function() {
self.populateInfoWindow(this, self.infowindow, element);
});
});
self.populateInfoWindow = (function(marker, infowindow, element) {
self.infowindow.setContent('<div><strong>' + element.title + '</strong><br>');
self.infowindow.open(map, marker);
self.animateMarker(marker);
});
self.animateMarker = (function(marker) {
marker.setAnimation(google.maps.Animation.BOUNCE);
setTimeout(function() {
marker.setAnimation(null)
}, 1500);
});
this.visibleLocations = ko.computed(function() {
var filter = self.filter();
if (!filter) {
ko.utils.arrayForEach(self.places(), function(item) {
item.marker.setVisible(true);
});
return self.places();
} else {
return ko.utils.arrayFilter(self.places(), function(item) {
// set all markers visible (false)
var result = (item.title.toLowerCase().search(filter) >= 0);
item.marker.setVisible(result);
return result;
});
}
});
};
//loading google maps error handling 
function googleError() {
alert("check your internet connection and reload the page");

}

索引.html

<!DOCTYPE html>
<html>
<head>
<title> Nighbour hood map </title>
<link rel="stylesheet" type="text/css" href="css/style.css">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous">
<script type="text/javascript" src="js/lib/knockout-3.4.2.js"></script>
</head>
<body>
<div class="search-menu ">
<nav class="navbar navbar-light bg-faded justify-content-between">
<h1 class="navbar-brand"> Find your favorite place</h1>
<form class="form-inline">
<input class="form-control mr-sm-2" type="text" placeholder="Search" data-bind="textInput: filter">
</form>
</nav>
<ul class="list-group" data-bind="foreach: visibleLocations">
<li class="list-group-item list-group-item-action" data-bind="text: title, click :$root.populateInfoWindow"></li>
</ul>
</div>

<div id="map"></div>

<script type="text/javascript" src="js/app.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCX6bSgdTWvavwA0O8B7KsObZhE5GAf6yQ&callback=initMap" / onerror="googleError()" async defer>
</script>

</body>
</html>

由于InfoWindow.open方法需要第二个参数MVCObject对象(在本例中为标记对象(,因此需要从以下位置更改click事件绑定:

data-bind="click: $root.populateInfoWindow"

对此:

data-bind="click: $root.populateInfoWindow.bind(this,$data.marker,$root.infowindow)"

这样(通过bind功能(既markerinfoWindow参数正在传递给populateInfoWindow函数

修改后的示例

var model = [
{
title: 'Park Ave Penthouse',
latLng: {
lat: 40.7713024,
lng: -73.9632393
}
},
{
title: 'Chelsea Loft',
latLng: {
lat: 40.7444883,
lng: -73.9949465
}
},
{
title: 'Union Square Open Floor Plan',
latLng: {
lat: 40.7347062,
lng: -73.9895759
}
},
{
title: 'East Village Hip Studio',
latLng: {
lat: 40.7281777,
lng: -73.984377
}
},
{
title: 'TriBeCa Artsy Bachelor Pad',
latLng: {
lat: 40.7195264,
lng: -74.0089934
}
},
{
title: 'Chinatown Homey Space',
latLng: {
lat: 40.7180628,
lng: -73.9961237
}
}
];
//declaring global variables 
var infoWindow, map;
function initMap() {
//initialize the map
map = new google.maps.Map(document.getElementById('map'), {
center: model[3].latLng,
zoom: 12
});
myViewModel = new ViewModel();
ko.applyBindings(myViewModel)
};
function ViewModel() {
var self = this;
this.filter = ko.observable();
this.places = ko.observableArray(model);
self.infowindow = new google.maps.InfoWindow();
// self.marker = [];
model.forEach(function (element) {
var position = element.latLng;
var title = element.title;
element.marker = new google.maps.Marker({
position: position,
title: title,
map: map,
animation: google.maps.Animation.DROP,
});
// self.marker.push(element.marker);
element.marker.addListener('click', function () {
self.populateInfoWindow(this, self.infowindow, element);
});
});
self.populateInfoWindow = (function (marker, infowindow, element) {
self.infowindow.setContent('<div><strong>' + marker.title + '</strong><br>');
self.infowindow.open(map, marker);
self.animateMarker(marker);
});
self.animateMarker = (function (marker) {
marker.setAnimation(google.maps.Animation.BOUNCE);
setTimeout(function () {
marker.setAnimation(null)
}, 1500);
});
this.visibleLocations = ko.computed(function () {
var filter = self.filter();
if (!filter) {
ko.utils.arrayForEach(self.places(), function (item) {
item.marker.setVisible(true);
});
return self.places();
} else {
return ko.utils.arrayFilter(self.places(), function (item) {
// set all markers visible (false)
var result = (item.title.toLowerCase().search(filter) >= 0);
item.marker.setVisible(result);
return result;
});
}
});
};
google.maps.event.addDomListener(window, 'load', initMap);
#map {
height: 140px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-debug.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.js"></script>
<script src="https://maps.googleapis.com/maps/api/js"></script>
<script type="text/javascript" src="app.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ"
crossorigin="anonymous">
<link href="style.css" rel="stylesheet">
<div class="search-menu ">
<nav class="navbar navbar-light bg-faded justify-content-between">
<h1 class="navbar-brand"> Find your favorite place</h1>
<form class="form-inline">
<input class="form-control mr-sm-2" type="text" placeholder="Search" data-bind="textInput: filter">
</form>
</nav>
<ul class="list-group" data-bind="foreach: visibleLocations">
<li class="list-group-item list-group-item-action" data-bind="text: title, click: $root.populateInfoWindow.bind(this,$data.marker,$root.infowindow)"></li>
</ul>
</div>
<div id="map"></div>

最新更新