我应用了@ghybs提供的popup.update()代码段,可以很好地调整弹出窗口使其适合地图框架,如您在此处看到的代码所示:
start
问题是我在每个弹出窗口的缩略图中都嵌入了一个URL。当我单击缩略图时,光标指示应该可以单击“单击”,但它不会执行任何操作。右键单击缩略图后,可以在新标签页中打开网址。网址在那里,只是无法按我想要的方式工作。我和一个朋友看着代码,我们确定正在不断重新创建javascript弹出窗口。他建议可能是更新电话,但不确定。如果有一种方法可以阻止javascript不断重新创建弹出窗口,那么这可能会解决问题。
他还指出,当他停止运行JavaScript时,只有在应该占据整个缩略图(通常为250px)的情况下,该URL才可在缩略图的下半部分(特别是14px高)上单击。
在更新后立即检查console.log(popup)时,它陷入了无限循环。我猜这是问题的核心。有没有办法在更新弹出窗口大小后停止更新?我希望这样做可以释放嵌入的URL,以便可以单击,但我也希望链接的高度与整个缩略图匹配。
作为参考,我正在从geojson文件中提取点并将相同的方法应用于每个点,就像这样:
document.querySelector(".leaflet-popup-pane").addEventListener("load", function (event) {
var tagName = event.target.tagName,
popup = map._popup;
console.log("got load event from " + tagName);
if (tagName === "IMG" && popup) {
popup.update();
}
}, true);
答案 0 :(得分:2)
欢迎您!
哼哼,当您将弹出内容指定为包含<img>
的HTML字符串时,看起来given workaround确实创建了一个无限循环。发生的情况是,当图像完成加载后,popup.update()
使用HTML字符串重置Popup内容,因此重新创建<img>
元素,该元素会发出新的"load"
事件,即使现在它来自浏览器缓存。然后,侦听器再次执行popup.update()
,依此类推。
演示(打开Web控制台以查看无限循环日志记录“来自IMG的加载事件”)
var map = L.map('map').setView([48.86, 2.35], 11);
// Modify the cache busting value to force browser fetching from network.
var imgSrc = 'https://a.tile.openstreetmap.org/0/0/0.png?bust=1';
var popupContent =
'<a href="https://a.tile.openstreetmap.org/0/0/0.png" target="_blank">' +
'<img src="' + imgSrc + '"/></a>';
L.marker([48.86, 2.35]).addTo(map).bindPopup(popupContent);
document.querySelector(".leaflet-popup-pane").addEventListener("load", function(event) {
var tagName = event.target.tagName,
popup = map._popup;
console.log("got load event from " + tagName);
if (tagName === "IMG" && popup) {
popup.update();
}
}, true);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
html,
body,
#map {
height: 100%;
margin: 0;
}
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.3/dist/leaflet.css" integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==" crossorigin="" />
<script src="https://unpkg.com/leaflet@1.3.3/dist/leaflet-src.js" integrity="sha512-GosS1/T5Q7ZMS2cvsPm9klzqijS+dUz8zgSLnyP1iMRu6q360mvgZ4d1DmMRP2TDEEyCT6C16aB7Vj1yhGT1LA==" crossorigin=""></script>
<div id="map"></div>
在您的情况下,如果您确定在任何给定时间仅打开1个弹出窗口,并且仅包含一个<img>
,则可以简单地在第一个"load"
处设置一个标志该弹出窗口上发生的事件,以防止无限循环:
var map = L.map('map').setView([48.86, 2.35], 11);
// Modify the cache busting value to force browser fetching from network.
var imgSrc = 'https://a.tile.openstreetmap.org/0/0/0.png?bust=2';
var popupContent =
'<a href="https://a.tile.openstreetmap.org/0/0/0.png" target="_blank">' +
'<img src="' + imgSrc + '"/></a>';
L.marker([48.86, 2.35]).addTo(map).bindPopup(popupContent);
document.querySelector(".leaflet-popup-pane").addEventListener("load", function(event) {
var tagName = event.target.tagName,
popup = map._popup;
console.log("got load event from " + tagName);
// Also check if flag is already set.
if (tagName === "IMG" && popup && !popup._updated) {
popup._updated = true; // Set flag to prevent looping.
popup.update();
}
}, true);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
html,
body,
#map {
height: 100%;
margin: 0;
}
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.3/dist/leaflet.css" integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==" crossorigin="" />
<script src="https://unpkg.com/leaflet@1.3.3/dist/leaflet-src.js" integrity="sha512-GosS1/T5Q7ZMS2cvsPm9klzqijS+dUz8zgSLnyP1iMRu6q360mvgZ4d1DmMRP2TDEEyCT6C16aB7Vj1yhGT1LA==" crossorigin=""></script>
<div id="map"></div>
(请注意,SO代码段似乎阻止了<a href>
链接的打开,因此这里有一个Plunk来检查链接是否可以正常打开:https://next.plnkr.co/edit/ore09Yxmm6DVmJGc)
现在,对于HTML字符串中包含任意数量的图像,并且可以同时打开多个Popup的情况,现在可以泛化解决方案,我们可以想象:
"popupopen"
和每个图像"load"
事件中,检查所有弹出图像是否具有非零的naturalWidth
,否则进行更新。map._popup
(仅引用最后一个打开的Popup)。
var map = L.map('map', {
closePopupOnClick: false
}).setView([48.86, 2.35], 11);
// Modify the cache busting value to force browser fetching from network.
var imgSrc1 = 'https://a.tile.openstreetmap.org/0/0/0.png?bust=3';
var imgSrc2 = 'https://a.tile.openstreetmap.org/11/1037/704.png?bust=3';
var popupContent =
'<a href="' + imgSrc1 + '" target="_blank">' +
'<img src="' + imgSrc1 + '"/></a>' +
'<a href="' + imgSrc2 + '" target="_blank">' +
'<img src="' + imgSrc2 + '"/></a>';
L.marker([48.86, 2.35]).addTo(map).bindPopup(popupContent, {
autoClose: false
}).on('click', function() {
// Open another Popup after this one.
m2.openPopup();
});
var m2 = L.marker([48.86, 2.32]).bindPopup('Second Popup', {
autoClose: false
}).addTo(map);
// Prepare the Popup when it opens.
map.on('popupopen', function(event) {
var popup = event.popup;
popup._imgAllSized = popupImgAllSized(popup);
});
document.querySelector(".leaflet-popup-pane").addEventListener("load", function(event) {
var target = event.target,
tagName = target.tagName,
popup = target._popup;
console.log("got load event from " + tagName);
// Also check the Popup "_imgAllSized" flag.
if (tagName === "IMG" && popup && !popup._imgAllSized) {
console.log('updated');
// Update the flag, in case all images have finished loading.
popup.update();
popup._imgAllSized = popupImgAllSized(popup);
}
}, true);
function popupImgAllSized(popup) {
// Get the HTMLElement holding the Popup content.
var container = popup._contentNode;
var imgs = container.querySelectorAll('img');
var imgAllSized = true;
for (var i = 0; i < imgs.length; i += 1) {
// Store reference to popup in <img>
imgs[i]._popup = popup;
// Check if the image has unknown size.
if (!imgs[i].naturalWidth) {
imgAllSized = false;
}
}
console.log(imgAllSized);
return imgAllSized;
}
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
html,
body,
#map {
height: 100%;
margin: 0;
}
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.3/dist/leaflet.css" integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==" crossorigin="" />
<script src="https://unpkg.com/leaflet@1.3.3/dist/leaflet-src.js" integrity="sha512-GosS1/T5Q7ZMS2cvsPm9klzqijS+dUz8zgSLnyP1iMRu6q360mvgZ4d1DmMRP2TDEEyCT6C16aB7Vj1yhGT1LA==" crossorigin=""></script>
<div id="map"></div>
然后,我们甚至可以通过尝试update as soon as the images have their naturalWidth
而不是等待它们的"load"
事件来进一步改进此解决方案,以便即使在浏览器仍在获取事件时,也会更新Popup的大小和位置