javascript 从 OpenLayers 功能中删除所有弹出窗口

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9274635/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 06:07:44  来源:igfitidea点击:

Remove all Popups from OpenLayers Features

javascriptopenlayers

提问by Christian Mayne

I am using OpenLayers to create a map and plot locations. Each location has a marker and a popup and are created using OpenLayers.Feature - at the moment, I'm definitely outside of my comfort zone here, so am cobbling example code together.

我正在使用 OpenLayers 创建地图和绘制位置。每个位置都有一个标记和一个弹出窗口,并使用 OpenLayers.Feature 创建 - 目前,我绝对超出了我的舒适区,所以我将示例代码拼凑在一起。

A marker is created as follows (I've chopped what I hope are obvious variable assignments for brevity):

一个标记创建如下(为了简洁起见,我已经砍掉了我希望是明显的变量分配):

function addMarker(ll, popupClass, popupContentHTML, closeBox, overflow, type)
{
    var feature = new OpenLayers.Feature(markerLayer, ll);  
    feature.closeBox = closeBox;
    feature.popupClass = popupClass;
    feature.data.icon = icon;
    feature.data.popupContentHTML = popupContentHTML;
    feature.data.overflow = (overflow) ? "auto" : "hidden";

    var marker = feature.createMarker();
    var markerClick = function (evt) {
        if (this.popup == null) {
            this.popup = this.createPopup(this.closeBox);
            map.addPopup(this.popup);
            this.popup.show();
        } else {
            this.popup.toggle();
    }
        currentPopup = this.popup;
        OpenLayers.Event.stop(evt);
    };

    marker.events.register("mousedown", feature, markerClick);
    markerLayer.addMarker(marker);
}

The map can contain many markers.

地图可以包含许多标记。

When a marker is clicked a popup toggles on and off. What I am trying to ado is make ALL popups relating to all markers on the map close when a new marker is clicked and a popup toggles on - that is, I only want one popup to display at a time.

单击标记时,弹出窗口会打开和关闭。我想要做的是在单击新标记并打开弹出窗口时关闭与地图上所有标记相关的所有弹出窗口 - 也就是说,我一次只希望显示一个弹出窗口。

It may be that my approach is all wrong, but would be grateful for pointers, even just ideas to try.

可能是我的方法全错了,但会感谢您的指点,甚至只是尝试的想法。

回答by tony gil

IF you implement a solution whereas only one popup is active at a time (i.e. every time a popup is unselected it disappears), you will NEVER have more than one popup at a time.

如果您实施了一个解决方案,而一次只有一个弹出窗口处于活动状态(即每次取消选择一个弹出窗口时它都会消失),那么您一次将永远不会有多个弹出窗口。

read thisSTACKOVERFLOW answer which i wrote for exactly this problem. you have all the necessary pseudocode there (with lengthy explanations about everything).

阅读我为这个问题写的这个STACKOVERFLOW 答案。你有所有必要的伪代码(对所有内容都有冗长的解释)。

if you dont need the explanations, this shows the solution:

如果您不需要解释,这将显示解决方案:

var urlKML = 'parseKMLTrack07d.php';         
var layerKML = new OpenLayers.Layer.Vector("KML1", {
            strategies: [new OpenLayers.Strategy.Fixed()],
            protocol: new OpenLayers.Protocol.HTTP({
                url: urlKML,
                format: new OpenLayers.Format.KML({
                    extractStyles: true, 
                    extractAttributes: true,
                    maxDepth: 2
                })
            })
        });

var layerOSM = new OpenLayers.Layer.OSM();
var map = new OpenLayers.Map({
    div: "map",
    layers: [
        layerOSM,
        layerKML 
    ]
});

var selectStop = new OpenLayers.Control.SelectFeature(layerKML,{onSelect: onFeatureSelect, onUnselect: onFeatureUnselect});
layerKML.events.on({
            "featureselected": onFeatureSelect,
            "featureunselected": onFeatureUnselect
        });
map.addControl(selectStop);
selectStop.activate();

function onFeatureSelect(event) {
    var feature = event.feature;
    var content = feature.attributes.name + '<br/>'+feature.attributes.description;
    popup = new OpenLayers.Popup.FramedCloud("chicken", 
                             feature.geometry.getBounds().getCenterLonLat(),
                             new OpenLayers.Size(100,100),
                             content,
                             null, true, onFeatureUnselect);
    feature.popup = popup;
    map.addPopup(popup);
    // GLOBAL variable, in case popup is destroyed by clicking CLOSE box
    lastfeature = feature;
}
function onFeatureUnselect(event) {
    var feature = lastfeature;  
    if(feature.popup) {
        map.removePopup(feature.popup);
        feature.popup.destroy();
        delete feature.popup;
    }
}

now, if you REALLY want to destroy all popups, regardless (which i very much discourage):

现在,如果你真的想销毁所有弹出窗口,不管(我非常不鼓励):

function popupClear() {
    //alert('number of popups '+map.popups.length);
    while( map.popups.length ) {
         map.removePopup(map.popups[0]);
    }
}

回答by j_freyre

What I remember about OpenLayers is that you should implement a control for the feature selection.

我记得关于 OpenLayers 的是你应该为特征选择实现一个控件。

I hope it will works with your markers...

我希望它适用于您的标记...

var selectedFeature, selectControl;
function init() {
...
  selectControl = new OpenLayers.Control.SelectFeature(yourMainLayer, {
        onSelect: onFeatureSelect, // will be called on feature select
        onUnselect: onFeatureUnselect // will be called on feature unselect
  });
  selectControl.activate();
...
}

function onFeatureSelect(feature) {
            popup = new OpenLayers.Popup.FramedCloud("chicken", 
                                     feature.geometry.getBounds().getCenterLonLat(),
                                     null,
                                     "some informations",
                                     null, true, onPopupClose);
            feature.popup = popup;
            map.addPopup(popup);
}
function onFeatureUnselect(feature) {
   map.removePopup(feature.popup);
   feature.popup.destroy();
   feature.popup = null;
} 
function onPopupClose(evt) {
   selectControl.unselect(selectedFeature);
}

回答by mihai

Why don't you throw the open popups into an array on the if(this.popup == null)branch, and on the elsebranch loop over this array and hide all popups.

为什么不将打开的弹出窗口放入if(this.popup == null)分支上的数组中,然后在else分支上循环遍历该数组并隐藏所有弹出窗口。