将图像预加载到传单弹出窗口中
Preloading Images into Leaflet Popup
我目前正在向我的国内旅游目的地传单地图添加一些弹出窗口。弹出窗口将有一个标题、图像和 wiki link。我想检查图像是否可用并预加载它们。这一切我都成功了,但现在我不知道如何将预加载的图像插入到弹出窗口中。
这是我的代码:
var tourists = result.tourists.geonames;
var images_urls = [];
for (let i in tourists) {
$.get(tourists[i].thumbnailImg)
.done(function () {
images_urls.push(tourists[i].thumbnailImg);
}).fail(function () {
images_urls.push("libs/css/image/wiki.png");
})
}
var images = [];
function preload(arguments) {
for (var i = 0; i < arguments.length; i++) {
images = new Image();
images.src = arguments[i];
}
}
preload(images_urls);
for (let i in tourists) {
markers.addLayer(
L.marker([tourists[i].lat, tourists[i].lng], { icon: touristIcon })
.bindPopup(`<b>${tourists[i].title}</b> <br> INSERT PRELOADED IMAGES <br> <a href="https://${tourists[i].wikipediaUrl}" target="_blank" >Wikipedia Article<a> <br>`)
)
}
一旦您“预加载”了您的图像,它就会存储在浏览器缓存中,您不需要做任何特别的事情就可以从该缓存中获益;浏览器检测到您请求相同的路径,并从其缓存中提供文件(前提是文件缓存策略允许)。
因此,暂时忽略文件可能不可用,您可以重新使用 tourists[i].thumbnailImg
URL.
但是如果我没理解错的话,您想使用不可用检测来显示另一张图片吗?
问题是您将此检测的结果推送到单独的数组 images_urls
中,并且这些结果可能是无序的(失败 URL 可能需要更多时间)。
一个简单的解决方案可能是扩展您的 tourists
object/array:
for (let i in tourists) {
$.get(tourists[i].thumbnailImg)
.done(function () {
// Add an extra property
tourists[i].safeImgUrl = tourists[i].thumbnailImg;
}).fail(function () {
tourists[i].safeImgUrl = "libs/css/image/wiki.png";
})
}
// preload
for (let i in tourists) {
markers.addLayer(
L.marker([tourists[i].lat, tourists[i].lng], {
icon: touristIcon
})
.bindPopup(`<b>${tourists[i].title}</b> <br>
${tourists[i].safeImgUrl}<br>
<a href="https://${tourists[i].wikipediaUrl}" target="_blank" >Wikipedia Article<a> <br>`)
)
}
注意:您可能希望在构建弹出内容之前等待一些时间,因为您的图像可用性检测可能需要一些时间才能填充新的 safeImgUrl 属性。
实现此目的的一种可能方法是在单击标记时重新设置弹出内容。
终于找到问题了!在将弹出窗口绑定到标记之前,我需要构建弹出窗口!所以这里是检查 URL 工作然后预加载图像的代码。
function preloadImage(url, width, height) {
var img = new Image(width, height);
img.src = url;
return img;
}
function checkImage(imageSrc, backup, width, height) {
var http = new XMLHttpRequest();
http.open('HEAD', imageSrc, true);
http.send();
if (http.status != 404) {
return preloadImage(imageSrc, width, height)
} else {
return preloadImage(backup, width, height)
}
}
弹出窗口的构造方法如下:
var tourists = result.tourists.geonames;
for (let i in tourists) {
var popup = document.createElement('div');
var br = document.createElement('br');
var picture_popup = checkImage(tourists[i].thumbnailImg, 'libs/css/image/wiki.png', 120, 100);
var a = document.createElement('a');
var linkText = document.createTextNode(tourists[i].title);
a.appendChild(linkText);
a.title = 'Wikipedia article';
a.target = '_blank';
a.href = 'https://' + tourists[i].wikipediaUrl;
popup.appendChild(picture_popup);
popup.appendChild(br);
popup.appendChild(a);
markers.addLayer(
L.marker([tourists[i].lat, tourists[i].lng], {
icon: touristIcon
})
.bindPopup(popup)
)
}
现在唯一的问题是相对备份 URL 无法正常工作,但它基本上就在那里!
我目前正在向我的国内旅游目的地传单地图添加一些弹出窗口。弹出窗口将有一个标题、图像和 wiki link。我想检查图像是否可用并预加载它们。这一切我都成功了,但现在我不知道如何将预加载的图像插入到弹出窗口中。
这是我的代码:
var tourists = result.tourists.geonames;
var images_urls = [];
for (let i in tourists) {
$.get(tourists[i].thumbnailImg)
.done(function () {
images_urls.push(tourists[i].thumbnailImg);
}).fail(function () {
images_urls.push("libs/css/image/wiki.png");
})
}
var images = [];
function preload(arguments) {
for (var i = 0; i < arguments.length; i++) {
images = new Image();
images.src = arguments[i];
}
}
preload(images_urls);
for (let i in tourists) {
markers.addLayer(
L.marker([tourists[i].lat, tourists[i].lng], { icon: touristIcon })
.bindPopup(`<b>${tourists[i].title}</b> <br> INSERT PRELOADED IMAGES <br> <a href="https://${tourists[i].wikipediaUrl}" target="_blank" >Wikipedia Article<a> <br>`)
)
}
一旦您“预加载”了您的图像,它就会存储在浏览器缓存中,您不需要做任何特别的事情就可以从该缓存中获益;浏览器检测到您请求相同的路径,并从其缓存中提供文件(前提是文件缓存策略允许)。
因此,暂时忽略文件可能不可用,您可以重新使用 tourists[i].thumbnailImg
URL.
但是如果我没理解错的话,您想使用不可用检测来显示另一张图片吗?
问题是您将此检测的结果推送到单独的数组 images_urls
中,并且这些结果可能是无序的(失败 URL 可能需要更多时间)。
一个简单的解决方案可能是扩展您的 tourists
object/array:
for (let i in tourists) {
$.get(tourists[i].thumbnailImg)
.done(function () {
// Add an extra property
tourists[i].safeImgUrl = tourists[i].thumbnailImg;
}).fail(function () {
tourists[i].safeImgUrl = "libs/css/image/wiki.png";
})
}
// preload
for (let i in tourists) {
markers.addLayer(
L.marker([tourists[i].lat, tourists[i].lng], {
icon: touristIcon
})
.bindPopup(`<b>${tourists[i].title}</b> <br>
${tourists[i].safeImgUrl}<br>
<a href="https://${tourists[i].wikipediaUrl}" target="_blank" >Wikipedia Article<a> <br>`)
)
}
注意:您可能希望在构建弹出内容之前等待一些时间,因为您的图像可用性检测可能需要一些时间才能填充新的 safeImgUrl 属性。 实现此目的的一种可能方法是在单击标记时重新设置弹出内容。
终于找到问题了!在将弹出窗口绑定到标记之前,我需要构建弹出窗口!所以这里是检查 URL 工作然后预加载图像的代码。
function preloadImage(url, width, height) {
var img = new Image(width, height);
img.src = url;
return img;
}
function checkImage(imageSrc, backup, width, height) {
var http = new XMLHttpRequest();
http.open('HEAD', imageSrc, true);
http.send();
if (http.status != 404) {
return preloadImage(imageSrc, width, height)
} else {
return preloadImage(backup, width, height)
}
}
弹出窗口的构造方法如下:
var tourists = result.tourists.geonames;
for (let i in tourists) {
var popup = document.createElement('div');
var br = document.createElement('br');
var picture_popup = checkImage(tourists[i].thumbnailImg, 'libs/css/image/wiki.png', 120, 100);
var a = document.createElement('a');
var linkText = document.createTextNode(tourists[i].title);
a.appendChild(linkText);
a.title = 'Wikipedia article';
a.target = '_blank';
a.href = 'https://' + tourists[i].wikipediaUrl;
popup.appendChild(picture_popup);
popup.appendChild(br);
popup.appendChild(a);
markers.addLayer(
L.marker([tourists[i].lat, tourists[i].lng], {
icon: touristIcon
})
.bindPopup(popup)
)
}
现在唯一的问题是相对备份 URL 无法正常工作,但它基本上就在那里!