0

Google マップ V3 マーカーのイベント リスナーとマップ外のサイドバー エントリの間に双方向バインディングを追加しようとしています。これを達成する例を探していますが、ベスト プラクティスを見つけるのに苦労しています。ESA 2009 は、Google Maps API V3 がリリースされた直後に、サイドバー エントリとマーカーの間にこのタイプの関連付けを確立することができました。おそらくjQuery.Callbacks()を使用して、これを達成するための現代的な方法はありますか? このESA 2009 の例は 3 年間公開されていますが、ESA 2009 の洗練された双方向バインディング機能をマーカーと対応する非マップ サイドバー エントリとの間で完全に複製することができたエミュレーション実装の成功例はほとんどありません (あったとしても)。このプラグインは素晴らしいスタートですが、マーカーが直接クリックされたときに選択されたサイドバー項目を強調表示または識別する機能が JQuery に欠けています。

ESA 2009 のアプローチでは、SidebarItem() および makeMarker() JS 関数の内部関数、クロージャ、およびプロトタイプを使用して、サイドバー エントリとマーカー間の双方向バインディングを確立します。マーカーがクリックされると、サイドバーのエントリが強調表示され (逆も同様)、明らかなメモリ リークや過剰な再帰は発生しません。ESA 2009 の手法は、概念的に把握または拡張するのが困難です。この動作は便利ですが、広く採用されていません。ユーザーがサイドバー アイテムをクリックすると、典型的な Google マップの動作があります。つまり、マップがパンして情報ウィンドウが開きます。これは標準ですが、ESA 2009 バージョンには、対応するマーカーのクリックを (フォーカスのある CSS を介して) リッスンして応答する非マップ サイドバー アイテムである余分な部分もあります。この双方向のリスナー効果は、JQuery を介して移植したり、最近のストア ロケーター ソリューションにネイティブに組み込むことは困難でした。必要な機能は次のとおりです。

ユーザーがマーカーまたはそのサイドバー エントリをクリックすると、既存のハイライトがクリアされ、選択された情報ウィンドウが開き、対応するサイドバー アイテムが同時に識別されます...逆も同様です。

この有用な効果を達成するためのベストプラクティスは何ですか? 双方向トリガーを統合した現在の例を知っている人はいますか? Google のサーバーからレンダリングされた特定のマーカーと、同じページ上にあるがマップの外側にある対応するイベント リスナー (サイドバー アイテムなど) との間のリンクをどのように達成するのが最適ですか。JQuery の最新 (1.7) のコールバック処理機能を使用する必要がありますか? JQuery 以外の優れた手法はありますか?

以下は、「map」という名前の Map() でマーカーと InfoWindow を作成し、「sidebar」という名前の DIV にサイドバー行を作成し、markerArray と markerBounds でマーカーを収集する、「最先端の」おなじみのスニペットです。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 マップ マーカーに関連付ける最もモダンな方法は何ですか?

前もって感謝します...

4

1 に答える 1

0

あなたが達成しようとしていることに魔法はないと思いますが、変数のスコープに注意する必要があります。最も簡単な方法は、マップ マーカーとサイドバー エントリを宣言し、それらのイベント ハンドラーを同じスコープ (たとえば、onload ハンドラー) で定義して、相互にアドレス指定できるようにすることです。私はあなたのコードを詳しく調べていないので、この点についてはすでに問題ないかもしれません。

A が B をトリガーし、B がすぐに A をトリガーするなどの可能性があります。その場合、コール スタックがいっぱいになるか、ブラウザーが停止する可能性があり.triggerHandler()ます。.trigger()


編集:

これは、Google マップ マーカーと対応する外部リンクのすべてに、相互に強調表示するためのマウスオーバー ハンドラーとマウスアウト ハンドラーが与えられているアプリケーションから取った、似たようなものです。アプリケーション全体は数千行の長さで、名前空間に編成されており、それぞれ大文字の名前 (例: 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 {
            //...
        }
    });
    //...
});

正直なところ、このコードが模範的であるとは言えません。おそらく、メモリの効率が向上する可能性がありますが、よく整理されており、完全に信頼できます。

于 2012-05-15T01:13:42.350 に答える