如何解决Overlay自动平移时Click误触发Select交互的问题?
问题描述
当为Overlay设置autopan: true时,点击红色圆形标记会出现以下情况:
- 弹出Overlay
- autopan功能滚动地图使整个Overlay可见
- Select交互捕获点击事件,导致矩形变为红色
若autopan设为false,点击红色圆形标记时仅弹出Overlay,不会触发Select交互。
推测原因:点击后autopan移动了地图,当Select交互检查是否处理该点击事件时,原本用于阻止触发的红色标记已移动,无法起到阻止作用。
需在全屏视图查看代码片段,将红色圆形标记置于地图视图底部,使autopan能让整个Overlay显示。请问该如何解决此问题?
代码片段
HTML
<link href="https://cdnjs.cloudflare.com/ajax/libs/openlayers/7.3.0/ol.min.css" rel="stylesheet" /> <script src="https://cdnjs.cloudflare.com/ajax/libs/openlayers/7.3.0/dist/ol.min.js"></script> <div id="map"></div> <div id="popup" class="popup"></div>
CSS
#map { height: 512px; width: 1024px; } .popup { width: 200px; height: 300px; background-color: blue; }
JavaScript
// // Create the Rectangle // function createRectangle(layerName) { const features = []; const feature = { type: "Feature", geometry: { type: "Polygon", coordinates: [ [ [30, 5], [30, 30], [85, 30], [85, 5] ] ] }, properties: { id: `${layerName}`, layerName } }; features.push(feature); const json = { type: "FeatureCollection", features }; return json; } const rectangle = createRectangle("small"); const rectangleStyle = new ol.style.Style({ stroke: new ol.style.Stroke({ color: "hsla(120, 50%, 100%, 1.0)", width: 5 }), fill: new ol.style.Fill({ color: "hsla(120, 50%, 50%, 0.50)" }) }); const rectangleVectorLayer = new ol.layer.Vector({ source: new ol.source.Vector({ features: new ol.format.GeoJSON({ featureProjection: "EPSG:4326" // 4326 3857 }).readFeatures(rectangle) }), style: (feature) => rectangleStyle, zIndex: 4, properties: { name: "small" } }); // // Create the marker which will have the overlay attached // const markerStyle = new ol.style.Style({ image: new ol.style.Circle({ radius: 12, fill: new ol.style.Fill({ color: "#e00" }), stroke: new ol.style.Stroke({ color: "black", width: 2 }) }) }); const markerLayer = new ol.layer.Vector({ source: new ol.source.Vector({ features: [ new ol.Feature({ geometry: new ol.geom.Point([55, 25]) }) ] }), style: (feature) => markerStyle, zIndex: 10 }); // // Create OSM Layer // const osmLayer = new ol.layer.Tile({ source: new ol.source.OSM() }); // // Create the Map // const map = new ol.Map({ target: "map", layers: [osmLayer, rectangleVectorLayer, markerLayer], view: new ol.View({ projection: "EPSG:4326", center: [55, 30], zoom: 5 }) }); // // // const selectedStyle = new ol.style.Style({ fill: new ol.style.Fill({ color: "hsla(0, 50%, 50%, 0.5)" }), stroke: new ol.style.Stroke({ color: "hsla(0, 50%, 100%, 1)", width: 3 }), zIndex: 1 }); const rectangleLayerInteraction = new ol.interaction.Select({ style: (feature) => { return selectedStyle; }, layers: [rectangleVectorLayer], condition: function (e) { const isSingleClick = ol.events.condition.singleClick(e); let passed = false; if (isSingleClick) { console.group(); const features = map.getFeaturesAtPixel(e.pixel, { layerFilter: function (l) { //console.log( // "rectangle layerFilter", // l.getZIndex(), // rectangleVectorLayer.getZIndex(), // l.getZIndex() > rectangleVectorLayer.getZIndex() //); return l.getZIndex() > rectangleVectorLayer.getZIndex(); } }); const noFeatures = features.length === 0; passed = isSingleClick && noFeatures; //console.log("condition features", features); //console.log("condition noFeatures", noFeatures); //console.log("condition isSingleClick", isSingleClick); //console.log("condition passed", passed); console.groupEnd(); } return passed; } }); map.addInteraction(rectangleLayerInteraction); // // Add overlay and handler // const popup = new ol.Overlay({ element: document.getElementById("popup"), autoPan: true }); map.addOverlay(popup); const markerLayerUID = ol.util.getUid(markerLayer); map.on("click", (e) => { const hitFeatures = map.getFeaturesAtPixel(e.pixel, { layerFilter: (layer) => { return ol.util.getUid(layer) === markerLayerUID; } }); //console.log("hitFeatures", hitFeatures); if (hitFeatures.length === 1) { const position = ol.extent.getBottomLeft( hitFeatures[0].getGeometry().getExtent() ); popup.setPosition(position); } else { popup.setPosition(undefined); } });
内容的提问来源于stack exchange,提问作者Eric G
相关产品推荐
相关产品推荐

