问题描述
我有一个Google地图,它可以从一个数组中加载数据,并且可以从一个数组中加载数据,
单击侧边栏项目可打开相应的infowindow,如预期的那样
当鼠标输入一个侧边栏项目时,它会根据需要进行平移,并突出显示相应的标记(并关闭当前打开的任何信息窗口)。
$ b
(。locs是侧边栏容器, .loc是一个项目)
$(document).on(mouseenter,。loc,function(){
var thisloc = $(this).data(locid);
for(var i = 0; i< markers.length; i ++){
if(markers [i]。 local == thisloc){//获取latlong
if(lastinfowindow instanceof google.maps.InfoWindow)lastinfowindow.close();
map.panTo(markers [i] .getPosition());
标记[i] .setIcon('../ mapIcons / mini-white.png');
}
}
});
这个位正常,因为我只是设置了一个固定的图像。
但是,当我mouseleave标记未能恢复到其原始状态。
如果我使用setIcon来处理特定的图像,它可以正常工作,但我想从数据集项目中引用原始图标。
标记物[I] .setIcon( currmark);
currmark是我用来保存原始图标的变种。
$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $($) (标记[i]);
var currmark = getIcon(mapData.type);
for(var i = 0; i< markers.length; i ++) (标记[i] .getPosition());
标记[i] .setIcon(currmark);
}
}
});
在'currmark'上设置的警报,我用来保存原始图标的var仅显示由mouseenter setIcon设置的最后一个图标。
这似乎暗示了数据集中的原始图标(mapdata.type)已被遗忘/由应用于标记[i]的最后设置取代。
我想我需要重新访问数据集来提醒当我设置时的原始状态的变量
$ b $ $ $ $ $ $ $ $ c $ var currmark =调用getIcon( mapData.type);
一些增加的信息....
我使用了一个实用函数,它将数据集中给定的'类型'转换为图标,因此是getIcon(type)函数。
function getIcon(type){
switch(type){
casebar:return../mapIcons/mini-blue.png;
caserestaurant:return../mapIcons/mini-red.png;
casecafe:return../mapIcons/mini-yellow.png;
default:return../mapIcons/mini-white.png;
$ / code>
数据录入的一个例子... p>
var data = [
{地址:'Rua Calheta',详细信息:'Restaurant',标题:'Dolphin',键入:'restaurant',ico:'red',lat:37.08570947136275,long: - 8.731633722782135}
];
我希望我能理解这一半。任何人都可以帮助我,因为我已经死了,我已经得到了这个。
甜菜根的第二个附加信息显示了我的标记和边栏最初是如何设置的....
data.forEach(function(mapData,idx){
var marker = new google.maps .Marker({
map:map,
position:new google.maps.LatLng(mapData.lat,mapData.long),
title:mapData.title,
icon: getIcon(mapData.type)
});
var linkHtml =('< a href =#'+ mapData.title +'>');
var contentHtml = < div id ='iw'class ='iw2'>< h3>+ link + mapData.title +< / a>< / h3>+ mapData.detail +< br& mapData.address +< / div>;
var infowindow = new google.maps.InfoWindow({
content:contentHtml
});
goog le.maps.event.addListener(marker,'click',function(){
if(lastinfowindow instanceof google.maps.InfoWindow)lastinfowindow.close();
marker.infowindow.open(map,marker);
lastinfowindow = marker.infowindow;
});
marker.locid = idx + 1;
marker.infowindow = infowindow;
标记[markers.length] = marker;
var spot =('< img src =''+(getIcon(mapData.type))+'/>');
var sideHtml ='< p class =locdata-locid ='+ marker.locid +'>'+ spot + mapData.title +'< / p>';
$(#locs)。append(sideHtml);
if(markers.length == data.length)doFilter();
});
编辑02/07
合并甜菜根 - 甜菜根的光滑变化后的完整源代码。在这里完整的,因为我现在不同意识,他只能帮助他,如果他有全貌!
现在尝试在学习后进行调试,我并不是那么聪明。
<!DOCTYPE html>
< html>
< head>
< / script>
< script type =text / javascriptsrc =jquery.min.js>< / script>
< script type =text / javascript>
var map;
var markers = [];
var lastinfowindow;
var locIndex;
// Credit:MDN
if(!Array.prototype.forEach){
Array.prototype.forEach = function(fn,scope){
for( var i = 0,len = this.length; i< len; ++ i){
fn.call(scope,this [i],i,this);
// my data〜cutdown and local for testing
var data = [
{address:'Rua Calheta',详细信息:'Restaurant',标题:'Dolphin',类型:'restaurant',icotyp:'red',lat:37.08570947136275,long: - 8.731633722782135},
{address:'Rua Calheta',详细信息:'Cafe',标题:'Cafe Calheta',类型:'cafe',icotyp:'yellow',lat:37.0858150589029,long: - 8.731550574302673},
{address:' Rua Calheta',详细信息:'Bar',标题:'Kellys',类型:'bar',icotyp:'red',lat:37.08583217639933,long: - 8.731239438056945},
{address:' Rua 2nd Abril',详细信息:'Bar',标题:'Godots',类型:'bar',icotyp:'blue',lat:37.08602046860496,long: - 8.731470108032226}
];
//翻译数据类型:图标
函数getIcon(type){
switch(type){
casebar:return../mapIcons /mini-blue.png;
caserestaurant:return../mapIcons/mini-red.png;
casecafe:return../mapIcons/mini-yellow.png;
default:return../mapIcons/mini-white.png;
函数初始化(){
var latlng = new google.maps.LatLng(37.08597981464561,-8.730670809745788);
var myOptions = {
zoom:18,
center:latlng,
mapTypeId:google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById(map_canvas),myOptions);
//修改了beetroot-beetroot'loop'函数来同时设置标记和边栏
var $ locs = $(#locs); // Used在循环内重复。
$ .each(data,function(idx,mapData){
//注意:将新标记作为`mapData`属性的关键赋值
mapData.marker = new google.maps.Marker({
map:map,
position:new google.maps.LatLng(mapData.lat,mapData.long),
title:mapData.title,
icon:getIcon(mapData.type)
});
var link ='< a href =#'+ mapData.title +'>'+ mapData.title + '< / a>';
var contentHtml =< div id ='iw'class ='iw2'>< h3>+ link +< / h3>+ mapData.detail +< br>+ mapData.address +< / div>;
//什么是'marker'现在必须被称为`mapData.marker`
mapData.marker.infowindow = new google.maps.InfoWindow({
content:contentHtml
});
google.maps.event.addListener(mapData.marker,'click',function( ){
if(lastinfowindow&& lastinfowindow.close)lastinfowindow.close();
//`this`指向被点击的元素; t他适当的标记
this.infowindow.open(map,this);
lastinfowindow = this.infowindow;
});
var spot ='< img src ='+(getIcon(mapData.type))+'/>';
//在这里,创建`sideitem`作为jQuery对象是很方便的,所以我们可以应用几个jQuery方法(不需要做任务)。
$('< p class =loc/>')
.html(spot + mapData.title)
.appendTo($ locs)
.data 'mapData',mapData); //<<<<<<<<<关键
});
doFilter(); //循环结束时应该可以执行这个语句。
$ b $(document).on(mouseenter,.loc,function(){
if(lastinfowindow&& lastinfowindow.close)lastinfowindow.close();
var mapData = $(this).data(mapData);
map.panTo(mapData.marker.getPosition()); //<<<<<<<
mapData.marker.setIcon(getIcon('')); //获取默认图标
))。on(mouseleave,.loc,function( ){
var mapData = $(this).data(mapData);
mapData.marker.setIcon(getIcon(mapData.type));
})。on(click ,。loc,function(){
var mapData = $(this).data(mapData);
mapData.marker.infowindow.open(map,mapData.marker);
lastinfowindow = mapData.marker.infowindow;
});
$ b $ *
对任何复选框进行每次更改运行
* /
函数doFilter(){
if(lastinfowindow& lastinfowindow.close)lastinfowindow.close(); //关闭最后的信息窗口,如果仍然打开并应用新的过滤器
if(!locIndex){
locIndex = {};
//我倒过索引标记找出loc的位置到标记索引
for(var x = 0,len = markers.length; x locIndex [标记[x] .locid] = x;
}
}
//检查了什么?
var checked = $(input [type = checkbox]:checked);
var selTypes = [];
for(var i = 0,len = checked.length; i< len; i ++){
selTypes.push($(checked [i])。val()); $ i
for(var i = 0,len = data.length; i var sideDom =p.loc [data-locid =+(i + 1)+ ];
//如果长度为$ = 0
if(checked.length!= 0&& selTypes.indexOf(data [i] .type)< 0){
$(sideDom).hide();
标记[locIndex [i + 1]]。setVisible(false);
} else {
$(sideDom).show();
标记[locIndex [i + 1]]。setVisible(true);
$ b $(document).on(click,input [type = checkbox],doFilter);
}
< / script>
< style type =text / css>
#container {width:920px; height:500px; margin-left:auto; margin-right:auto;}
#map_canvas {width:700px; height:500px; float:left; border:1px gray solid; margin-right:10px;}
/ *侧边栏样式* /
#locs {margin-top:0px; padding- top:0px; margin-left:5px; height:500px; width:200px; overflow-y:auto; overflow-x:hidden;}
#locs img {float:left; padding-right:5px;}
.loc {border:0; width:200px; padding:2px; cursor:pointer; margin:0; text-transform:uppercase; font-family:Arial,Helvetica,sans-serif; font-size:0.90 em;}
/ *复选框样式* /
#form {margin-top:0px; padding-top:0px; height:29px;}
.label {width: 32.5%; margin:0; padding:4px 0 4px 4px; display:inline-block; font-family:Trebuchet MS,Verdana,Arial,sans-serif; text-transform:uppercase; font-size:0.75em; font-weight:bold;}
.red {color:white; background-color:red;}
.yellow {color:yellow; background-color:black;}
.blue {颜色:白色;背景颜色:蓝色;}
/ *地图信息样式* /
#map_canvas div#iw {width:250px; height:65px; overflow:hidden;}
#map_canvas h3 {font-si ZE:1EM;余量:0; padding:3px;}
#map_canvas .iw2 a {text-decoration:none; border-bottom:thin blue dashed;}
#map_canvas .iw2 a:hover {text-decoration:none; border-底部:薄红色实心;}
< / style>
< / head>
< body onLoad =initialize()>
< div id =container>
< div id =map_canvas>< / div> <! - 地图// - >
< div id =locs>< / div> <! - 侧边栏 - >
< div id =formstyle =margin:0; padding:0; border:thin gray solid; width:910px>
< span class =label blue>< input type =checkboxname =barsvalue =bar>酒吧< / span>
< span class =label yellow>< input type =checkboxname =cafesvalue =cafe>咖啡馆< / span>
< span class =label red>< input type =checkboxname =restaurantsvalue =restaurant>餐厅< / span>
< / div>
< / div> <! - 容器的结尾// - >
< / body>
< / html>
编辑3 - 03/07 - 修正初始标记/边栏
// BB - 修改每个循环函数以同时设置标记和边栏
var $ locs = $(#locs); //在循环中重复使用。
$ .each(data,function(idx,mapData){
// BB - 注意:将新标记作为mapData属性的关键赋值
mapData .marker = new google.maps.Marker({
map:map,
position:new google.maps.LatLng(mapData.lat,mapData.long),
title:mapData.title ,
icon:getIcon(mapData.type)
});
var link ='< a href =#'+ mapData.title +'> '+ mapData.title +'< / a>';
var contentHtml =< div id ='iw'class ='iw2'>< h3>+ link +< / h3> ;+ mapData.detail +< br>+ mapData.address +< / div>;
//什么是'marker'现在必须被称为mapData。 marker
mapData.marker.infowindow = new google.maps.InfoWindow({
content:contentHtml
});
google.maps.event.addListener(mapData.marker, 'click',function(){
if(lastinfowindow&& lastinfowindow.close)lastinfowindow.close();
// BB - `thi s`指向被点击的元素;适当的标记
this.infowindow.open(map,this);
lastinfowindow = this.infowindow;
});
// BB - 在这里,创建`sideitem`作为jQuery对象是很方便的,所以我们可以应用几个jquery方法(不需要做任务)。
var spot ='< img src ='+(getIcon(mapData.type))+'/>';
$('< p class =loc/>')
.html(spot + mapData.title)
.appendTo($ locs)
.data 'mapData',mapData); //<<<<<<<<<关键
// BB - 在initialize()的$ .each()循环的底部,创建并填充每个类别的一个数组,作为标记的属性://
if( !标记[mapData.type])标记[mapData.type] = [];
标记[mapData.type] .push(mapData.marker);
});
//为每个循环结束
$
< script type =text / b $ b编辑4 - 07/07 - 修改后的完整脚本以供评论
的javascript>
var map;
// var markers = [];
//对象,而不是数组。 BB
var markers = {};
var lastinfowindow;
// var locIndex;
// Credit:MDN
if(!Array.prototype.forEach){
Array.prototype.forEach = function(fn,scope){
for( var i = 0,len = this.length; i< len; ++ i){
fn.call(scope,this [i],i,this);
// my data〜cutdown and local for testing
var data = [
{address:'Rua Calheta',细节:'南非&葡萄牙餐厅',标题:'海豚',类型:'餐厅',lat:37.08570947136275,长: - 8.731633722782135},
{地址:'Rua Calheta',细节:'Poruguese Cafe / Bar' ,title:'Cafe Calheta',类型:'cafe',lat:37.0858150589029,长: - 8.731550574302673},
{地址:'Rua Calheta',详细信息:'英国酒吧',标题:' Kellys',输入:'bar',lat:37.08583217639933,long: - 8.731239438056945},
{地址:'Rua 2nd Abril',细节:'英国酒吧',标题:'Godots',类型:'bar',lat:37.08602046860496,long: - 8.731470108032226},
{地址:'Rua 2nd Abril',细节:'中国餐厅',标题:'皇家花园',类型:餐厅',lat:37.086164896968405,long: - 8.731738328933715},
{地址:'Rua 2nd Abril',细节:'英文栏',标题:'Clives',类型:'bar'lat: 37.086125,长: - 8.731374},
{地址:'Rua 2nd Abril',细节:'英国餐厅',标题:'青柠树',类型:'餐厅',lat:37.086125877750365 看哪ng: - 8.731588125228881},
{地址:'Praia da Luz',详细信息:'Portuguese Restaurant',标题:'Alloro',类型:'restaurant',lat:37.09158,长: 8.724850},
{地址:'Rua Calheta',详细信息:'English Cafe / Bistro',标题:'Jakes',类型:'cafe',lat:37.0862601125538,长: - 8.732671737670898} ,
{address:'Av dos Pescadores',detail:'English& amp; amp; amp;葡萄牙餐厅',标题:'Chaplins',类型:'餐厅',lat:37.08550480361006,长: - 8.730005621910095},
{地址:'Av dos Pescadores',细节:'英语&放大器;葡萄牙餐厅',标题:'Atlantico',类型:'餐厅',lat:37.085425634814705,长: - 8.729941248893737},
{地址:'Av dos Pescadores',细节:'Indian Restaurant' title:'藏红花',输入:'restaurant',lat:37.08534432623613,long: - 8.729884922504425},
{地址:'Av dos Pescadores',细节:'Indian Restaurant',标题:'Pashmina ',输入:'restaurant',lat:37.08526729697597,long: - 8.729839324951171},
{地址:'Rua Calheta',细节:'英国酒吧',标题:'The Bull' 'bar',lat:37.085652442494,long: - 8.73089075088501},
{address:'Av dos Pescadores',detail:'English& amp; amp; amp; '餐厅',lat:37.08571577732778,长: - 8.729227781295776},
{地址:'Av dos Pescadores',细节:'英语和放大器' ;葡萄牙酒吧',标题:'Carlos',类型:'bar',lat:37.0856306176238,long: - 8.729227781295776}
];
// translate data.type:to icon $ b $ function getIcon(type){
switch(type){
casebar:return../ mapIcons /小型blue.png;
caserestaurant:return../mapIcons/mini-red.png;
casecafe:return../mapIcons/mini-green.png;
default:return../mapIcons/mini-white.png; //用作当前选择指示符
//默认值:return../mapIcons/marker-yellow-dot.png; //稍后使用而不是白色
}
}
函数初始化(){
var latlng = new google.maps.LatLng(37.08597981464561,-8.730670809745788) ;
var myOptions = {
zoom:17,
center:latlng,
mapTypeId:google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById(map_canvas),myOptions);
// ---------------------------------------- -------------------------------------------------
/ *
开始为/每个循环
* /
var $ locs = $(#locs); //在循环中重复使用。
$ .each(data,function(idx,mapData){
// BB - 注意:新标记作为mapData属性的关键赋值
/ / section 1 - 标记构造
mapData.marker = new google.maps.Marker({
map:map,
position:new google.maps.LatLng(mapData.lat,mapData.long ),
title:mapData.title,
icon:getIcon(mapData.type)
});
//第1节结束
//第2部分 - Infowindow构造
var link ='< a href =#'+ mapData.title +'>'+ mapData.title +'< / a>'; //创建链接名称
var contentHtml =< div id ='iw'class ='iw2'>< h3>+ link +< / h3>+ mapData.detail +< / div> ;; //样式信息窗口并添加详细信息
//什么是`marker`现在必须被称为`mapData.marker`
mapData.marker.infowindow = new google.maps.InfoWindow( {
content:contentHtml,
});
//第2节结束
/ / section 3 - 地图标记点击功能
google.maps.event.addListener(mapData.marker,'click',function(){
if(lastinfowindow&& lastinfowindow.close)lastinfowindow.close(); //关闭任何打开的infowindows
map.setZoom(18); //放大
map.setCenter(mapData.marker.getPosition()); //在选区中心
// BB - `this`指向被点击的元素;适当的标记
this.infowindow.open(map,this); //打开infowindow
lastinfowindow = this.infowindow; //记得关闭这个infowindow,如果在选择变化时仍然打开
});
//第3节结束
//第4节 - 显示地图标记和侧边栏项目
// BB - 在这里,创建sideitem作为jQuery是很方便的对象,所以我们可以应用几个jquery方法(不需要做任务)。
var spot ='< img src ='+(getIcon(mapData.type))+'/>'; // sidebar copy of marker for display
$('< p class =loc/>')
.html(spot + mapData.title)//侧边栏图标和名称
.appendTo($ locs)//添加到侧边栏容器
.data('mapData',mapData); //<<<<<<<<关键
// BB删除不匹配的边栏
marker.loc = $('< p class =loc/>').addClass(mapData.type ).html(spot + mapData .title).data('marker',{m:marker,type:mapData.type})。appendTo($ locs).get(0);
// BB - 在initialize()的$ .each()循环的底部,创建并填充每个类别的一个数组,作为标记的属性://
if(!markers [mapData。类型])标记[mapData.type] = [];
标记[mapData.type] .push(marker);
});
//为每个循环结束
// ---------------------------- -------------------------------------------------- -----------
} //初始化结束(?)
// ------------ -------------------------------------------------- ---------------------------
/ *
侧栏功能
* /
$(document).on(mouseenter,.loc,function(){
// if(lastinfowindow&& lastinfowindow.close)lastinfowindow.close(); // moving to点击时,避免意外移动鼠标时关闭
var mapData = $(this).data(mapData);
map.setZoom(18); //放大一点
map .setCenter(mapData.marker.getPosition()); //选择中心
//map.panTo(mapData.marker.getPosition())////直接引用标记可避免循环。
mapData.marker.setIcon(getIcon('')); //获取默认图标,即大黄点。
var mapData = $(this).dat一( 属于MapData);
mapData.marker.setIcon(getIcon(mapData.type)); //重置标记以更正类型
map.setZoom(17); // rest放大到默认值
map.setCenter(marker.getPosition()); //(在地图上居中放置
))。on(click,.loc,function(){//在地图
上打开相应的信息窗口if(lastinfowindow&& lastinfowindow.close )lastinfowindow.close();
var mapData = $(this).data(mapData);
//map.setZoom(19); // zoom in more maybe
mapData .marker.infowindow.open(map,mapData.marker); //打开infowindow
lastinfowindow = mapData.marker.infowindow; //记得关闭此infowindow,如果在选择更改时仍然打开
})
// ---------------------------------------- -------------------------------------------------
/ *
对任何复选框进行每次更改运行
* /
函数doFilter(){
if(lastinfowindow&& lastinfowindow。关闭)lastinfowindow.close(); //关闭上一个infowindow,如果仍然打开
alert(filter triggered);
$(input [type = checkbox])。each(function(i,checkbox){
var markersArr = markers [checkbox.value];
if(markersArr){
$ .each(markersArr,function(i,marker){
marker.loc.style.display = ['none','block'] [Number(checkbox.checked)]; // do not显示未选择的类型
marker.setVisible(checkbox.checked); //显示选定的类型
});
};
});
}
// --------------------------------------- --------------------------------------------------
/ *
在初始设置时运行
* /
doFilter();
// ---------------------------------------- ------------------------------------------------- $ (click,.cat,doFilter)$ b $ * /
$ *
$ *
$ *
$ * b
$ b< / script>
如果在创建标记的循环中,你给每个边栏项目引用它的标记而不是locid,那么就不需要循环来重新发现mouseenter / mouseleave上的标记。
即,不是设置:
thisloc.data(locid,id);
//如果在其他地方使用thisloc.data(locid),则保留此行。
set(在侧边栏项/标记创建循环中):
var marker = ....;
var thisloc = ...;
...
data [i] .marker = marker; //将一个.marker属性添加到原始数据集。
thisloc.data(itemData,data [i]); //将原始数据集与边栏条目相关联
现在mouseenter / mouseleave处理程序应该简化如下:
$ b $ (document).on(mouseenter,.loc,function(){
if(lastinfowindow&& lastinfowindow.close)lastinfowindow.close();
var data = $(this ).data(itemData);
map.panTo(data.marker.getPosition()); //<<<<<<直接引用标记避免循环
data.marker.setIcon(getIcon('')); //获取默认图标
})。on(mouseleave,.loc,function(){
var data = $(this).data(itemData);
data.marker.setIcon(getIcon(data.type));
});
注意:您不需要再次在mouseleave上平移到标记。
$$ b
编辑:
b
$ b
这应该回答提出的问题以及其他优点。现在我已经看到了主循环,它可以像这样修改,使用各种各样的mod:
var $ locs = $(#locs); //在循环中重复使用。
$ .each(data,function(idx,mapData){
//注意:将新标记作为`mapData`属性的关键赋值
mapData.marker = new google.maps.Marker({
map:map,
position:new google.maps.LatLng(mapData.lat,mapData.long),
title:mapData.title,
icon:getIcon(mapData.type)
});
var link ='< a href =#'+ mapData.title +'>'+ mapData.title + '< / a>';
var contentHtml =< div id ='iw'class ='iw2'>< h3>+ link +< / h3>+ mapData.detail +< br>+ mapData.address +< / div>;
//什么是'marker'现在必须被称为`mapData.marker`
mapData.marker.infowindow = new google.maps.InfoWindow({
content:contentHtml
});
google.maps.event.addListener(mapData.marker,'click',function( ){
if(lastinfowindow&& lastinfowindow.close)lastinfowindow.clos e();
//`this`指向被单击的元素;适当的标记
this.infowindow.open(map,this);
lastinfowindow = this.infowindow;
});
var spot ='< img src ='+(getIcon(mapData.type))+'/>';
//在这里,创建`sideitem`作为jQuery对象是很方便的,所以我们可以应用几个jQuery方法(不需要做任务)。
$('< p class =loc/>')
.html(spot + mapData.title)
.appendTo($ locs)
.data 'mapData',mapData); //<<<<<<<<<关键
});
doFilter(); //循环结束时应该可以执行这个语句。
并且相应的mouseenter / mouseleave处理程序是:
$(document).on(mouseenter,.loc,function(){
if(lastinfowindow&& amp ; lastinfowindow.close)lastinfowindow.close();
var mapData = $(this).data(mapData);
map.panTo(mapData.marker.getPosition()); //< ;<<<<<直接引用标记避免循环需要
mapData.marker.setIcon(getIcon('')); //获取默认图标
})。 (mouseleave,.loc,function(){
var mapData = $(this).data(mapData);
mapData.marker.setIcon(getIcon(mapData.type)) ;
});
全部未经测试,因此可能需要调试。
EDIT2:
我把它放在上面,数组 markers 没有被填充。现在我已经看到函数 doFilter()我可以看到应该填充 markers ,但是它更方便它是一个对象而不是数组。
markers = {}; //与前面相同的范围
在 $。each()循环的底部在 initialize()中,创建并填充每个类别的一个数组,作为标记的属性:
if(!markers [mapData.type])markers [mapData.type] = [];
标记[mapData.type] .push(mapData.marker);
通过这种方式填充标记您有一个非常简单的方法来识别每个类别中的所有标记,并且 doFilter()将极大地简化为:
<$如果(lastinfowindow&& lastinfowindow.close)lastinfowindow.close();函数doFilter(){
。
$(input [type = checkbox])。each(function(i,checkbox){
var markersArr = markers [checkbox.value];
if(markersArr){
$ .each(markersArr,function(i,marker){
marker.setVisible(checkbox.checked);
});
}
});
}
EDIT3
要让边栏条目显示/隐藏同类别控件, initialize()应如下所示:
函数initialize(){
var latlng = new google.maps.LatLng(37.08597981464561,-8.730670809745788);
var myOptions = {
zoom: 18,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById(map_canvas),myOptions);
var $locs = $(\"#locs\");//Used repeatedly inside the loop.
var marker;
$.each(data, function(idx, mapData) {
//Note: critical assignment of the new marker as a property of `mapData`.
marker = new google.maps.Marker({
map: map,
position: new google.maps.LatLng(mapData.lat, mapData.long),
title: mapData.title,
icon: getIcon(mapData.type)
});
var link = ’<a href=\"#\"’ + mapData.title +’\">’ + mapData.title + ’</a>’;
var contentHtml = \"<div id=’iw’ class=’iw2’><h3>\" + link + \"</h3>\" + mapData.detail + \"<br>\" + mapData.address + \"</div>\";
marker.infowindow = new google.maps.InfoWindow({
content: contentHtml
});
google.maps.event.addListener(marker, ’click’, function() {
closeLastInfoWindow();
//`this` refers back to the clicked element; the appropriate marker
this.infowindow.open(map, this);
lastinfowindow = this.infowindow;
});
var spot = ’<img src=\"’ + (getIcon(mapData.type)) + ’\" />’;
//Here, it’s convenient to create what was `sideitem` as a jQuery object, so we can apply several jquery methods.
marker.loc = $(’<p class=\"loc\" />’)
.addClass(mapData.type)
.html(spot + mapData.title)
.data(’marker’, {m:marker, type:mapData.type})
.appendTo($locs).get(0);
if(!markers[mapData.type]) markers[mapData.type] = [];
markers[mapData.type].push(marker);
});
$(document).on(\"mouseenter\", \".loc\", function() {
closeLastInfoWindow();
var m = $(this).data(\"marker\").m;
map.panTo(m.getPosition());//<<<< direct reference to the marker avoids the need to loop.
m.setIcon(getIcon(’’));//get the default icon.
}).on(\"mouseleave\", \".loc\", function() {
var data = $(this).data(\"marker\");
data.m.setIcon(getIcon(data.type));
}).on(\"click\",\".loc\",function() {
var m = $(this).data(\"marker\").m;
m.infowindow.open(map, m);
lastinfowindow = m.infowindow;
});
$(\"#form\").on(\"click\", \".cat\", doFilter);
doFilter();
}
A wee bit out of my depth here, I hope someone can help me resolve this...
I have a Google map which loads data from an array and also populates a sidebar list of the items.
A click on the sidebar item opens the corresponding infowindow as expected o.k.
When I mouseenter a sidebar item it pans to if necessary and highlights the corresponding marker (and closes any infowindow currently open ).
(.locs is the sidebar container, .loc is an item)
$(document).on("mouseenter",".loc",function() { var thisloc = $(this).data("locid"); for(var i=0; i<markers.length; i++) { if(markers[i].locid == thisloc) { //get the latlong if(lastinfowindow instanceof google.maps.InfoWindow) lastinfowindow.close(); map.panTo(markers[i].getPosition()); markers[i].setIcon('../mapIcons/mini-white.png'); } } });
This bit works fine as I'm just setting a fixed image.However, when I mouseleave the marker fails to revert back to its original state.If I use the setIcon for a specic image it works fine, but I want to refer back to the original icon from the dataset item.
markers[i].setIcon("currmark");
currmark is the var I used to hold the original icon.
$(document).on("mouseleave",".loc",function() { var thisloc = $(this).data("locid"); var currmark = getIcon("mapData.type"); for(var i=0; i<markers.length; i++) { if(markers[i].locid == thisloc) { //get the latlong map.panTo(markers[i].getPosition()); markers[i].setIcon("currmark"); } } });
An alert set on 'currmark', the var I used to hold the original icon, shows only the last icon set by the mouseenter setIcon.This seems to idicate to me that the original icon from the dataset (mapdata.type) has been forgotten / replaced by the last setting applied to markers[i].I think I need to reaccess the dataset to remind the var of the original state when I set
var currmark = getIcon("mapData.type");
Some added info....
I'm using a utility function that translates a given 'type' in the dataset to an icon, hence the getIcon(type) function.
function getIcon(type) { switch(type) { case "bar": return "../mapIcons/mini-blue.png"; case "restaurant": return "../mapIcons/mini-red.png"; case "cafe": return "../mapIcons/mini-yellow.png"; default: return "../mapIcons/mini-white.png"; } }
An example of a data entry...
var data = [ {address:'Rua Calheta',detail:'Restaurant',title:'Dolphin',type:'restaurant',ico:'red',lat:"37.08570947136275",long:"-8.731633722782135"} ];
I hope I've explained this half sensibly. Can anyone assist me, as I was dead chuffed I'd got this far.
2nd Additional Info for Beetroot showing how my marker and sidebar are initially setup....
data.forEach(function(mapData,idx) { var marker = new google.maps.Marker({ map: map, position: new google.maps.LatLng(mapData.lat,mapData.long), title: mapData.title, icon: getIcon(mapData.type) }); var link=('<a href="#"' + mapData.title +'">'); var contentHtml = "<div id='iw' class='iw2'><h3>" + link + mapData.title+"</a></h3>" + mapData.detail+"<br>"+mapData.address+"</div>"; var infowindow = new google.maps.InfoWindow({ content: contentHtml }); google.maps.event.addListener(marker, 'click', function() { if(lastinfowindow instanceof google.maps.InfoWindow) lastinfowindow.close(); marker.infowindow.open(map, marker); lastinfowindow = marker.infowindow; }); marker.locid = idx+1; marker.infowindow = infowindow; markers[markers.length] = marker; var spot=('<img src="' + (getIcon(mapData.type)) + '" />'); var sideHtml = '<p class="loc" data-locid="'+marker.locid+'">'+spot+mapData.title+'</p>'; $("#locs").append(sideHtml); if(markers.length == data.length) doFilter(); });
EDIT 02/07The complete source after incorporating Beetroot-Beetroot's slick changes. Here in its entirety as I'm now vary aware that he can only help if he has the whole picture!Now attempting to debug after learning I'm not such a smartass.
<!DOCTYPE html> <html> <head> <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false& style=feature:all|element:labels|visibility:off"> </script> <script type="text/javascript" src="jquery.min.js"></script> <script type="text/javascript"> var map; var markers = []; var lastinfowindow; var locIndex; //Credit: MDN if ( !Array.prototype.forEach ) { Array.prototype.forEach = function(fn, scope) { for(var i = 0, len = this.length; i < len; ++i) { fn.call(scope, this[i], i, this); } } } //my data ~ cutdown and local for testing var data = [ {address:'Rua Calheta',detail:'Restaurant',title:'Dolphin',type:'restaurant',icotyp:'red',lat:"37.08570947136275",long:"-8.731633722782135"}, {address:'Rua Calheta',detail:'Cafe',title:'Cafe Calheta',type:'cafe',icotyp:'yellow',lat:"37.0858150589029",long:"-8.731550574302673"}, {address:'Rua Calheta',detail:'Bar',title:'Kellys',type:'bar',icotyp:'red',lat:"37.08583217639933",long:"-8.731239438056945"}, {address:'Rua 2nd Abril',detail:'Bar',title:'Godots',type:'bar',icotyp:'blue',lat:"37.08602046860496",long:"-8.731470108032226"} ]; // translate data type: to icon function getIcon(type) { switch(type) { case "bar": return "../mapIcons/mini-blue.png"; case "restaurant": return "../mapIcons/mini-red.png"; case "cafe": return "../mapIcons/mini-yellow.png"; default: return "../mapIcons/mini-white.png"; } } function initialize() { var latlng = new google.maps.LatLng(37.08597981464561, -8.730670809745788); var myOptions = { zoom: 18, center: latlng, mapTypeId: google.maps.MapTypeId.ROADMAP }; map = new google.maps.Map(document.getElementById("map_canvas"),myOptions); // revised beetroot-beetroot 'loop' function to set markers and sidebar at the same time var $locs = $("#locs");//Used repeatedly inside the loop. $.each(data, function(idx, mapData) { //Note: critical assignment of the new marker as a property of `mapData`. mapData.marker = new google.maps.Marker({ map: map, position: new google.maps.LatLng(mapData.lat,mapData.long), title: mapData.title, icon: getIcon(mapData.type) }); var link = '<a href="#"' + mapData.title +'">' + mapData.title + '</a>'; var contentHtml = "<div id='iw' class='iw2'><h3>" + link + "</h3>" + mapData.detail + "<br>" + mapData.address + "</div>"; //What was `marker` must now be referred to as `mapData.marker` mapData.marker.infowindow = new google.maps.InfoWindow({ content: contentHtml }); google.maps.event.addListener(mapData.marker, 'click', function() { if(lastinfowindow && lastinfowindow.close) lastinfowindow.close(); //`this` refers back to the clicked element; the appropriate marker this.infowindow.open(map, this); lastinfowindow = this.infowindow; }); var spot = '<img src="' + (getIcon(mapData.type)) + '" />'; //Here, it's convenient to create what was `sideitem` as a jQuery object, so we can apply several jquery methods (without making an assignment). $('<p class="loc" />') .html(spot + mapData.title) .appendTo($locs) .data('mapData', mapData);//<<<<<<<< critical }); doFilter(); //It should be possible to execute this statement when the loop is finished. $(document).on("mouseenter", ".loc", function() { if(lastinfowindow && lastinfowindow.close) lastinfowindow.close(); var mapData = $(this).data("mapData"); map.panTo(mapData.marker.getPosition());//<<<< direct reference to the marker avoids the need to loop. mapData.marker.setIcon(getIcon(''));//get the default icon. }).on("mouseleave", ".loc", function() { var mapData = $(this).data("mapData"); mapData.marker.setIcon(getIcon(mapData.type)); }).on("click",".loc",function() { var mapData = $(this).data("mapData"); mapData.marker.infowindow.open(map, mapData.marker); lastinfowindow = mapData.marker.infowindow; }); /* Run on every change to any of the checkboxes */ function doFilter() { if(lastinfowindow && lastinfowindow.close) lastinfowindow.close(); //Close last info windows if still open and new filter applied if(!locIndex) { locIndex = {}; //I reverse index markers to figure out the position of loc to marker index for(var x=0, len=markers.length; x<len; x++) { locIndex[markers[x].locid] = x; } } //what's checked? var checked = $("input[type=checkbox]:checked"); var selTypes = []; for(var i=0, len=checked.length; i<len; i++) { selTypes.push($(checked[i]).val()); } for(var i=0, len=data.length; i<len; i++) { var sideDom = "p.loc[data-locid="+(i+1)+"]"; //Only hide if length != 0 if(checked.length !=0 && selTypes.indexOf(data[i].type) < 0) { $(sideDom).hide(); markers[locIndex[i+1]].setVisible(false); } else { $(sideDom).show(); markers[locIndex[i+1]].setVisible(true); } } } $(document).on("click", "input[type=checkbox]", doFilter); } </script> <style type="text/css"> #container {width:920px;height:500px; margin-left:auto;margin-right:auto;} #map_canvas {width: 700px; height: 500px;float:left;border:1px gray solid;margin-right:10px;} /* sidebar styling */ #locs {margin-top: 0px;padding-top: 0px;margin-left: 5px;height: 500px;width:200px;overflow-y: auto;overflow-x: hidden;} #locs img {float:left;padding-right:5px;} .loc {border: 0;width: 200px;padding: 2px;cursor: pointer;margin:0;text-transform:uppercase;font-family:Arial, Helvetica, sans-serif;font-size:0.90em;} /* checkbox styling */ #form {margin-top: 0px;padding-top: 0px;height: 29px;} .label {width: 32.5%;margin: 0;padding: 4px 0 4px 4px;display: inline-block;font-family: "Trebuchet MS", Verdana, Arial, sans-serif;text-transform: uppercase;font-size: 0.75em;font-weight: bold;} .red {color:white;background-color:red;} .yellow {color:yellow;background-color:black;} .blue {color:white;background-color:blue;} /* Map info styling */ #map_canvas div#iw {width:250px;height:65px;overflow:hidden;} #map_canvas h3 {font-size:1em; margin:0; padding:3px;} #map_canvas .iw2 a {text-decoration:none;border-bottom:thin blue dashed;} #map_canvas .iw2 a:hover {text-decoration:none;border-bottom:thin red solid;} </style> </head> <body onLoad="initialize()"> <div id="container"> <div id="map_canvas"></div> <!-- map //--> <div id="locs"></div> <!-- sidebar //--> <div id="form" style="margin:0;padding:0;border:thin gray solid;width:910px"> <span class="label blue"><input type="checkbox" name="bars" value="bar">Bars</span> <span class="label yellow"><input type="checkbox" name="cafes" value="cafe">Cafes</span> <span class="label red"><input type="checkbox" name="restaurants" value="restaurant">Restaurants</span> </div> </div> <!-- end of container //--> </body> </html>
EDIT 3 - 03/07 - Revised initialise marker / sidebar
// BB - revised each loop function to set markers and sidebar at the same time var $locs = $("#locs");//Used repeatedly inside the loop. $.each(data, function(idx, mapData) { //BB - Note: critical assignment of the new marker as a property of `mapData`. mapData.marker = new google.maps.Marker({ map: map, position: new google.maps.LatLng(mapData.lat,mapData.long), title: mapData.title, icon: getIcon(mapData.type) }); var link = '<a href="#"' + mapData.title +'">' + mapData.title + '</a>'; var contentHtml = "<div id='iw' class='iw2'><h3>" + link + "</h3>" + mapData.detail + "<br>" + mapData.address + "</div>"; //What was `marker` must now be referred to as `mapData.marker` mapData.marker.infowindow = new google.maps.InfoWindow({ content: contentHtml }); google.maps.event.addListener(mapData.marker, 'click', function() { if(lastinfowindow && lastinfowindow.close) lastinfowindow.close(); //BB - `this` refers back to the clicked element; the appropriate marker this.infowindow.open(map, this); lastinfowindow = this.infowindow; }); //BB - Here, it's convenient to create what was `sideitem` as a jQuery object, so we can apply several jquery methods (without making an assignment). var spot = '<img src="' + (getIcon(mapData.type)) + '" />'; $('<p class="loc" />') .html(spot + mapData.title) .appendTo($locs) .data('mapData', mapData);//<<<<<<<< critical //BB - At the bottom of the $.each() loop in initialize(), create and populate one array per category, as properties of markers :// if(!markers[mapData.type]) markers[mapData.type] = []; markers[mapData.type].push(mapData.marker); }); // End of for/each loop
EDIT 4 - 07/07 - Revised full script for comment
<script type="text/javascript"> var map; //var markers = []; //object, not array. BB var markers = {}; var lastinfowindow; //var locIndex; //Credit: MDN if ( !Array.prototype.forEach ) { Array.prototype.forEach = function(fn, scope) { for(var i = 0, len = this.length; i < len; ++i) { fn.call(scope, this[i], i, this); } } } //my data ~ cutdown and local for testing var data = [ {address:'Rua Calheta',detail:'South African & Portuguese Restaurant',title:'Dolphin',type:'restaurant',lat:"37.08570947136275",long:"-8.731633722782135"}, {address:'Rua Calheta',detail:'Poruguese Cafe / Bar',title:'Cafe Calheta',type:'cafe',lat:"37.0858150589029",long:"-8.731550574302673"}, {address:'Rua Calheta',detail:'English Bar',title:'Kellys',type:'bar',lat:"37.08583217639933",long:"-8.731239438056945"}, {address:'Rua 2nd Abril',detail:'English Bar',title:'Godots',type:'bar',lat:"37.08602046860496",long:"-8.731470108032226"}, {address:'Rua 2nd Abril',detail:'Chinese Restaurant',title:'Royal Garden',type:'restaurant',lat:"37.086164896968405",long:"-8.731738328933715"}, {address:'Rua 2nd Abril',detail:'English Bar',title:'Clives',type:'bar',lat:"37.086125",long:"-8.731374"}, {address:'Rua 2nd Abril',detail:'English Restaurant',title:'The Lime Tree',type:'restaurant',lat:"37.086125877750365",long:"-8.731588125228881"}, {address:'Praia da Luz',detail:'Portuguese Restaurant',title:'Alloro',type:'restaurant',lat:"37.09158",long:"-8.724850"}, {address:'Rua Calheta',detail:'English Cafe / Bistro',title:'Jakes',type:'cafe',lat:"37.0862601125538",long:"-8.732671737670898"}, {address:'Av dos Pescadores',detail:'English & Portuguese Restaurant',title:'Chaplins',type:'restaurant',lat:"37.08550480361006",long:"-8.730005621910095"}, {address:'Av dos Pescadores',detail:'English & Portuguese Restaurant',title:'Atlantico',type:'restaurant',lat:"37.085425634814705",long:"-8.729941248893737"}, {address:'Av dos Pescadores',detail:'Indian Restaurant',title:'Saffron',type:'restaurant',lat:"37.08534432623613",long:"-8.729884922504425"}, {address:'Av dos Pescadores',detail:'Indian Restaurant',title:'Pashmina',type:'restaurant',lat:"37.08526729697597",long:"-8.729839324951171"}, {address:'Rua Calheta',detail:'English Bar',title:'The Bull',type:'bar',lat:"37.085652442494",long:"-8.73089075088501"}, {address:'Av dos Pescadores',detail:'English & Portuguese Restaurant',title:'Galley',type:'restaurant',lat:"37.08571577732778",long:"-8.729227781295776"}, {address:'Av dos Pescadores',detail:'English & Portuguese Bar',title:'Carlos',type:'bar',lat:"37.0856306176238",long:"-8.729227781295776"} ]; // translate data.type: to icon function getIcon(type) { switch(type) { case "bar": return "../mapIcons/mini-blue.png"; case "restaurant": return "../mapIcons/mini-red.png"; case "cafe": return "../mapIcons/mini-green.png"; default: return "../mapIcons/mini-white.png"; // used as current selection indicator //default: return "../mapIcons/marker-yellow-dot.png"; // will use instead of white later } } function initialize() { var latlng = new google.maps.LatLng(37.08597981464561, -8.730670809745788); var myOptions = { zoom: 17, center: latlng, mapTypeId: google.maps.MapTypeId.ROADMAP }; map = new google.maps.Map(document.getElementById("map_canvas"),myOptions); //----------------------------------------------------------------------------------------- /* Start of for/each loop */ var $locs = $("#locs");//Used repeatedly inside the loop. $.each(data, function(idx, mapData) { //BB - Note: critical assignment of the new marker as a property of `mapData`. // section 1 - Marker construct mapData.marker = new google.maps.Marker({ map: map, position: new google.maps.LatLng(mapData.lat,mapData.long), title: mapData.title, icon: getIcon(mapData.type) }); // section 1 end // section 2 - Infowindow construct var link = '<a href="#"' + mapData.title +'">' + mapData.title + '</a>'; // make a link of name var contentHtml = "<div id='iw' class='iw2'><h3>" + link + "</h3>" + mapData.detail + "</div>"; // style info window and add detail // What was `marker` must now be referred to as `mapData.marker` mapData.marker.infowindow = new google.maps.InfoWindow({ content: contentHtml, }); // section 2 end // section 3 - Map marker click function google.maps.event.addListener(mapData.marker, 'click', function() { if(lastinfowindow && lastinfowindow.close) lastinfowindow.close(); // close any open infowindows map.setZoom(18); // zoom in map.setCenter(mapData.marker.getPosition());// centre on selection //BB - `this` refers back to the clicked element; the appropriate marker this.infowindow.open(map, this); // open infowindow lastinfowindow = this.infowindow; // remember for closing this infowindow, if still open when selection changes }); // section 3 end // section 4 - Display Map marker and sidebar item // BB - Here, it's convenient to create what was `sideitem` as a jQuery object, so we can apply several jquery methods (without making an assignment). var spot = '<img src="' + (getIcon(mapData.type)) + '" />'; // sidebar copy of marker for display $('<p class="loc" />') .html(spot + mapData.title) // sidebar icon and name .appendTo($locs) // add to sidebar container .data('mapData', mapData); //<<<<<<<< critical // BB Remove non matching from sidebar marker.loc = $('<p class="loc" />').addClass(mapData.type).html(spot + mapData.title).data('marker', {m:marker, type:mapData.type}).appendTo($locs).get(0); // BB - At the bottom of the $.each() loop in initialize(), create and populate one array per category, as properties of markers :// if(!markers[mapData.type]) markers[mapData.type] = []; markers[mapData.type].push(marker); }); // End of for/each loop //----------------------------------------------------------------------------------------- } // end of initialise (?) //----------------------------------------------------------------------------------------- /* Sidebar Functions */ $(document).on("mouseenter", ".loc", function() { //if(lastinfowindow && lastinfowindow.close) lastinfowindow.close(); // moved to on click, avoids closing when accidently moving mouse var mapData = $(this).data("mapData"); map.setZoom(18); // zoom in a bit map.setCenter(mapData.marker.getPosition());// centre on selection //map.panTo(mapData.marker.getPosition());// direct reference to the marker avoids the need to loop. mapData.marker.setIcon(getIcon(''));//get the default icon ie. larger yellow spot. }).on("mouseleave", ".loc", function() { var mapData = $(this).data("mapData"); mapData.marker.setIcon(getIcon(mapData.type));//reset marker to correct type map.setZoom(17); //rest zoom to default map.setCenter(marker.getPosition()); // centre on map middle }).on("click", ".loc", function() { // opens corresponding info window on map if(lastinfowindow && lastinfowindow.close) lastinfowindow.close(); var mapData = $(this).data("mapData"); //map.setZoom(19); // zoom in more maybe mapData.marker.infowindow.open(map, mapData.marker); // open infowindow lastinfowindow = mapData.marker.infowindow; // remember for closing this infowindow, if still open when selection changes }) //----------------------------------------------------------------------------------------- /* Run on every change to any of the checkboxes */ function doFilter() { if(lastinfowindow && lastinfowindow.close) lastinfowindow.close(); // close last infowindow if still open alert ("filter triggered"); $("input[type=checkbox]").each(function(i, checkbox) { var markersArr = markers[checkbox.value]; if(markersArr) { $.each(markersArr, function(i, marker) { marker.loc.style.display = ['none', 'block'][Number(checkbox.checked)]; // don't display non selected types marker.setVisible(checkbox.checked); // display selected type(s) }); }; }); } //----------------------------------------------------------------------------------------- /* Run on initial setup */ doFilter(); //----------------------------------------------------------------------------------------- /* fires on every checkbox change */ $("#form").on("click", ".cat", doFilter) </script>
If, in the loop where the markers are created, you give each sidebar item a reference to its marker instead of the locid, then there's no need to loop to rediscover the marker on mouseenter/mouseleave.
ie, instead of setting :
//My best guess at what the statement must be. thisloc.data("locid", id); //Keep this line if thisloc.data("locid") is used elsewhere.
set (within the sidebar item/marker creation loop) :
var marker = ....; var thisloc = ...; ... data[i].marker = marker;//add a .marker property to the original dataset. thisloc.data("itemData", data[i]);//associate the original dataset with the sidebar item
Now the mouseenter/mouseleave handlers should simplify as follows:
$(document).on("mouseenter", ".loc", function() { if(lastinfowindow && lastinfowindow.close) lastinfowindow.close(); var data = $(this).data("itemData"); map.panTo(data.marker.getPosition());//<<<< direct reference to the marker avoids the need to loop. data.marker.setIcon(getIcon(''));//get the default icon. }).on("mouseleave", ".loc", function() { var data = $(this).data("itemData"); data.marker.setIcon(getIcon(data.type)); });
Note: You shouldn't need to pan to the marker again on mouseleave.
This should answer the question posed plus other advantages.
EDIT:
OK, now I've seen the main loop, it can be revised something like this, with various mods all through :
var $locs = $("#locs");//Used repeatedly inside the loop. $.each(data, function(idx, mapData) { //Note: critical assignment of the new marker as a property of `mapData`. mapData.marker = new google.maps.Marker({ map: map, position: new google.maps.LatLng(mapData.lat,mapData.long), title: mapData.title, icon: getIcon(mapData.type) }); var link = '<a href="#"' + mapData.title +'">' + mapData.title + '</a>'; var contentHtml = "<div id='iw' class='iw2'><h3>" + link + "</h3>" + mapData.detail + "<br>" + mapData.address + "</div>"; //What was `marker` must now be referred to as `mapData.marker` mapData.marker.infowindow = new google.maps.InfoWindow({ content: contentHtml }); google.maps.event.addListener(mapData.marker, 'click', function() { if(lastinfowindow && lastinfowindow.close) lastinfowindow.close(); //`this` refers back to the clicked element; the appropriate marker this.infowindow.open(map, this); lastinfowindow = this.infowindow; }); var spot = '<img src="' + (getIcon(mapData.type)) + '" />'; //Here, it's convenient to create what was `sideitem` as a jQuery object, so we can apply several jquery methods (without making an assignment). $('<p class="loc" />') .html(spot + mapData.title) .appendTo($locs) .data('mapData', mapData);//<<<<<<<< critical }); doFilter();//It should be possible to execute this statement when the loop is finished.
And the corresponding mouseenter/mouseleave handlers would be :
$(document).on("mouseenter", ".loc", function() { if(lastinfowindow && lastinfowindow.close) lastinfowindow.close(); var mapData = $(this).data("mapData"); map.panTo(mapData.marker.getPosition());//<<<< direct reference to the marker avoids the need to loop. mapData.marker.setIcon(getIcon(''));//get the default icon. }).on("mouseleave", ".loc", function() { var mapData = $(this).data("mapData"); mapData.marker.setIcon(getIcon(mapData.type)); });
All untested, so may well need debugging.
EDIT2 :
The way I left it above, the array markers wasn't being populated. Now I have seen the function doFilter() I can see that markers should be populated, however it is more convenient for it to be an object rather than an array.
markers = {};//in the same scope as before
At the bottom of the $.each() loop in initialize(), create and populate one array per category, as properties of markers :
if(!markers[mapData.type]) markers[mapData.type] = []; markers[mapData.type].push(mapData.marker);
With the markers populated in this way, you have a very simple means of identifying all markers in each category, and doFilter() will simplify enormously to :
function doFilter() { if(lastinfowindow && lastinfowindow.close) lastinfowindow.close(); $("input[type=checkbox]").each(function(i, checkbox) { var markersArr = markers[checkbox.value]; if(markersArr) { $.each(markersArr, function(i, marker) { marker.setVisible(checkbox.checked); }); } }); }
EDIT3
To get the sidebar entries to show/hide in sympathy with the category controls, initialize() should be as follows :
function initialize() { var latlng = new google.maps.LatLng(37.08597981464561, -8.730670809745788); var myOptions = { zoom: 18, center: latlng, mapTypeId: google.maps.MapTypeId.ROADMAP }; map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); var $locs = $("#locs");//Used repeatedly inside the loop. var marker; $.each(data, function(idx, mapData) { //Note: critical assignment of the new marker as a property of `mapData`. marker = new google.maps.Marker({ map: map, position: new google.maps.LatLng(mapData.lat, mapData.long), title: mapData.title, icon: getIcon(mapData.type) }); var link = '<a href="#"' + mapData.title +'">' + mapData.title + '</a>'; var contentHtml = "<div id='iw' class='iw2'><h3>" + link + "</h3>" + mapData.detail + "<br>" + mapData.address + "</div>"; marker.infowindow = new google.maps.InfoWindow({ content: contentHtml }); google.maps.event.addListener(marker, 'click', function() { closeLastInfoWindow(); //`this` refers back to the clicked element; the appropriate marker this.infowindow.open(map, this); lastinfowindow = this.infowindow; }); var spot = '<img src="' + (getIcon(mapData.type)) + '" />'; //Here, it's convenient to create what was `sideitem` as a jQuery object, so we can apply several jquery methods. marker.loc = $('<p class="loc" />') .addClass(mapData.type) .html(spot + mapData.title) .data('marker', {m:marker, type:mapData.type}) .appendTo($locs).get(0); if(!markers[mapData.type]) markers[mapData.type] = []; markers[mapData.type].push(marker); }); $(document).on("mouseenter", ".loc", function() { closeLastInfoWindow(); var m = $(this).data("marker").m; map.panTo(m.getPosition());//<<<< direct reference to the marker avoids the need to loop. m.setIcon(getIcon(''));//get the default icon. }).on("mouseleave", ".loc", function() { var data = $(this).data("marker"); data.m.setIcon(getIcon(data.type)); }).on("click",".loc",function() { var m = $(this).data("marker").m; m.infowindow.open(map, m); lastinfowindow = m.infowindow; }); $("#form").on("click", ".cat", doFilter); doFilter(); }
这篇关于Google地图将标记更改为原始图片的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!