Я не уверен, почему это не работает. У меня нет ошибок, но что происходит, на какой маркер я нажимаю, он всегда нажимает последний маркер. Я не уверен, почему, хотя, потому что the_marker настраивается тот же путь. Как я могу зафиксировать это?:
(Обновленный с новым jQuery + XML)
$(function(){
var latlng = new google.maps.LatLng(45.522015,-122.683811);
var settings = {
zoom: 15,
center: latlng,
disableDefaultUI:true,
mapTypeId: google.maps.MapTypeId.SATELLITE
};
var map = new google.maps.Map(document.getElementById("map_canvas"), settings);
$.get('mapdata.xml',{},function(xml){
$('location',xml).each(function(i){
the_marker = new google.maps.Marker({
title:$(this).find('name').text(),
map:map,
clickable:true,
position:new google.maps.LatLng(
parseFloat($(this).find('lat').text()),
parseFloat($(this).find('lng').text())
)
});
infowindow = new google.maps.InfoWindow({
content: $(this).find('description').text()
});
new google.maps.event.addListener(the_marker, 'click', function() {
infowindow.open(map,the_marker);
});
});
});
});
У вас очень распространенная проблема закрытия в следующем цикле:
for(x in locations){
console.log(x);
infowindow[x] = new google.maps.InfoWindow({content: x});
marker[x] = new google.maps.Marker({title:locations[x][0],map:map,position:locations[x][2]});
google.maps.event.addListener(marker[x], 'click', function() {infowindow[x].open(map,marker[x]);});
}
Переменные, заключенные в закрытие, используют одну и ту же единую среду, поэтому к моменту времени обратные вызовы щелчка
будут выполняется, цикл завершился, и переменная x
останется указывающей на последнюю запись.
Вы можете решить эту проблему с помощью еще большего количества замыканий, используя фабрику функций:
function makeInfoWindowEvent(map, infowindow, marker) {
return function() {
infowindow.open(map, marker);
};
}
for(x in locations){
infowindow[x] = new google.maps.InfoWindow({content: x});
marker[x] = new google.maps.Marker({title: locations[x][0],
map: map,
position: locations[x][3]});
google.maps.event.addListener(marker[x], 'click',
makeInfoWindowEvent(map, infowindow[x], marker[x]);
}
Это может быть довольно сложной темой, если вы не знакомы с тем, как работают замыкания. Вы можете ознакомиться со следующей статьей Mozilla для краткого введения:
ОБНОВЛЕНИЕ:
В дополнение к обновленному вопросу вы должны принять во внимание следующее:
Прежде всего, имейте в виду этот JavaScript не имеет области блока. Только функции имеют область видимости.
Когда вы назначаете переменную, которая ранее не была объявлена, с ключевым словом var
, она будет объявлена как глобальная переменная. Это часто считается уродливой функцией (или недостатком) JavaScript, поскольку она может незаметно скрыть многие ошибки. Поэтому этого следует избегать. У вас есть два экземпляра этих подразумеваемых глобальных переменных: the_marker
и infowindow
, и, собственно, именно поэтому ваша программа дает сбой.
В JavaScript есть закрытие. Это означает, что внутренние функции имеют доступ к переменным и параметрам внешней функции. Вот почему вы сможете получить доступ к the_marker
, информационному окну
и карте
из функции обратного вызова метода addListener
.Однако, поскольку ваши the_marker
и информационное окно
обрабатываются как глобальные переменные, закрытие не работает.
Все, что вам нужно сделать, это использовать ключевое слово var
при их объявлении, как в следующем примере:
$(function() {
var latlng = new google.maps.LatLng(45.522015,-122.683811);
var settings = {
zoom: 15,
center: latlng,
disableDefaultUI: true,
mapTypeId: google.maps.MapTypeId.SATELLITE
};
var map = new google.maps.Map(document.getElementById("map_canvas"), settings);
$.get('mapdata.xml', {}, function(xml) {
$('location', xml).each(function(i) {
var the_marker = new google.maps.Marker({
title: $(this).find('name').text(),
map: map,
clickable: true,
position: new google.maps.LatLng(
parseFloat($(this).find('lat').text()),
parseFloat($(this).find('lng').text())
)
});
var infowindow = new google.maps.InfoWindow({
content: $(this).find('description').text();
});
new google.maps.event.addListener(the_marker, 'click', function() {
infowindow.open(map, the_marker);
});
});
});
});