2012-05-14 28 views
0

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

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

当用户点击标记或它的侧边栏条目,现有亮点被清除和所选择的信息窗口打开并且相应的侧边栏 项被并行识别...,反之亦然。

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

下面是在一个名为'map'的Map()上创建Marker和InfoWindow并在名为'sidebar'的DIV中创建一个侧栏行的“最先进的”熟悉的片段,其中markerArray和markerBounds收集标记。该SidebarItem()构造函数是由makeMarker()函数从欧洲航天局2009年的优秀例子叫做:

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标记关联的最佳现代方式?

在此先感谢...

回答

0

我不认为有任何的魔法在你想实现什么,但你需要知道的可变范围。最简单的方法是在相同的范围内(例如在一个onload处理程序中)声明地图标记和边栏条目,并定义它们的事件处理程序,以便它们可以相互处理。我没有详细通过你的代码,所以你在这方面可能已经OK了。

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


编辑:

这里是类似的东西,从其中谷歌地图标记和相应的外部链接都给出鼠标悬停及移出处理相互highliting申请采取。整个应用程序长达数千行,并组织到名称空间中,每个名称空间都带有大写的名称(例如,GOOGLEMAP,DATA)。

您会看到数据结构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 { 
      //... 
     } 
    }); 
    //... 
}); 

我不能诚实地说,这个代码是示例性的 - 它可能会更有效率的记忆 - 但它组织良好,而且十分可靠。

+0

谢谢。欣赏范围提示,但不认为这是困难。将检查.triggerHandler方法。您是否知道任何主要商店定位器上的双触发示例实现? – BogieCoder

+0

@BogieCoder,请参阅我的编辑,了解具有类似目标的代码示例。 –

+0

谢谢@甜菜根 - 甜菜根。将研究该解决方案,这是我正在寻找的策略类型。 – BogieCoder