Chỉ mở một InfoWindow trong API Google Maps v3


85

Tôi chỉ cần mở một InfoWindow trên Google Map của mình. Tôi cần đóng tất cả các InfoWindows khác trước khi mở một InfoWindows mới.

Ai đó có thể chỉ cho tôi cách làm điều này?


Bạn đã thử những gì?
IgniteCoders

Câu trả lời:


151

Bạn chỉ cần tạo một InfoWindowđối tượng, giữ một tham chiếu đến nó và sử dụng lại nếu cho tất cả các điểm đánh dấu. Trích dẫn từ Tài liệu API của Google Maps :

Nếu bạn chỉ muốn một cửa sổ thông tin hiển thị tại một thời điểm (cũng như hoạt động trên Google Maps), bạn chỉ cần tạo một cửa sổ thông tin, bạn có thể gán lại cho các vị trí hoặc điểm đánh dấu khác nhau theo các sự kiện trên bản đồ (chẳng hạn như nhấp chuột của người dùng).

Do đó, bạn có thể chỉ muốn tạo InfoWindowđối tượng ngay sau khi bạn khởi tạo bản đồ của mình và sau đó xử lý các clicktrình xử lý sự kiện của điểm đánh dấu của bạn như sau. Giả sử bạn có một điểm đánh dấu được gọi là someMarker:

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

Sau đó, InfoWindowsẽ tự động đóng khi bạn nhấp vào một điểm đánh dấu mới mà không cần phải gọi close()phương thức.


Tôi cũng làm điều này nhưng có bình thường là infoWindow mất +1 giây để mở trên điểm đánh dấu tiếp theo không? đôi khi nó không mở ở tất cả. Tôi sử dụng cùng một mã
MJB

Daniel, ý tưởng tuyệt vời !! trước đó tôi đã cố gắng đồng bộ hóa theo cách thủ công, nhưng nó hiển thị lỗi javascript lạ (như "c is null" trong main.js hoặc tương tự như (123 ngoài phạm vi 43)).
Victor

30

Tạo infowindow của bạn ngoài phạm vi để bạn có thể chia sẻ nó.

Đây là một ví dụ đơn giản:

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);
  });
}

Cảm ơn bạn. Sử dụng "cái này" đã giải quyết hầu hết các vấn đề của tôi. Tôi vẫn không hiểu cách sử dụng nội dung tùy chỉnh bên trong setContent. Ví dụ: trong vòng lặp đánh dấu của tôi, tôi tạo một biến contentHtml bằng cách sử dụng biến "i" và liên kết nó với một đối tượng cơ sở dữ liệu. Làm cách nào để chuyển biến contentHtml đó vào trình nghe?
Ryan

Trong trường hợp của tôi, cửa sổ chỉ mở khi tôi sử dụng "this" trong infowindow.open (bản đồ, cái này); Thay vì "marker". Thx để chia sẻ giải pháp của bạn.
ownking

Tôi cũng làm điều này nhưng có bình thường là infoWindow mất +1 giây để mở trên điểm đánh dấu tiếp theo không? đôi khi nó không mở ở tất cả. Tôi sử dụng cùng một mã
MJB

14

Tôi đã gặp vấn đề tương tự nhưng câu trả lời tốt nhất không giải quyết được nó hoàn toàn, những gì tôi phải làm trong câu lệnh for của mình là sử dụng điều này liên quan đến điểm đánh dấu hiện tại của tôi. Có lẽ điều này sẽ giúp ai đó.

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
Cách bạn vượt qua chuỗi nội dung rất hữu ích cho tôi, thx.
ownking

4

muộn một chút, nhưng tôi đã quản lý để chỉ có một infowindow mở bởi maken infowindow một biến toàn cục.

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

sau đó bên trong trình nghe

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

infowindow.open(map, this);

1
Làm việc tuyệt vời cho tôi :)
lumos

4

Khai báo một globar var selectedInfoWindow;và sử dụng nó để giữ cửa sổ thông tin đã mở:

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

Bạn cần theo dõi đối tượng InfoWindow trước đó của mình và gọi phương thức đóng trên đó khi bạn xử lý sự kiện nhấp chuột trên một điểm đánh dấu mới .

NB Không nhất thiết phải gọi đóng trên đối tượng cửa sổ thông tin chia sẻ, gọi mở bằng một điểm đánh dấu khác sẽ tự động đóng đối tượng gốc. Xem câu trả lời của Daniel để biết chi tiết.


Tôi biết đây là một câu trả lời cũ và API v3 lúc đó không rõ ràng ... Nhưng thực ra không cần gọi close()phương thức, nếu một InfoWindowđối tượng được sử dụng. Nó sẽ tự động đóng nếu open()phương thức được gọi lại trên cùng một đối tượng.
Daniel Vassallo

@ daniel-vassallo Cảm ơn bạn đã lưu ý :) Tôi đã ủng hộ câu trả lời của bạn cho phù hợp, đó là câu trả lời hữu ích nhất mà tôi nghĩ.
RedBlueThing

0

Về cơ bản bạn muốn một hàm giữ tham chiếu đến một new InfoBox()=> ủy quyền sự kiện onclick. Trong khi tạo điểm đánh dấu của bạn (trong một vòng lặp), hãy sử dụngbindInfoBox(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được gán không đồng bộ và được lưu trong bộ nhớ. Mỗi khi bạn gọi bindInfoBox()hàm trả về sẽ được gọi thay thế. Cũng tiện dụng để vượt qua infoBoxOptionsmột lần duy nhất!

Trong ví dụ của tôi, tôi đã phải thêm một tham số bổ sung vào mapvì quá trình khởi tạo của tôi bị trì hoãn bởi các sự kiện tab.

InfoBoxOptions


0

Đây là một giải pháp không cần chỉ tạo một infoWindow để sử dụng lại nó. Bạn có thể tiếp tục tạo nhiều infoWindows, điều duy nhất bạn cần là xây dựng một hàm closeAllInfoWindows và gọi nó trước khi mở một infowindow mới. Vì vậy, giữ mã của bạn, bạn chỉ cần:

  1. Tạo một mảng toàn cầu để lưu trữ tất cả các thông tin

    var infoWindows = [];
    
  2. Lưu trữ từng thông tin mớiWindow trong mảng, chỉ sau infoWindow = new ...

    infoWindows.push(infoWindow);
    
  3. Tạo hàm closeAllInfoWindows

    function closeAllInfoWindows() {
        for (var i=0;i<infoWindows.length;i++) {
            infoWindows[i].close();
        }
    }
    
  4. Trong mã của bạn, hãy gọi tới closeAllInfoWindows () ngay trước khi mở infoWindow.

Trân trọng,


-1

Đã giải quyết nó theo cách này:

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);

-4

Google Maps cho phép bạn chỉ mở một cửa sổ thông tin. Vì vậy, nếu bạn mở một cửa sổ mới, thì cửa sổ kia sẽ tự động đóng lại.


2
Điều đó không đúng, tôi có thể mở tối đa 20 infowindows trên bản đồ của mình. nó là v3 btw.
leo

Được rồi, cảm ơn bạn đã sửa. Tôi không biết điều đó đã thay đổi trong phiên bản 3.
Kimmo Puputti
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.