将图像预加载到传单弹出窗口中

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 无法正常工作,但它基本上就在那里!