从 Google 地图 (V3) 外部打开特定标记的信息窗口

发布于 2024-10-16 03:10:21 字数 4598 浏览 1 评论 0原文

我似乎无法解决这个问题:

我有一张带有(很多)标记(公司)的地图,这些标记(公司)来自生成的 XML 文件。在地图下方,我想显示地图上显示的所有公司的(非 JavaScript 生成的)列表。当我单击列表中的一家公司时,地图将平移到该特定标记并打开一个信息窗口。问题是我希望地图和列表是两个独立的东西......

解决这个问题的正确方法是什么?谢谢!重要的是,所有标记信息都是动态的...

function initialize_member_map(lang) {
  var map = new google.maps.Map(document.getElementById("large-map-canvas"), {
    center: new google.maps.LatLng(50.85034, 4.35171),
    zoom: 13,
    mapTypeId: 'roadmap'
  });
  var infoWindow = new google.maps.InfoWindow;

  downloadUrl("/ajax/member-xml-output.php", function(data) {
  var xml = data.responseXML;
  var markers = xml.documentElement.getElementsByTagName("marker");
  var bounds = new google.maps.LatLngBounds();
  for (var i = 0; i < markers.length; i++) {
    var company = markers[i].getAttribute("company");
    var address = markers[i].getAttribute("address");
    var type = markers[i].getAttribute("type");
    var uid = markers[i].getAttribute("uid"); // Primary key of company table in MySQL
    var point = new google.maps.LatLng(
        parseFloat(markers[i].getAttribute("lat")),
        parseFloat(markers[i].getAttribute("lng")));
    var html = "<b>" + company + "</b> <br/>" + address;
    bounds.extend(point);    
    var marker = new google.maps.Marker({
      map: map,
      position: point,
      uid: uid // Some experiments, wanted to use this to target specific markers...
    });
    bindInfoWindow(marker, map, infoWindow, html); 
  }        
  map.setCenter(bounds.getCenter());
  map.fitBounds(bounds); 
});
}

function bindInfoWindow(marker, map, infoWindow, html) {
  google.maps.event.addListener(marker, 'click', function() {
    infoWindow.setContent(html);
    infoWindow.open(map, marker);
  });
}

function downloadUrl(url, callback) {
  var request = window.ActiveXObject ?
    new ActiveXObject('Microsoft.XMLHTTP') :
    new XMLHttpRequest;

  request.onreadystatechange = function() {
    if (request.readyState == 4) {
      request.onreadystatechange = doNothing;
      callback(request, request.status);
    } 
  };

  request.open('GET', url, true);
  request.send(null);
}
function doNothing() {}

按照 Michal 的建议,我尝试了以下操作,但遇到了两个问题:我的控制台告诉我 markers[index].getPosition 不是函数我的列表中的第一项显示为未定义。你能帮忙吗?

//JavaScript Document
var map;
var markers = new Array();
var company_list;
function initialize_member_map(lang) {
  map = new google.maps.Map(document.getElementById("large-map-canvas"), {
    center: new google.maps.LatLng(50.85034, 4.35171),
    zoom: 13,
    mapTypeId: 'roadmap'
  });
  var infoWindow = new google.maps.InfoWindow;

  // Change this depending on the name of your PHP file
  downloadUrl("/ajax/member-xml-output.php?country=BE", function(data) {
    var xml = data.responseXML;
    markers = xml.documentElement.getElementsByTagName("marker");
    var bounds = new google.maps.LatLngBounds();
    for (var i = 0; i < markers.length; i++) {
      var company = markers[i].getAttribute("company");
      var address = markers[i].getAttribute("address");
      var type = markers[i].getAttribute("type");
      var uid = markers[i].getAttribute("uid");
      var point = new google.maps.LatLng(
          parseFloat(markers[i].getAttribute("lat")),
          parseFloat(markers[i].getAttribute("lng")));
      var html = "<b>" + company + "</b> <br/>" + address;
      bounds.extend(point); 
      var marker = new google.maps.Marker({
        map: map,
        position: point,
        uid: uid
      });
      bindInfoWindow(marker, map, infoWindow, html); 
      company_list += "<div onclick=scrollToMarker(" + i + ")>"+company+"</div>";
    }       
    map.setCenter(bounds.getCenter());
    map.fitBounds(bounds); 
    //display company data in html
    document.getElementById("company_list").innerHTML = company_list;
  });

}

function scrollToMarker(index) {
    map.panTo(markers[index].getPosition());
}

function bindInfoWindow(marker, map, infoWindow, html) {
  google.maps.event.addListener(marker, 'click', function() {
    infoWindow.setContent(html);
    infoWindow.open(map, marker);
  });
}

function downloadUrl(url, callback) {
  var request = window.ActiveXObject ?
      new ActiveXObject('Microsoft.XMLHTTP') :
      new XMLHttpRequest;

  request.onreadystatechange = function() {
    if (request.readyState == 4) {
      request.onreadystatechange = doNothing;
      callback(request, request.status);
    }
  };

  request.open('GET', url, true);
  request.send(null);
}
function doNothing(){
}

I can't seem to get my head around this problem:

I've got a map with (a lot of) markers (companies) that come from a generated XML file. Below the map, I want to show a (non-JavaScript-generated) list of all the companies that are displayed on the map. When I would click a company in the list, the map would pan to that specific marker and open an infoWindow. The thing is that I want the map and the list to be two separate things...

What would be the right way to tackle this problem? Thanks! Important is that all markerinfo is dynamic...

function initialize_member_map(lang) {
  var map = new google.maps.Map(document.getElementById("large-map-canvas"), {
    center: new google.maps.LatLng(50.85034, 4.35171),
    zoom: 13,
    mapTypeId: 'roadmap'
  });
  var infoWindow = new google.maps.InfoWindow;

  downloadUrl("/ajax/member-xml-output.php", function(data) {
  var xml = data.responseXML;
  var markers = xml.documentElement.getElementsByTagName("marker");
  var bounds = new google.maps.LatLngBounds();
  for (var i = 0; i < markers.length; i++) {
    var company = markers[i].getAttribute("company");
    var address = markers[i].getAttribute("address");
    var type = markers[i].getAttribute("type");
    var uid = markers[i].getAttribute("uid"); // Primary key of company table in MySQL
    var point = new google.maps.LatLng(
        parseFloat(markers[i].getAttribute("lat")),
        parseFloat(markers[i].getAttribute("lng")));
    var html = "<b>" + company + "</b> <br/>" + address;
    bounds.extend(point);    
    var marker = new google.maps.Marker({
      map: map,
      position: point,
      uid: uid // Some experiments, wanted to use this to target specific markers...
    });
    bindInfoWindow(marker, map, infoWindow, html); 
  }        
  map.setCenter(bounds.getCenter());
  map.fitBounds(bounds); 
});
}

function bindInfoWindow(marker, map, infoWindow, html) {
  google.maps.event.addListener(marker, 'click', function() {
    infoWindow.setContent(html);
    infoWindow.open(map, marker);
  });
}

function downloadUrl(url, callback) {
  var request = window.ActiveXObject ?
    new ActiveXObject('Microsoft.XMLHTTP') :
    new XMLHttpRequest;

  request.onreadystatechange = function() {
    if (request.readyState == 4) {
      request.onreadystatechange = doNothing;
      callback(request, request.status);
    } 
  };

  request.open('GET', url, true);
  request.send(null);
}
function doNothing() {}

Following the suggestions by Michal, I've tried the following, but am encountering two problems: my console tells me markers[index].getPosition is not a function and the first item in my list shows to be undefined. Can you please help?

//JavaScript Document
var map;
var markers = new Array();
var company_list;
function initialize_member_map(lang) {
  map = new google.maps.Map(document.getElementById("large-map-canvas"), {
    center: new google.maps.LatLng(50.85034, 4.35171),
    zoom: 13,
    mapTypeId: 'roadmap'
  });
  var infoWindow = new google.maps.InfoWindow;

  // Change this depending on the name of your PHP file
  downloadUrl("/ajax/member-xml-output.php?country=BE", function(data) {
    var xml = data.responseXML;
    markers = xml.documentElement.getElementsByTagName("marker");
    var bounds = new google.maps.LatLngBounds();
    for (var i = 0; i < markers.length; i++) {
      var company = markers[i].getAttribute("company");
      var address = markers[i].getAttribute("address");
      var type = markers[i].getAttribute("type");
      var uid = markers[i].getAttribute("uid");
      var point = new google.maps.LatLng(
          parseFloat(markers[i].getAttribute("lat")),
          parseFloat(markers[i].getAttribute("lng")));
      var html = "<b>" + company + "</b> <br/>" + address;
      bounds.extend(point); 
      var marker = new google.maps.Marker({
        map: map,
        position: point,
        uid: uid
      });
      bindInfoWindow(marker, map, infoWindow, html); 
      company_list += "<div onclick=scrollToMarker(" + i + ")>"+company+"</div>";
    }       
    map.setCenter(bounds.getCenter());
    map.fitBounds(bounds); 
    //display company data in html
    document.getElementById("company_list").innerHTML = company_list;
  });

}

function scrollToMarker(index) {
    map.panTo(markers[index].getPosition());
}

function bindInfoWindow(marker, map, infoWindow, html) {
  google.maps.event.addListener(marker, 'click', function() {
    infoWindow.setContent(html);
    infoWindow.open(map, marker);
  });
}

function downloadUrl(url, callback) {
  var request = window.ActiveXObject ?
      new ActiveXObject('Microsoft.XMLHTTP') :
      new XMLHttpRequest;

  request.onreadystatechange = function() {
    if (request.readyState == 4) {
      request.onreadystatechange = doNothing;
      callback(request, request.status);
    }
  };

  request.open('GET', url, true);
  request.send(null);
}
function doNothing(){
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

爱她像谁 2024-10-23 03:10:21

你走在正确的轨道上。您只需为标记对象创建一个单独的全局数组,并将所有创建的标记推送到该数组。当您将所有公司数据写入 html 时,请包含一个调用,其中包含单击时执行的标记的索引。下面是示例代码。我使用 JSON 作为数据结构来保存公司信息,而不是 XML。

<html> 
<head> 
    <meta name="viewport" content="initial-scale=1.0, user-scalable=yes" /> 
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"/> 
    <title>Google Maps Scroll to Marker</title> 

    <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script> 

</head> 
<body onload="initialize()"> 

    <div id="map_canvas" style="width: 900px;height: 600px;"></div> 
    <div id="companies"></div>
    <script type="text/javascript"> 
        var map;
        //JSON of company data - equivalent of your XML 
        companies = {
            "data": [
            {
                "name": "Company 1",
                "lat": 42.166,
                "lng": -87.848 
            }, 
            {
                "name": "Company 2",
                "lat": 41.8358,
                "lng": -87.7128 
            },
            {
                "name": "Company 3",
                "lat": 41.463, 

                "lng": -88.870 
            },
            {"name":"Company 4",
            "lat":41.809, "lng":-87.790}		
            ]
        }
        //we will use this to store google map Marker objects 
        var markers=new Array();
        function initialize() {
            var chicago = new google.maps.LatLng(41.875696,-87.624207);
            var myOptions = {
                zoom: 9,
                center: chicago,
                mapTypeId: google.maps.MapTypeId.ROADMAP
            }
            map = new google.maps.Map(document.getElementById("map_canvas"),
                myOptions);
            listCompanies();
        }		 

        function listCompanies() {
            html = ""
        //loop through all companies
        for (i=0;i<companies.data.length;i++) {
        //get the maker postion
        lat  = companies.data[i].lat
        lng =  companies.data[i].lng

        //add google maps marker
        marker = new google.maps.Marker({
            map:map,
            position: new google.maps.LatLng(lat,lng),
            title: companies.data[i].name
        })
        markers.push(marker);
        html += "<div onclick=scrollToMarker(" + i + ")>"+companies.data[i].name+"</div>";
        }
        //display company data in html
        document.getElementById("companies").innerHTML =html;
        }

        function scrollToMarker(index) {
            map.panTo(markers[index].getPosition());
        }
</script>

</body> 
</html> 

好的,我为您添加了另一个解决方案 - 使用您的代码。这个使用您的bindInfWindow 函数来绑定DOM (HTML) 单击事件以打开信息窗口并滚动到标记。请注意,因为您正在动态加载公司,所以在开始将事件绑定到它之前,保存其名称和 ID 的 div(或其他一些标签)必须存在于 DOM 中 - 因此您需要执行的第一个函数是呈现公司的函数HTML(不是地图初始化)。请注意,我没有测试过这个,因为我没有你的数据。

//you must write out company divs first

<body onload="showCompanies()">



<script>
//JavaScript Document
var map;
//this is your text data
var markers = new Array();


//you need to create your company list first as we will be binding dom events to it so it must exist before marekrs are initialized
function showCompanies() {
 downloadUrl("/ajax/member-xml-output.php?country=BE", function(data) {
    var xml = data.responseXML;
    markers = xml.documentElement.getElementsByTagName("marker");

    for (var i = 0; i < markers.length; i++) {
      var company = markers[i].getAttribute("company");

      markerId = "id_"+i;

      company_list += "<div id="+markerId+">"+company+"</div>";
    }       

    //display company data in html
    document.getElementById("company_list").innerHTML = company_list;

    //now you are ready to initialize map
    initialize_member_map("lang")
  });
}

function initialize_member_map(lang) {
  map = new google.maps.Map(document.getElementById("large-map-canvas"), {
    center: new google.maps.LatLng(50.85034, 4.35171),
    zoom: 13,
    mapTypeId: 'roadmap'
  });




    var xml = data.responseXML;

    var bounds = new google.maps.LatLngBounds();
    //your company data was read in and is ready to be mapped
    for (var i = 0; i < markers.length; i++) {
      var infoWindow = new google.maps.InfoWindow;
      var company = markers[i].getAttribute("company");
      var address = markers[i].getAttribute("address");
      var type = markers[i].getAttribute("type");
      var uid = markers[i].getAttribute("uid");
      var point = new google.maps.LatLng(
          parseFloat(markers[i].getAttribute("lat")),
          parseFloat(markers[i].getAttribute("lng")));
      var html = "<b>" + company + "</b> <br/>" + address;
      bounds.extend(point); 
      var marker = new google.maps.Marker({
        map: map,
        position: point,
        uid: uid
      });
      //add the new marker object to the gMarkers array

      markerId = "id_"+i;
      bindInfoWindow(marker, map, infoWindow, html,markerId); 

    }       
    map.setCenter(bounds.getCenter());
    map.fitBounds(bounds); 


}

function scrollToMarker(index) {
    map.panTo(markers[index].getPosition());
}

function bindInfoWindow(marker, map, infoWindow, html, markerId) {
  google.maps.event.addListener(marker, 'click', function() {
    infoWindow.setContent(html);
    infoWindow.open(map, marker);
  });
  //bind onlcick events to the div or other object in html
  markerObj =  document.getElementById(markerId);
  //you can create DOM event listeners for the map
  google.maps.event.addDomListener(markerObj, 'click', function() {
    infoWindow.setContent(html);
    infoWindow.open(map, marker);
    map.panTo(marker.getPosition());
  });

}

function downloadUrl(url, callback) {
  var request = window.ActiveXObject ?
      new ActiveXObject('Microsoft.XMLHTTP') :
      new XMLHttpRequest;

  request.onreadystatechange = function() {
    if (request.readyState == 4) {
      request.onreadystatechange = doNothing;
      callback(request, request.status);
    }
  };

  request.open('GET', url, true);
  request.send(null);
}
function doNothing(){
}

</script> 

You are on the right track. You just need to create a separate global array for your Marker objects and push all created markers to this array. When you write out all your company data to html include a call with the index of the marker executed on click. Below is an example code. I used JSON as my data structure to hold company info instead of XML.

<html> 
<head> 
    <meta name="viewport" content="initial-scale=1.0, user-scalable=yes" /> 
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"/> 
    <title>Google Maps Scroll to Marker</title> 

    <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script> 

</head> 
<body onload="initialize()"> 

    <div id="map_canvas" style="width: 900px;height: 600px;"></div> 
    <div id="companies"></div>
    <script type="text/javascript"> 
        var map;
        //JSON of company data - equivalent of your XML 
        companies = {
            "data": [
            {
                "name": "Company 1",
                "lat": 42.166,
                "lng": -87.848 
            }, 
            {
                "name": "Company 2",
                "lat": 41.8358,
                "lng": -87.7128 
            },
            {
                "name": "Company 3",
                "lat": 41.463, 

                "lng": -88.870 
            },
            {"name":"Company 4",
            "lat":41.809, "lng":-87.790}		
            ]
        }
        //we will use this to store google map Marker objects 
        var markers=new Array();
        function initialize() {
            var chicago = new google.maps.LatLng(41.875696,-87.624207);
            var myOptions = {
                zoom: 9,
                center: chicago,
                mapTypeId: google.maps.MapTypeId.ROADMAP
            }
            map = new google.maps.Map(document.getElementById("map_canvas"),
                myOptions);
            listCompanies();
        }		 

        function listCompanies() {
            html = ""
        //loop through all companies
        for (i=0;i<companies.data.length;i++) {
        //get the maker postion
        lat  = companies.data[i].lat
        lng =  companies.data[i].lng

        //add google maps marker
        marker = new google.maps.Marker({
            map:map,
            position: new google.maps.LatLng(lat,lng),
            title: companies.data[i].name
        })
        markers.push(marker);
        html += "<div onclick=scrollToMarker(" + i + ")>"+companies.data[i].name+"</div>";
        }
        //display company data in html
        document.getElementById("companies").innerHTML =html;
        }

        function scrollToMarker(index) {
            map.panTo(markers[index].getPosition());
        }
</script>

</body> 
</html> 

Ok I added another solution for you - uising your code. This one uses your bindInfWindow function to bind the DOM (HTML) click event to open info window and scroll to marker. Please note that because you are loading companies dynamically the divs (or some other tags) that hold their names and ids must exist in the DOM BEFORE you start binding events to it - so the first function you need to execute is the one that renders companies HTML (not the map init). Please note I have not tested this one as I do not have your data..

//you must write out company divs first

<body onload="showCompanies()">



<script>
//JavaScript Document
var map;
//this is your text data
var markers = new Array();


//you need to create your company list first as we will be binding dom events to it so it must exist before marekrs are initialized
function showCompanies() {
 downloadUrl("/ajax/member-xml-output.php?country=BE", function(data) {
    var xml = data.responseXML;
    markers = xml.documentElement.getElementsByTagName("marker");

    for (var i = 0; i < markers.length; i++) {
      var company = markers[i].getAttribute("company");

      markerId = "id_"+i;

      company_list += "<div id="+markerId+">"+company+"</div>";
    }       

    //display company data in html
    document.getElementById("company_list").innerHTML = company_list;

    //now you are ready to initialize map
    initialize_member_map("lang")
  });
}

function initialize_member_map(lang) {
  map = new google.maps.Map(document.getElementById("large-map-canvas"), {
    center: new google.maps.LatLng(50.85034, 4.35171),
    zoom: 13,
    mapTypeId: 'roadmap'
  });




    var xml = data.responseXML;

    var bounds = new google.maps.LatLngBounds();
    //your company data was read in and is ready to be mapped
    for (var i = 0; i < markers.length; i++) {
      var infoWindow = new google.maps.InfoWindow;
      var company = markers[i].getAttribute("company");
      var address = markers[i].getAttribute("address");
      var type = markers[i].getAttribute("type");
      var uid = markers[i].getAttribute("uid");
      var point = new google.maps.LatLng(
          parseFloat(markers[i].getAttribute("lat")),
          parseFloat(markers[i].getAttribute("lng")));
      var html = "<b>" + company + "</b> <br/>" + address;
      bounds.extend(point); 
      var marker = new google.maps.Marker({
        map: map,
        position: point,
        uid: uid
      });
      //add the new marker object to the gMarkers array

      markerId = "id_"+i;
      bindInfoWindow(marker, map, infoWindow, html,markerId); 

    }       
    map.setCenter(bounds.getCenter());
    map.fitBounds(bounds); 


}

function scrollToMarker(index) {
    map.panTo(markers[index].getPosition());
}

function bindInfoWindow(marker, map, infoWindow, html, markerId) {
  google.maps.event.addListener(marker, 'click', function() {
    infoWindow.setContent(html);
    infoWindow.open(map, marker);
  });
  //bind onlcick events to the div or other object in html
  markerObj =  document.getElementById(markerId);
  //you can create DOM event listeners for the map
  google.maps.event.addDomListener(markerObj, 'click', function() {
    infoWindow.setContent(html);
    infoWindow.open(map, marker);
    map.panTo(marker.getPosition());
  });

}

function downloadUrl(url, callback) {
  var request = window.ActiveXObject ?
      new ActiveXObject('Microsoft.XMLHTTP') :
      new XMLHttpRequest;

  request.onreadystatechange = function() {
    if (request.readyState == 4) {
      request.onreadystatechange = doNothing;
      callback(request, request.status);
    }
  };

  request.open('GET', url, true);
  request.send(null);
}
function doNothing(){
}

</script> 
爱你是孤单的心事 2024-10-23 03:10:21

由于我无法删除这个答案,所以我决定添加一些注释!

如果您的 xml 格式与此类似:http://www.w3schools.com/dom/books。 在package.xml

中,您可以使用以下行访问 author nodeValue。

markers = xml.documentElement.getElementsByTagName("book");

for (var i = 0; i < markers.length; i++) {
  authors = markers[i].getElementsByTagName('author')[0].innerHTML;
}

希望它对某人有帮助:)

since i cannot remove this answer, I decided to add some notes!

if your xml format is similar to this: http://www.w3schools.com/dom/books.xml

you may access author nodeValue with following lines.

markers = xml.documentElement.getElementsByTagName("book");

for (var i = 0; i < markers.length; i++) {
  authors = markers[i].getElementsByTagName('author')[0].innerHTML;
}

hope it helps someone :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文