เปิด InfoWindow เพียงรายการเดียวใน Google Maps API v3


85

ฉันต้องเปิด InfoWindow เพียงอันเดียวบน Google Map ฉันจำเป็นต้องปิด InfoWindows อื่น ๆ ทั้งหมดก่อนที่จะเปิดใหม่

ใครช่วยแสดงวิธีทำ


คุณพยายามทำอะไร?
IgniteCoders

คำตอบ:


152

คุณต้องสร้างInfoWindowออบเจ็กต์เพียงชิ้นเดียวเก็บข้อมูลอ้างอิงและใช้ซ้ำถ้าสำหรับเครื่องหมายทั้งหมด อ้างจากเอกสาร Google Maps API :

หากคุณต้องการให้หน้าต่างข้อมูลแสดงครั้งละหนึ่งหน้าต่างเท่านั้น (เช่นเดียวกับลักษณะการทำงานบน Google แผนที่) คุณต้องสร้างหน้าต่างข้อมูลเพียงหน้าต่างเดียวซึ่งคุณสามารถกำหนดใหม่ให้กับตำแหน่งหรือเครื่องหมายต่างๆตามเหตุการณ์บนแผนที่ได้ (เช่นการคลิกของผู้ใช้)

ดังนั้นคุณอาจต้องการสร้างInfoWindowวัตถุหลังจากที่คุณเริ่มต้นแผนที่ของคุณจากนั้นจัดการตัวจัดการclickเหตุการณ์ของเครื่องหมายของคุณดังนี้ สมมติว่าคุณมีเครื่องหมายที่เรียกว่าsomeMarker:

google.maps.event.addListener(someMarker, 'click', function() {
   infowindow.setContent('Hello World');
   infowindow.open(map, this);
});

จากนั้นInfoWindowควรปิดโดยอัตโนมัติเมื่อคุณคลิกที่เครื่องหมายใหม่โดยไม่ต้องเรียกใช้close()เมธอด


ฉันทำเช่นนี้เช่นกัน แต่เป็นเรื่องปกติหรือไม่ที่ infoWindow จะใช้เวลา +1 วินาทีในการเปิดเครื่องหมายถัดไป บางครั้งก็ไม่เปิดเลย ฉันใช้รหัสเดียวกัน
เป๊ะ

แดเนียลไอเดียสุดล้ำ !! ก่อนหน้านั้นฉันพยายามซิงโครไนซ์ด้วยตนเอง แต่มันแสดงข้อผิดพลาดของจาวาสคริปต์แปลก ๆ (เช่น "c is null" ใน main.js หรือบางอย่างเช่น (123 นอกช่วง 43))
วิกเตอร์

31

สร้างหน้าต่างข้อมูลของคุณนอกขอบเขตเพื่อให้คุณสามารถแบ่งปันได้

นี่คือตัวอย่างง่ายๆ:

var markers = [AnArrayOfMarkers];
var infowindow = new google.maps.InfoWindow();

for (var i = 0, marker; marker = markers[i]; i++) {
  google.maps.event.addListener(marker, 'click', function(e) {
    infowindow.setContent('Marker position: ' + this.getPosition());
    infowindow.open(map, this);
  });
}

ขอขอบคุณ. การใช้ "this" ช่วยแก้ปัญหาส่วนใหญ่ของฉันได้ ฉันยังไม่เข้าใจวิธีใช้เนื้อหาที่กำหนดเองภายใน setContent เช่นในลูปเครื่องหมายของฉันฉันสร้างตัวแปร contentHtml โดยใช้ตัวแปร "i" และเชื่อมโยงกับวัตถุฐานข้อมูล ฉันจะส่งผ่านตัวแปร contentHtml ไปยังผู้ฟังได้อย่างไร
Ryan

ในกรณีของฉันหน้าต่างจะเปิดขึ้นเมื่อฉันใช้ "this" ใน infowindow.open เท่านั้น (แผนที่นี้); แทน "เครื่องหมาย" ขอบคุณสำหรับการแบ่งปันโซลูชันของคุณ
เจ้าของ

ฉันทำเช่นนี้เช่นกัน แต่เป็นเรื่องปกติหรือไม่ที่ infoWindow จะใช้เวลา +1 วินาทีในการเปิดเครื่องหมายถัดไป บางครั้งก็ไม่เปิดเลย ฉันใช้รหัสเดียวกัน
เป๊ะ

14

ฉันมีปัญหาเดียวกัน แต่คำตอบที่ดีที่สุดไม่สามารถแก้ปัญหาได้อย่างสมบูรณ์สิ่งที่ฉันต้องทำในคำสั่ง for ของฉันคือการใช้สิ่งนี้ที่เกี่ยวข้องกับเครื่องหมายปัจจุบันของฉัน บางทีนี่อาจช่วยใครบางคนได้

for(var i = 0; i < markers.length; i++){
    name = markers[i].getAttribute("name");
    address = markers[i].getAttribute("address");        
    point = new google.maps.LatLng(parseFloat(markers[i].getAttribute("lat")), parseFloat(markers[i].getAttribute("lng")));                                     
    contentString = '<div style="font-family: Lucida Grande, Arial, sans-serif;>'+'<div><b>'+ name +'</b></div>'+'<div>'+ address +'</div>';                    
    marker = new google.maps.Marker({                       
        map: map,
        position: point,
        title: name+" "+address,
        buborek: contentString 
    });                                     
    google.maps.event.addListener(marker, 'click', function(){
        infowindow.setContent(this.buborek); 
        infowindow.open(map,this); 
    });                                                         
    marker.setMap(map);                 
}

2
วิธีการส่ง contentString ของคุณมีประโยชน์สำหรับฉันขอบคุณมาก
เจ้าของ

5

ช้าไปหน่อย แต่ฉันจัดการเพื่อให้มีเพียงหน้าต่างเดียวที่เปิดโดย maken infowindow ตัวแปรส่วนกลาง

var infowindow = new google.maps.InfoWindow({});

จากนั้นเข้าไปใน listner

infowindow.close();
infowindow = new google.maps.InfoWindow({   
    content: '<h1>'+arrondissement+'</h1>'+ gemeentesFiltered                           
});

infowindow.open(map, this);

1
ใช้งานได้ดีสำหรับฉัน :)
lumos

4

ประกาศ globar var selectedInfoWindow;และใช้เพื่อเปิดหน้าต่างข้อมูลที่เปิดไว้:

var infoWindow = new google.maps.InfoWindow({
    content: content
});

// Open the infowindow on marker click
google.maps.event.addListener(marker, "click", function() {
    //Check if there some info window selected and if is opened then close it
    if (selectedInfoWindow != null && selectedInfoWindow.getMap() != null) {
        selectedInfoWindow.close();
        //If the clicked window is the selected window, deselect it and return
        if (selectedInfoWindow == infoWindow) {
            selectedInfoWindow = null;
            return;
        }
    }
    //If arrive here, that mean you should open the new info window 
    //because is different from the selected
    selectedInfoWindow = infoWindow;
    selectedInfoWindow.open(map, marker);
});

0

คุณจำเป็นต้องติดตามของคุณก่อนหน้านี้InfoWindowวัตถุและเรียกใกล้วิธีในเมื่อคุณจัดการกับเหตุการณ์คลิกที่เครื่องหมายใหม่

หมายเหตุไม่จำเป็นต้องเรียกปิดบนวัตถุหน้าต่างข้อมูลที่แชร์การเรียกเปิดด้วยเครื่องหมายอื่นจะปิดต้นฉบับโดยอัตโนมัติ ดูคำตอบของ Danielสำหรับรายละเอียด


ฉันรู้ว่านี่เป็นคำตอบเก่าและ v3 API ก็ไม่ชัดเจนในเวลานั้น ... แต่จริงๆแล้วไม่จำเป็นต้องเรียกclose()เมธอดนี้หากใช้InfoWindowออบเจ็กต์เดียว มันจะปิดโดยอัตโนมัติหากมีopen()การเรียกใช้เมธอดอีกครั้งบนวัตถุเดียวกัน
Daniel Vassallo

@ daniel-vassallo ขอบคุณสำหรับบันทึก :) ฉันได้เพิ่มคะแนนคำตอบของคุณแล้วมันเป็นประโยชน์ที่สุดที่ฉันคิดว่า
RedBlueThing

0

โดยทั่วไปคุณต้องการหนึ่งฟังก์ชันที่คอยอ้างอิงถึงหนึ่งnew InfoBox()=> มอบหมายเหตุการณ์ onclick ในขณะที่สร้างเครื่องหมายของคุณ (แบบวนซ้ำ) ให้ใช้bindInfoBox(xhr, map, marker);

// @param(project): xhr : data for infoBox template
// @param(map): object : google.maps.map
// @param(marker): object : google.maps.marker
bindInfoBox: (function () {
    var options = $.extend({}, cfg.infoBoxOptions, { pixelOffset: new google.maps.Size(-450, -30) }),
        infoBox = new window.InfoBox(options);

    return function (project, map, marker) {
        var tpl = renderTemplate(project, cfg.infoBoxTpl); // similar to Mustache, Handlebars

        google.maps.event.addListener(marker, 'click', function () {
            infoBox.setContent(tpl);
            infoBox.open(map, marker);
        });
    };
}())

var infoBoxถูกกำหนดแบบอะซิงโครนัสและเก็บไว้ในหน่วยความจำ ทุกครั้งที่คุณเรียกbindInfoBox()ใช้ฟังก์ชัน return จะถูกเรียกแทน ยังสะดวกที่จะผ่านinfoBoxOptionsเพียงครั้งเดียว!

ในตัวอย่างของฉันฉันต้องเพิ่มพารามิเตอร์พิเศษลงในmapเนื่องจากการเริ่มต้นของฉันล่าช้าเนื่องจากเหตุการณ์ในแท็บ

InfoBoxOptions


0

นี่คือโซลูชันที่ไม่จำเป็นต้องสร้าง infoWindow เพียงอันเดียวเพื่อนำมาใช้ซ้ำ คุณสามารถสร้าง infoWindows ต่อไปได้สิ่งเดียวที่คุณต้องการคือสร้างฟังก์ชัน closeAllInfoWindows และเรียกใช้ก่อนเปิดหน้าต่างข้อมูลใหม่ ดังนั้นการรักษารหัสของคุณคุณเพียงแค่ต้อง:

  1. สร้างอาร์เรย์ส่วนกลางเพื่อจัดเก็บข้อมูลทั้งหมดของ Windows

    var infoWindows = [];
    
  2. จัดเก็บ infoWindow ใหม่แต่ละรายการในอาร์เรย์หลังจาก infoWindow = new ...

    infoWindows.push(infoWindow);
    
  3. สร้างฟังก์ชัน closeAllInfoWindows

    function closeAllInfoWindows() {
        for (var i=0;i<infoWindows.length;i++) {
            infoWindows[i].close();
        }
    }
    
  4. ในรหัสของคุณโทรไปที่ closeAllInfoWindows () ก่อนเปิด infoWindow

ความนับถือ,


มันใช้งานได้ แต่ไม่ใช่วิธีแก้ปัญหาที่ดีนักเพราะคุณเพียงแค่เพิ่มหน้าต่างข้อมูลลงในอาร์เรย์ดังนั้นจึงมีความเป็นไปได้ที่จะมีอาร์เรย์ที่มีหน้าต่างข้อมูลเดียวกันเกิดขึ้นมากมาย
เก่ง

-1

แก้ไขด้วยวิธีนี้:

function window(content){
    google.maps.event.addListener(marker,'click', (function(){
        infowindow.close();
        infowindow = new google.maps.InfoWindow({
            content: content
        });
        infowindow.open(map, this);
    }))
}
window(contentHtml);

-5

Google Maps ช่วยให้คุณเปิดหน้าต่างข้อมูลได้เพียงหน้าต่างเดียว ดังนั้นหากคุณเปิดหน้าต่างใหม่หน้าต่างอื่นจะปิดโดยอัตโนมัติ


2
ไม่ถูกต้องฉันสามารถเปิด infowindows ได้มากถึง 20 หน้าต่างบนแผนที่ของฉัน มันคือ v3 btw
สิงห์

โอเคขอบคุณสำหรับการแก้ไข ฉันไม่รู้ว่ามันมีการเปลี่ยนแปลงในเวอร์ชัน 3
Kimmo Puputti
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.