2011-04-14 34 views
3

我試圖將Google Maps的InfoWindow與DOM節點一起使用,並保留InfoWindow交換之間的節點,而無需在DOM之外創建顯式內容存儲。不幸的是,當一個InfoWindow的內容被改變時,以前的內容似乎被破壞了,這是不幸的,因爲它無法切換回前一個節點。更糟糕的是,InfoWindow的content_changed事件似乎沒有參考先前的內容,因爲MVC事件沒有event參數。此外,如here所述,引用函數內的內容屬性只引用當前值,而不引用前一個值,因此似乎以前的值對於所有時態和目的都沒有了。使用Google InfoWindow和content_changed保留節點?

例如,假設您想要這樣做,假設我們已經有一張地圖,LatLng位於myLatLng,myLatLng2中。請注意,唯一對shortlived節點的引用已添加到dom中。


document.body.appendChild(document.createElement('div')).id = 'shortlived'; 
document.getElementById('shortlived').innerHTML = 'I will pass soon...'; 

var infowindow = new google.maps.InfoWindow(); 
var marker1 = new google.maps.Marker({ 
    position: myLatlng, 
    map: map, 
    title:"Marker1" 
}); 
var marker2 = new google.maps.Marker({ 
    position: myLatlng2, 
    map: map, 
    title:"Marker2" 
}); 

google.maps.event.addListener(marker1, 'click', function() { 
    infoWindow.setContent(document.getElementById('shortlived')); 
    infowindow.open(map, marker1); 
}); 
google.maps.event.addListener(marker2, 'click', function() { 
    infoWindow.setContent('Some Text'); 
    infowindow.open(map, marker2); 
}); 

你會發現,如果你點擊MARKER1看到短命的節點,然後如果你點擊MARKER2它消失,但是當您再次單擊標誌1,你不會得到短暫的,你可能會得到'有些文字',或者你什麼也得不到,但無論如何,短暫的消失了。在我的情況,我想最好做到以下幾點:


google.maps.event.addListener(infoWindow, 'content_changed' function(e){ 
    //where e.content is the previous content 
    document.body.appendChild(e.content) 
} 


google.maps.event.addListener(infoWindow, 'content_changed' function(e){ 
    //No such thing exists 
    document.body.appendChild(infoWindow.previousContent) 
} 

這似乎並不像它可以開箱即用,任何想法?再次,我想避免創建一個獨立的商店來保持對DOM節點的單獨引用,而不是DOM中已有的引用。我希望有一些我錯過了。

在此先感謝。

回答

2

我不是100%肯定它符合你的使用情況,但有關安裝DOM參考標記本身怎麼樣?如果每個標記只有一個DOM節點,這應該很好,這意味着你可以簡化你的點擊處理程序代碼(對於兩個標記來說不是很大的收益,但對於20來說非常方便)。這適用於我:

document.body.appendChild(document.createElement('div')).id = 'longlived'; 
document.getElementById('longlived').innerHTML = 'I will stick around!'; 

var infowindow = new google.maps.InfoWindow(); 
var marker1 = new google.maps.Marker({ 
    position: myLatlng, 
    map: map, 
    title:"Marker1" 
}); 
// attach the DOM node to the marker instance 
// marker1.iwcontent = myNode also works, but this follows the API 
marker1.set('iwcontent', document.getElementById('longlived')); 

var marker2 = new google.maps.Marker({ 
    position: myLatlng2, 
    map: map, 
    title:"Marker2" 
}); 
// attach alternate content to this marker 
marker2.set('iwcontent', "Some Text"); 

// create a click handler that will work for both markers 
// a more robust option might check for the existence of iwcontent first 
var openContentWindow = function() { 
    var marker = this; 
    // set the content to whatever's attached to the marker 
    infowindow.setContent(marker.get('iwcontent')); 
    infowindow.open(map, marker); 
} 

// attach your handler to your markers 
google.maps.event.addListener(marker1, 'click', openContentWindow); 
google.maps.event.addListener(marker2, 'click', openContentWindow); 

請注意,儘管DOM節點在標記點擊之間持續存在,但它已從實際頁面中刪除。我無法分辨這是否是您想要的,但如果您希望在信息窗口更改後讓DOM節點可用,則看起來您可以通過信息窗口上的anchor屬性訪問標記:

google.maps.event.addListener(infowindow, 'content_changed', function(){ 
    // I don't see this in the documented API, but it seems to reference 
    // the *previous* anchor, the one you're interested in 
    var marker = this.anchor; 
    // there are better tests for whether a var is a DOM node 
    if (marker && marker.get('iwcontent').nodeType) { 
     // do something with the DOM node here 
    } 
}); 

如果你擔心使用未公開的API屬性,你可以使用與上述相同的技術,將信息窗口設置爲舊錨的引用,然後檢索它的內容發生變化時 - 但它似乎沒有必要。

+0

我知道有一些沒有記錄的屬性。我很高興我問了,而不是玩API或無數次檢查它。我不介意沒有記錄的屬性,我們將管理包裝,所以沒什麼大不了的。我會檢查出來,然後接受。謝謝! – asnyder 2011-04-23 00:49:06

+0

好的,你的解決方案工作。有趣的是,我不知道爲什麼我沒有考慮將對象存儲在標記中,當在API的範圍內工作時,人們會如何限制自己到那裏。我可以一直將這個對象存儲在任何構建的屬性中,我想我很害怕Google的API會意外地修改它。感謝您的建議。 – asnyder 2011-04-23 08:47:34

+0

嗯,這可能是對的,Google的代碼會做一些意想不到的事情(關閉源代碼爲:(),這就是爲什麼我提出get和set方法,因爲那裏有更多的API合約。很高興爲你效勞! – nrabinowitz 2011-04-23 14:01:41

0

你可以做到這一點,像這樣

createMessage(); 

var infowindow = new google.maps.InfoWindow(); 
var marker1 = new google.maps.Marker({ 
    position: new google.maps.LatLng(18.464008, -66.117776), 
    map: map, 
    title:"Marker1" 
}); 
var marker2 = new google.maps.Marker({ 
    position: new google.maps.LatLng(18.470338, -66.123503), 
    map: map, 
    title:"Marker2" 
}); 

google.maps.event.addListener(marker1, 'click', function() { 
    infowindow.setContent(document.getElementById('shortlived')); 
    infowindow.open(map, marker1); 
    createMessage(); 
}); 
google.maps.event.addListener(marker2, 'click', function() { 
    infowindow.setContent('Some Text'); 
    infowindow.open(map, marker2); 
}); 

function createMessage(){ 
    document.body.appendChild(document.createElement('div')).id = 'shortlived'; 
    document.getElementById('shortlived').innerHTML = 'I will pass soon...'; 
} 
+0

不幸的是,這實際上並沒有解決問題,它只是通過不斷重新創建節點來掩蓋它,與.setContent('Some Text')的情況不同,我需要對象節點持續存在,以便任何它是屬性,因爲它可能已經在某些地方仍然有效。感謝您的嘗試。 – asnyder 2011-04-16 19:08:43