将Google地图标记绑定到非地图边栏条目

时间:2012-05-14 22:19:24

标签: jquery google-maps binding google-maps-markers sidebar

我试图在Google Map V3标记和非地图边栏条目上添加事件侦听器之间的双向绑定。我寻求实现这一目标的示例,但我无法找到最佳实践。在Google Maps API V3发布后,ESA 2009能够在侧边栏输入和标记之间建立这种类型的关联。是否有一个现代的方法来实现这一点,可能与jQuery.Callbacks()?这个ESA 2009 Example已经使用了3年,但是很少(如果有的话)成功的仿真实现能够在标记和相应的非Map侧边栏条目之间干净地复制ESA 2009优雅的双向绑定功能。 This PlugIn是一个很好的开始,但是当直接单击标记时,JQuery无法突出显示或识别所选的侧边栏项。

ESA 2009方法使用SidebarItem()和makeMarker()JS函数中的内部函数,闭包和原型来建立侧边栏条目和标记之间的双向绑定。单击标记时,侧边栏条目会突出显示(反之亦然),而不会出现明显的内存泄漏或过多的递归。从概念上讲,ESA 2009技术难以掌握或扩展。这种行为很有用,但没有被广泛采用。当用户点击侧边栏项时,会出现典型的Google地图行为:地图平移和信息窗打开。这是标准的,但在ESA 2009版本中还有一个额外的部分,即非地图侧边栏项目,通过相应的标记点击来监听和响应(通过CSS聚焦)。这种双向监听器效果很难通过JQuery移植,或者仅仅是在任何最近的商店定位器解决方案中本地合并。所需的功能是:

  

当用户点击某个标记或其侧边栏条目时,将清除现有的高光,并打开所选的信息窗口和相应的侧边栏   项目是并行识别的......反之亦然。

实现这种有用效果的最佳做法是什么?有没有人知道整合双向触发器的当前例子?如何在Google服务器呈现的特定标记与同一页面上但在地图之外的相应事件监听器之间实现最佳链接(例如,侧边栏项目)。我们应该使用任何JQuery最新的(1.7)回调处理功能吗?是否有更好的非JQuery技术?

以下是“最先进”熟悉的片段,在名为“map”的Map()上创建Marker和InfoWindow,并使用markerArray和markerBounds在标记为“sidebar”的DIV中创建侧栏行。 SidebarItem()构造函数由ESA 2009的优秀示例中的makeMarker()函数调用:

 var infoWindow = new google.maps.InfoWindow();
 var markerBounds = new google.maps.LatLngBounds();
 var markerArray = [];

    function makeMarker(options){
    var pushPin = new google.maps.Marker({map:map});
    pushPin.setOptions(options);
    google.maps.event.addListener(pushPin, "click", function(){
      infoWindow.setOptions(options);
      infoWindow.open(map, pushPin);
      if(this.sidebarButton)this.sidebarButton.button.focus();
    });
    var idleIcon = pushPin.getIcon();
    if(options.sidebarItem){
      pushPin.sidebarButton = new SidebarItem(pushPin, options);
  pushPin.sidebarButton.addIn("sidebar");
}
markerBounds.extend(options.position);
markerArray.push(pushPin);
     return pushPin;
  }

google.maps.event.addListener(map, "click", function(){
  infoWindow.close();
});

function SidebarItem(marker, opts){
var tag = opts.sidebarItemType || "button";
var row = document.createElement(tag);
row.innerHTML = opts.sidebarItem;
row.className = opts.sidebarItemClassName || "sidebar_item";  
row.style.display = "block";
row.style.width = opts.sidebarItemWidth || "120px";
row.onclick = function(){
google.maps.event.trigger(marker, 'click');
}
row.onmouseover = function(){
google.maps.event.trigger(marker, 'mouseover');
}
row.onmouseout = function(){
google.maps.event.trigger(marker, 'mouseout');
}
this.button = row;
}
// adds a sidebar item to a 

SidebarItem.prototype.addIn = function(block){
if(block && block.nodeType == 1)this.div = block;
else
this.div = document.getElementById(block)
|| document.getElementById("sidebar")
|| document.getElementsByTagName("body")[0];
this.div.appendChild(this.button);
}
// deletes a sidebar item
SidebarItem.prototype.remove = function(){
if(!this.div) return false;
this.div.removeChild(this.button);
return true;
}

SidebarItem()和makeMarker()是公共领域的功能,但对于像我这样的新手来说,它们很难理解,采用和集成。任何建议或当前的例子将不胜感激。具体来说,ESA 2009的方法是否过时了?我没有发现最近使用这种策略。将非地图DOM元素与特定Google Map标记相关联的最佳现代方法是什么?

提前致谢...

1 个答案:

答案 0 :(得分:0)

我认为你想要达到的目标没有任何魔力,但你确实需要了解变量范围。最简单的方法是声明地图标记和侧边栏条目,并在同一范围内定义它们的事件处理程序(例如,在onload处理程序中),以便它们可以相互寻址。我没有详细介绍你的代码,所以你可能已经在这方面做得很好。

您可能还想尝试使用.triggerHandler()而不是.trigger(),否则A会触发B和B会立即触发A等等。如果是,那么调用堆栈可能填满或浏览器可能只是抓住。


编辑:

这是一个类似的东西,取自一个应用程序,其中谷歌地图标记和相应的外部链接都被赋予mouseover和mouseout处理程序以进行相互高位。整个应用程序长达数千行,并组织成命名空间,每个命名空间都有一个大写的名称(例如GOOGLEMAPDATA)。

您将看到数据结构DATA.locationData是标记和外部链接之间交互的关键。它允许处理程序连接到不同的名称空间(即不同的范围)到链接和标记。

命名空间“GOOGLEMAP”(简化):

var GOOGLEMAP = (function(){//NAMESPACE pattern
    //...
    var mouseoverLocMarker_closure = function(loc) {
        return function() {
            $(loc.link).addClass('hilight');
        };
    };
    var mouseoutLocMarker_closure = function(loc) {
        return function() {
            $(loc.link).removeClass('hilight');
        };
    };
    //...
    var init = function(...) {
        //...
        for(var name in DATA.locationData) {
            //...
            var loc = DATA.locationData[name];//lookup in a large hardcoded data structure in the DATA namespace
            loc.marker = new google.maps.Marker({ map:map, icon:'images/symbols/green.gif', zIndex:0 });//makes the marker available in other scopes
            //Here we attach functions returned by "_closure" functions, in order to correctly remember loc.
            google.maps.event.addListener( loc.marker, 'mouseover', mouseoverLocMarker_closure(loc) );
            google.maps.event.addListener( loc.marker, 'mouseout', mouseoutLocMarker_closure(loc) );
            //...
        }
    };
    //...
})();

jQuery“文档就绪”闭包(简化):

$(function(){
    $('#towns a.location').each(function(){
        //...
        var loc = DATA.locationData[name];//lookup in a large hardcoded data structure in the DATA namespace
        if(loc){
            //...
            $this.mouseover(function(){
                if(loc.marker) {
                    loc.icon = loc.marker.getIcon();
                    loc.marker.setIcon('images/symbols/red.gif');
                }
            });
            $this.mouseout(function(){
                if(loc.marker) {
                    loc.marker.setIcon(loc.icon);
                }
            });
            loc.link = this;//makes the link available to other scopes
        }
        else {
            //...
        }
    });
    //...
});

我不能诚实地说这段代码是典型的 - 它可能更有效的内存 - 但它组织良好且完全可靠。