javascript - 如何设置信息框的动态像素偏移?

标签 javascript google-maps google-maps-api-3

我有一张 map ,其中包含基本上两种类型的多个标记。一个是较大的宽标记,另一个是较小的方形标记。两种类型都需要有一个单击时出现的信息框。由于标记的形状和大小不同,我非常希望根据单击的标记将信息框窗口锚定在不同的位置。当然,我找到了信息框选项的 PixelOffset 属性,但我似乎无法根据循环经过的标记动态设置它。基本上,我循环遍历标记数据数组,构建标记(通过“new google.maps.marker()”),然后继续添加一个事件监听器,用于单击标记,该标记调用函数来打开信息框。

所以我的问题是,在查看下面的代码后,如何动态设置信息框的pixelOffset?
我在下面尝试过的方法显然不起作用!当我加载页面时,我转储到那里的警报实际上显示了正确的设置!

<script type="text/javascript">
var LocationData = [
    [29.966270,-95.682491, "bhi", "Company Houston", "", "", "", "", "", "", "1"],
    [34.936190, -88.655899, "motors", "ConocoPhilips", "testfield #1", "rig #1", "HT102313MTR", "Eagle Ford", "v", "m", "0"],
    [32.133333, -102.3167, "type1", "Halliburton", "Test Field #2", "H&P #48", "HT070313RSS", "Bakken", "h", "m", "1"],
    [47.4667, -100.9333, "type2", "BP", "Test Field #3", "Ensco #318", "CC111512GWD", "Marcellus", "s", "", "2"],
    [41.5700, -117.7839, "type3", "Drake Directional", "Test Field #4", "H&P #143", "PE010214MWD", "Utica", "j", "f", "3"],
    [40.4667, -76.9333, "type4", "Shell", "testfield #5", "Ensco #23", "HT121213GYRO", "Barnett", "h", "m", "4"],

];

jQuery(document).ready(function(){
    initMap();  
});

var side_bar_html = '';
var gmarkers = [];
var htmls = [];

var myLatLong = new google.maps.LatLng(29.966270, -95.682491);
var mapOptions = {
    panControl: true,
    zoomControl: true,
    scaleControl: true
};

boxText = document.createElement("div");

function iconSizeFunction(usedIcon) {
    switch(usedIcon)
    {
    case 'bhi':
        var iconSizew_or = '68';
        var iconSizeh_or = '72';
        var iconSizew = '34';
        var iconSizeh = '36';
        var iconOriginw = '17';
        var iconOriginh = '28';
        var infoboxOffsetw = '200';
        var infoboxOffseth = '10';
        return [iconSizew_or, iconSizeh_or, iconSizew, iconSizeh, iconOriginw, iconOriginh, infoboxOffsetw, infoboxOffseth];
        break;
    default:
        var iconSizew_or = '264';
        var iconSizeh_or = '70';
        var iconSizew = '132';
        var iconSizeh = '35';
        var iconOriginw = '17';
        var iconOriginh = '-5';
        var infoboxOffsetw = '150';
        var infoboxOffseth = '200';
        return [iconSizew_or, iconSizeh_or, iconSizew, iconSizeh, iconOriginw, iconOriginh, infoboxOffsetw, infoboxOffseth];
        break;
    }
}

function initMap()
{
    var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
    var bounds = new google.maps.LatLngBounds();
    var infowindow = new google.maps.InfoWindow();
    var iconUsed;

    for (var i in LocationData)
    {
        var p = LocationData[i];
        var latlng = new google.maps.LatLng(p[0], p[1]);
        var iconUsed = p[2];
        var iconSizes = iconSizeFunction(p[2]);
        var infoBoxPosition = new google.maps.Size(iconSizes[6], iconSizes[7]);

        var jobStatus = p[10];

        switch(jobStatus)
        {
        case '0':
            jobStatus = 'off';
            break;
        case '1':
            jobStatus = 'on';
            break;
        case '2':
            jobStatus = 'up';
            break;
        case '3':
            jobStatus = 'unknown';
            break;
        case '4':
            jobStatus = 'new';
            break;
        }

        bounds.extend(latlng);

        var marker = new google.maps.Marker({
            position: latlng,
            map: map,
            icon: {
                url: '/images/mapicons/' + iconUsed + '_' + jobStatus + '.png',
                size: new google.maps.Size(iconSizes[0], iconSizes[1]),
                origin: new google.maps.Point(0,0),
                anchor: new google.maps.Point(iconSizes[4], iconSizes[5]),
                scaledSize: new google.maps.Size(iconSizes[2], iconSizes[3])
            },
            shape: {
                coord: [0, 0, iconSizes[2], iconSizes[3]],
                type: 'rect'
            },
            optimized: false,
            animation: google.maps.Animation.DROP,
            content: '<div class="boxOptionsHeader"><h2>' + p[3] + '</h2></div><div class="boxOptionsExtra">' + p[4] + '<br /><a href="http://maps.apple.com/maps?saddr=Current+Location&daddr=' + p[0] + ',' + p[1] + '">Directions to here</a></div>'
        });

        var i = gmarkers.length;
        gmarkers.push(marker);
        markerLength = gmarkers.length-1;
        side_bar_html += '- <a href="javascript:sidebarclick(' + markerLength + ')">' + p[3] + '<\/a><br \/>';


        alert(infoBoxPosition);
        var boxOptions = {
            content: boxText,
            disableAutoPan: false,
            alignBottom: true,
            maxWidth: 0,
            pixelOffset: infoBoxPosition,
            zIndex: null,
            boxStyle: {
                width: "240px"
            },
            closeBoxMargin: "0px 0px 0px -40px",
            closeBoxURL: "/images/mapicons/close_info.png",
            infoBoxClearance: new google.maps.Size(1, 1),
            visible: true,
            pane: "floatPane",
            enableEventPropagation: false,
            boxClass: 'boxOptions'
        };

        //console.log(marker.content);
        var ib = new InfoBox(boxOptions);
        google.maps.event.addListener(marker, 'click', function(e) {
            boxText.innerHTML = this.content;
            ib.open(map, this);
        });

        google.maps.event.addListener(map, 'click', function() {
            ib.close();
        });

        function setZoomWhenMarkerClicked() {
            var currentZoom = map.getZoom();
            if (currentZoom < 7) {
                map.setZoom(7);
            }
            return false;
        }
    }

    document.getElementById("side_bar").innerHTML = side_bar_html;
    map.fitBounds(bounds);
}

function sidebarclick(i) {
  google.maps.event.trigger(gmarkers[i], "click");
}

</script>

这是该框的 CSS。

html { height: 100% }
body { height: 100%; margin: 0; padding: 0; background-color: #FFF; }
#map-canvas { height: 100%;}

.infobox-wrapper {
    display:none;
}

.boxOptions {
    position: relative;
    border: 2px solid #E1002B;
    margin-top: 0px;
    background: #FAFAFA;
    color:#5B6770;
    font-family:Arial, Helvetica, sans-serif;
    font-size: 14px;
    -webkit-border-radius: 3px;
    -moz-border-radius: 3px;
    border-radius: 2px;
    text-shadow:0 -1px #FFF;
    z-index: 20;
}

.boxOptionsHeader {
    margin-top: -10px;
    padding: 0 1em;
}

.boxOptionsExtra {
    margin-top: -12px;
    padding: .5em 1em;
}

.boxOptions:after, .boxOptions:before {
    top: 100%;
    left: 15px;
    border: solid transparent;
    content: " ";
    height: 0;
    width: 0;
    position: absolute;
    pointer-events: none;
}

.boxOptions:after {
    border-color: rgba(136, 183, 213, 0);
    border-top-color: #FAFAFA;
    border-width: 8px;
    margin-left: -8px;
}

.boxOptions:before {
    border-color: rgba(194, 225, 245, 0);
    border-top-color: #E1002B;
    border-width: 11px;
    margin-left: -11px;
}

最佳答案

循环内信息框的创建是多余的,所有标记都将使用相同的信息框(将创建的最后一个信息框。请注意,您在每次迭代时都会覆盖 ib 变量) 。使用默认选项在循环外部创建单个 InfoBox 实例。

如何应用动态像素偏移:

将其存储为标记的属性,例如:

ibOffset :new google.maps.Size(iconSizes[6], iconSizes[7])

click监听器中设置ibpixelOffset选项:

ib.setOptions({'pixelOffset':this.ibOffset}); 

但最重要的是:

google.maps.Size() 期望参数为数字类型,但您提供字符串

删除 infoboxOffsetwinfoboxOffseth 值两边的引号

关于javascript - 如何设置信息框的动态像素偏移?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21262380/

相关文章:

javascript - 带有 'RETURNS TABLE' 的 Postgres PLV8 函数抛出 'ERROR: ReferenceError: $1 is not defined'

javascript - 为什么 omit() 不在映射后删除未定义的值?

algorithm - 多起点和一个终点的旅行商

google-maps - 如何判断当前是否选择了 Google map 标记?

google-maps-api-3 - 谷歌地图 v3 向圆圈添加信息窗口

javascript - 滚动到 href 属性时删除类

javascript - 重新加载 Disqus 的评论数

java - 我的 fragment 显示白屏而不是谷歌地图,为什么?

javascript - 谷歌地图回归原点

ios - 如何在 iOS 中使用 Google map API 在 mapView 上获取触摸位置的纬度和经度