在动态生成的DIV的鼠标悬停上显示谷歌地图标记信息名称
Showing Google Maps Marker infoname on Mouseover of a Dynamically Generated DIV
我想引入一个功能,该功能允许标记的信息名称在从jQuery生成的相应div元素鼠标悬停或移出时出现或消失。然而,我在main.js的第19行遇到了一个">a is undefined"错误。经过对我的脚本的广泛测试,我意识到这与新添加的行中的标记有关,如下所述:
function addMarker(A) {
var point = new google.maps.LatLng(A.lat, A.lng);
var image = new google.maps.MarkerImage('images/r.png',
new google.maps.Size(30, 30),
new google.maps.Point(0, 0),
new google.maps.Point(0, 30));
marker = new google.maps.Marker({
map: map,
position: point,
icon: image,
});
}
function addInfoName(A) {
var infoname = new infoName; // custom object
google.maps.event.addListener(marker, 'mouseover', function(event) {infoname.show();});
google.maps.event.addListener(marker, 'mouseout', function(event) {infoname.hide();});
infoname.open(map, marker);
}
function showResult(A) {
$('#results').append('<DIV id=' + A.pid + '>{Blah Blah Blah}</DIV>');
return document.getElementById(A.pid);
}
function process(json) {
$('#results').empty();
total = json.details.length;
for(i=0; i<total; i++) {
var detail = json.details[i];
var marker;
addMarker(detail);
addInfoName(detail);
// these new lines are added
var listDisplay = showResult(detail);
listDisplay.onmouseover = function(){google.maps.event.trigger(marker, 'mouseover');};
listDisplay.onmouseout = function(){google.maps.event.trigger(marker, 'mouseout');};
}
}
google.maps.event.addListener(map, 'idle', function () {$.getJSON(query, process);});
如果我将函数addInfoName
合并到process
,则错误消失。然而,如果我这样做,所有的DIV都会指向最后一个标记。我的问题是,我如何修改我的脚本以实现上面提到的功能?
当前,您有一个声明为process
函数本地的变量marker
,但您正在尝试从其他函数读取和写入它。特别地,addMarker
在没有var
的情况下写入marker
,这会导致意外的全局变量被创建。同时,process
实际上并没有写入它声明的marker
本地,所以它包含undefined
,当你传入它时,它会绊倒谷歌地图代码。
(像jslint或ECMAScript 5 Strict Mode这样的工具可以为您捕获意外全局。注意total
和i
也是意外全局。(
看起来addMarker
和addInfoname
已经从process
的主体中被黑客入侵,而没有绑定它们都使用的process
中的变量。如果它们包含在process
的主体中,它会起作用,但您会得到所描述的行为,因为闭包循环问题,每个div都使用相同的marker
值。
这个问题发生在具有闭包和函数级作用域的语言中,包括JavaScript、Python和其他语言。在这些语言中,for
循环定义的或循环内部的任何变量都是包含函数的本地变量,而不是每次循环时重新分配的。因此,如果在循环的第一次迭代中创建一个引用i
的闭包,那么它与循环的第二次迭代中引用的变量i
相同;函数的每个实例在相同的变量CCD_ 22上都有一个闭包,因此每个函数都将看到相同的值。CCD_ 23也是如此。
闭包循环问题可以通过使用第二个闭包来避免,该闭包将循环变量保持在参数中,或者更干净地说,使用基于闭包的循环机制而不是类似C的for
循环。ECMAScript 5为此提供array.forEach()
,jQuery提供$.each()
:
function process(json) {
$('#results').empty();
var gev= google.maps.event;
$.each(json.details, function(detaili, detail) {
var marker= addMarker(detail.lat, detail.lng);
$('#results').append($('<div>', {
text: detail.name,
mouseover: function() { gev.trigger(marker, 'mouseover'); },
mouseout: function() { gev.trigger(marker, 'mouseout'); }
}));
var infoname= new InfoName();
gev.addListener(marker, 'mouseover', function() { infoname.show(); });
gev.addListener(marker, 'mouseout', function() { infoname.hide(); });
infoname.open(map, marker);
});
}
function addMarker(lat, lng) {
return new google.maps.Marker({
map: map,
position: new google.maps.LatLng(lat, lng),
icon: new google.maps.MarkerImage(
'images/r.png',
new google.maps.Size(30, 30),
new google.maps.Point(0, 0),
new google.maps.Point(0, 30)
)
});
}
"a未定义"错误可能是因为您试图在dom准备好之前创建映射。至少,这是我唯一一次看到它。我无法从你的代码中判断你在哪里创建它,但要确保mapdiv已经准备好了。您必须将对initialize函数的调用放在页面底部或页面加载侦听器中。这里有一种方法可以做到这一点(这可以在页面中的任何地方进行(:
function initialize() {
var map = new google.maps.Map(document.getElementById("map_canvas"), {
zoom: 6,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
google.maps.event.addListener(map, 'idle', function () {
$.getJSON(query, process);
});
}
google.maps.event.addDomListener(window, 'load', initialize);
还要注意,您的空闲侦听器也会进入init函数,因为在创建映射之前,它将无法运行。
如果这不是导致"a未定义"错误的原因,那么我在您发布的代码中看不到它。但是,我确实看到您的代码存在其他一些问题。所以也许这就是造成它的原因。首先,process
中的var marker;
定义没有任何作用。在这里,您正在创建一个局部变量,但该局部变量从未被定义。那么addMarker
就是通过定义不带var
的marker
来创建全局变量。因此,addInfoname
中的标记总是指全局标记,它将始终是最后定义的标记。这就是为什么div总是带着最后一个标记出现的原因。我会在addMarker中的marker = ...
之前放一个return,并用它来设置标记变量,如下所示:
var marker = addMarker(detail);
当然,在process
中。然后,您还必须将其作为参数发送到addInfoname,以便它获得正确的参数。
- 如何更改角度谷歌地图上的集群图标
- 谷歌地图API-显示具有不同图标的标记
- 谷歌地图-更改图层图标大小
- 在地图加载/页面加载时,我想将地图设置为当前地理位置,但不想在地图上显示定位图标
- 将图标作为参数传递不会;t工作-谷歌地图
- 谷歌地图隐藏手图标
- 从谷歌地图信息窗口中删除关闭图标
- 在javascript中设置谷歌地图标记图标属性
- 我是否可以在单击特定图标时更改地图标记图标,然后在单击另一个图标时切换,等等
- 我如何才能在某些条件下更改c#中谷歌地图标记的图标
- 使用HTML元素代替gmap3的地图标记图标
- 谷歌地图标记图标作为变量
- 我如何使谷歌地图不更改标记的自定义图标大小
- 饼图而不是谷歌地图中的标记集群图标
- 如何在谷歌地图上放置图标标记,图标数量是否有配额
- 可拖动图标未显示在 Google 地图顶部且不重复
- 谷歌地图v3更改标记图标在安卓网络视图
- AngularJS谷歌地图(ng-map)图标网址不起作用
- 带有群集和过滤器复选框的地图框个性化图标
- 添加 removeMarker 函数时,每 5 秒在地图上加载一次图钉不会显示图标