使用Google Maps API从表格中获取地址并在地图上显示标记,但标记的悬停标题或infoWindow(onclick)无效

mdxe

该脚本可以用作独立的javascript或油脂猴子脚本。我要解决的是悬停标题和单击信息窗口(应该显示地址)。这是一个jsFiddle

// ==UserScript==
// @name        mapMarkers
// @namespace   mapMarkers
// @include     https://www.example.com/*
// @description map markers of addresses in table
// @version     1
// @grant       none
// ==/UserScript==
// find the table and loop through each rows to get the 11th, 12th, 13th cell's content (street address, city and zip respectively
// convert to lat/lon and show markers on map


if (document.getElementById('main_report') !== null) {

    API_js_callback = 'https://maps.googleapis.com/maps/api/js?v=3.exp&callback=initialize';
    var script = document.createElement('script');
    script.src = API_js_callback;
    var head = document.getElementsByTagName("head")[0];
    (head || document.body).appendChild(script);

    var Table_1 = document.getElementById('main_report');


    var DIVmap = document.createElement('div');
        DIVmap.id = 'DIVmap';
        DIVmap.style.border = '2px coral solid';
        DIVmap.style.cursor = 'pointer';
        DIVmap.style.display = '';
        DIVmap.style.height = '35%';
        DIVmap.style.margin = '1';
        DIVmap.style.position = 'fixed';
        DIVmap.style.padding = '1';
        DIVmap.style.right = '1%';
        DIVmap.style.bottom = '1%';
        DIVmap.style.width = '35%';
        DIVmap.style.zIndex = '99';

    var DIVinternal = document.createElement('div');
        DIVinternal.id = 'DIVinternal';
        DIVinternal.style.height = '100%';
        DIVinternal.style.width = '100%';
        DIVinternal.style.zIndex = '999';

        document.body.appendChild(DIVmap);
        DIVmap.appendChild(DIVinternal);

    //Adds a button which allows the user to re-run calcRoute
    var reloadMapButton = document.createElement("button");
    reloadMapButton.setAttribute("type", "button");
    reloadMapButton.setAttribute("href", "#");
    reloadMapButton.textContent="Reload map";
    reloadMapButton.id="calcRoute";
    reloadMapButton.style.zIndex = '1000';
    document.getElementById('Content_Title').appendChild(reloadMapButton);

    window.initialize = setTimeout(function () {
        var myWindow;
        try{
            myWindow = unsafeWindow;
        }catch(e){
            myWindow = window;
        }
        google = myWindow.google;
        directionsService = new google.maps.DirectionsService();
        directionsDisplay = new google.maps.DirectionsRenderer();

        var myLoc = new google.maps.LatLng(28.882193,-81.317936);
        var myOptions = {
            zoom: 13,
            mapTypeId: google.maps.MapTypeId.ROADMAP,
            center: myLoc
        }

        map = new google.maps.Map(document.getElementById("DIVinternal"), myOptions);
        var infoWindow1 = new google.maps.InfoWindow();
        //var bounds = new google.maps.LatLngBounds();
        var geocoder = new google.maps.Geocoder();

        function codeAddress(address,i) {
            setTimeout( function () {  // timer to avoid google geocode limits
                geocoder.geocode( { 'address': address}, function(results, status) {
                if (status == google.maps.GeocoderStatus.OK) {
                    //map.setCenter(results[0].geometry.location);
                    var marker = new google.maps.Marker({
                        map: map,
                        position: results[0].geometry.location
                    });
                } else {
                    alert("Geocode was not successful for the following reason: " + status);
                }
                });
            }, i * 350);
        }

        function calcRoute() {
            if (Table_1.rows.length > 1) { // table has 1 empty row if no search results are returned and first row is always empty
                var newPoint;
                for (var i = 1, row; row = Table_1.rows[i]; i++) {
                    newPoint = codeAddress(row.cells[10].title +  ', ' + row.cells[11].innerHTML + ', ' + row.cells[12].innerHTML, i);
                // bounds.extend(newPoint);
                    marker = new google.maps.Marker({
                        position: newPoint,
                        map: map,
                        title: row.cells[10].title +  ', ' + row.cells[11].innerHTML + ', ' + row.cells[12].innerHTML
                    });
                google.maps.event.addListener(marker, 'click', function () {
                    infoWindow1.setContent(row.cells[10].title +  ', ' + row.cells[11].innerHTML + ', ' + row.cells[12].innerHTML);
                    infoWindow1.open(map, this);
                });
                    // Automatically center the map fitting all markers on the screen
                // map.fitBounds(bounds);
                }
            }
        }
        //reloadMapButton.addEventListener('click', calcRoute);
        document.getElementById("calcRoute").onclick = calcRoute;
        calcRoute();
    }, 1000);
} // if (document.getElementById('main_report') !== null)

样本数据

伊恩

从Reddit帖子复制的答案:

如果您仔细地一步一步地思考代码,则可以看到为什么infowindow未将自身分配给标记的原因。calcRoute函数开始

  1. 如果表格多于一行
  2. 创建newPoint变量
  3. 对于表格中从第二行开始的每一行:
  4. 调用该codeAddress函数并将其分配给newPoint

让我切入这里。这是您开始困惑的地方。codeAddress没有return语句(即使这样做,它也是异步的,[AJAX]无关紧要),因此实际上并没有对它做任何事情newPoint整个标记都函数内部创建codeAddress,使该行下方的行无用-没有位置存储,newPoint因此没有创建标记,因此也没有infoWindow创建。

相反,您必须在创建infoWindow之后立即创建内部地址解析回调marker您也可以来指派infoWindow的,以marker使用Click事件。另外,如果您要悬停标题,只需将其添加为标记的属性即可title

最终代码在这里:http : //pastebin.com/3rpWEnrp

您会注意到我对其进行了一些清理,以使其更具可读性和清晰度:

  • 可以使用以下方式访问文档的头部document.head-无需通过标签名称进行获取
  • 有一个为两个变量分配相同值的简写: x = y = 3
  • 无需z-index在内部div上;外部div已经拥有它。(例如,将一块硬纸板放在东西上方,硬纸板上的任何东西也会被提起)
  • 不需要的unsafeWindow; 这实际上是不安全的
  • 一次定义多个变量的简写是 var x = 3, y = 4;
  • 您不需要该codeAddress函数,因为您只需调用一次,因此函数的全部内容都将放入该calcRoute函数中。
  • alert除非您确实希望用户知道,否则使用控制台代替,会减少干扰,在这种情况下,您需要一条更简单的消息
  • 如果if在这种情况下由于语句从第2行开始而无法触发,为什么还要检查表是否长于一行?

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章