草庐IT

javascript - 从 Google map (V3) 外部打开特定标记的信息窗口

coder 2024-05-14 原文

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

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

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

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 is not a function 和我列表中的第一项显示为 undefined。你能帮忙吗?

//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(){
}

最佳答案

您走在正确的轨道上。您只需要为您的 Marker 对象创建一个单独的全局数组,并将所有创建的标记推送到该数组。当您将所有公司数据写出到 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 函数来绑定(bind) DOM (HTML) 单击事件以打开信息窗口并滚动到标记。请注意,因为您正在动态加载公司,所以在您开始将事件绑定(bind)到它之前,保存其名称和 ID 的 div(或其他一些标签)必须存在于 DOM 中 - 因此您需要执行的第一个功能是呈现公司的功能HTML(不是 map 初始化)。请注意我没有测试过这个,因为我没有你的数据..

//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> 

关于javascript - 从 Google map (V3) 外部打开特定标记的信息窗口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4904549/

有关javascript - 从 Google map (V3) 外部打开特定标记的信息窗口的更多相关文章

  1. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  2. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  3. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  4. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  5. ruby - 如何通过 Rubocop 指示打开 & :read as argument to File. - 2

    我有这个代码File.open(file_name,'r'){|file|file.read}但是Rubocop发出警告:Offenses:Style/SymbolProc:Pass&:readasargumenttoopeninsteadofablock.你是怎么做到的? 最佳答案 我刚刚创建了一个名为“t.txt”的文件,其中包含“Hello,World\n”。我们可以按如下方式阅读。File.open('t.txt','r',&:read)#=>"Hello,World\n"顺便说一下,由于第二个参数的默认值是'r',所以这样

  6. ruby - 从外部访问类的实例变量 - 2

    我理解(我认为)Ruby中类变量和类的实例变量之间的区别。我想知道如何从该类外部访问该类的实例变量。从内部(即在类方法中而不是实例方法中),它可以直接访问,但是从外部,有没有办法做MyClass.class.[@$#]variablename?我没有任何具体原因要这样做,只是学习Ruby并想知道是否可行。 最佳答案 classMyClass@my_class_instance_var="foo"class上述yield:>>foo我相信Arkku演示了如何从类外部访问类变量(@@),而不是类实例变量(@)。我从这篇文章中提取了上述内

  7. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

  8. ruby - 从 Rakefile 打开 Vim? - 2

    我正在为个人笔记创建一个日志应用程序,并且在我的Rakefile中包含以下内容:task:newdoentry_name="Entries/#{Time.now.to_s.gsub(/[-\:]+/,'.').gsub(/.0500+/,'')}.md"`touch#{entry_name}``echo"#$(date)">>#{entry_name}`end我想包括的最后一部分是Vim文本编辑器的打开,但我不知道如何打开它,就像我直接从bash终端调用它一样。我试过:vim#{entry_name}但不幸的是,我认为它们都将其作为后台进程打开。我一直在引用“6WaystoRunShe

  9. ruby - what is - gets is a directory - 错误信息 - 2

    我遇到了这个奇怪的错误.../Users/gideon/Documents/ca_ruby/rubytactoe/lib/player.rb:13:in`gets':Isadirectory-spec(Errno::EISDIR)player_spec.rb:require_relative'../spec_helper'#theuniverseisvastandinfinite...itcontainsagame....butnoplayersdescribe"tictactoegame"docontext"theplayerclass"doit"musthaveahumanplay

  10. ruby - 无法安装 gem - make 未被识别为内部或外部命令可运行程序或批处理文件 - 2

    我想在Windows7上安装带有ruby​​1.9.3的rspec-railsgem。我收到一些错误消息,提示无法安装某些json库。所以,我使用下面的说明来解决它。来源=The'json'nativegemrequiresinstalledbuildtools从[rubyinstaller.org][3]下载[Ruby1.9.3][2]从[rubyinstaller.org][3]下载DevKit文件对于Ruby1.9.3,使用[DevKit-tdm-32-4.5.2-20110712-1620-sfx.exe][4]将DevKit解压到路径C:\Ruby193\DevKit运行cd

随机推荐