【问题标题】:Fallback background-image if default doesn't exist如果默认值不存在,则回退背景图像
【发布时间】:2016-06-02 09:36:53
【问题描述】:

我想将图像设置为背景,但是图像名称可能是bg.pngbg.jpg

如果默认背景不存在,是否有任何非 JavaScript 方法可以创建备用图像的回退?

body{
    background: url(bg.png);
    background-size: 100% 100%;
    width: 100vw;
    height: 100vh;
    margin: 0;
}

【问题讨论】:

  • 如果图像存在,期望的行为是什么?
  • 我将添加一个文件上传器,上传器将接受 png 或 jpg。根据要上传的图片,它会将文件设置为 bg.png 或 bg.jpg
  • 可以在body标签中添加data-fallback属性,然后勾选var body = $(document.body);if(!(body.css('background'))) {body.css('background', body.data('fallback ')) }

标签: html css background


【解决方案1】:

如果不涉及透明度并且它们占据所有可用空间或具有相同大小,您可以使用多个背景:

div{   
     background-image: url('http://placehold.it/1000x1000'), url('http://placehold.it/500x500');
     background-repeat:no-repeat;
     background-size: 100%;
     height:200px;
     width:200px;
}
<div></div>

如果第一个没有退出,则会显示第二个。

div{   
     background-image: url('http://placehol/1000x1000'), url('http://placehold.it/500x500');
     background-repeat:no-repeat;
     background-size: 100%;
     height:200px;
     width:200px;
}
<div></div>

【讨论】:

  • 图片是叠放的,如果上面有透明的,下面的图片会看透
  • 浏览器兼容性如何?
  • @CrystalMiller 你可以在这里看到:caniuse.com/#feat=multibackgrounds
  • 不幸的是,在 chrome - 网络选项卡上 - 我可以看到它从服务器加载了两个图像。即使第一次成功。
  • 浏览器加载两个图像。如果第二个仅在第一个失败时才加载,那就太好了。 Afaik,这个解决方案不可能。
【解决方案2】:

要指定多个可能的背景,您可以这样做:

  background-color: green;
  background-image: url('bg.png'), url('bg.jpg');

这会将背景设置为bg.png(如果存在)。如果它不存在,它将被设置为bg.jpg。如果这些图像都不存在,则背景将设置为静态green 颜色。

请注意,它将优先考虑首先指定的任何图像。因此,如果两个图像都存在,它将选择bg.png 而不是bg.jpg

查看demo here。通过破坏任何图像 url 来测试它。

【讨论】:

  • 它不是我需要的解决方案,但我只是对替代解决方案投了赞成票。
  • @djsony90 哦,所以图像会一直存在,但它要么是jpg 要么是png
  • 对不起,我没有指定。上传者将删除现有的 bg.png 或 bg.jpg 然后更新一个新的 bg.png 或 bg.jpg
  • 正如@blonfu 在另一个答案中提到的那样,两个图像都已加载和堆叠。它不只是加载第一个成功的文件。
  • @J.Hendrix 是对的,但是没有 JavaScript 就没有其他方法可以解决这个问题。 OP 要求使用“非 javascript 方式”,这可能与仅使用 css 的方式一样好。除非我遗漏了什么(如果有,请说明什么),我认为否决票是不合理的,因为实际上没有其他方法可以解决这个问题。
【解决方案3】:

虽然这个方案确实涉及到JS,但是它会使用CSS下载第一张图片,并且在主图下载失败的情况下使用JS下载备用图片。

首先,像往常一样用CSS设置主图,例如:

.myImage {
    background-image = "main-image.png";
}

并添加以下JS,仅在加载主图像失败时才会起作用(否则将永远不会下载备用图像)。

var img = document.createElement("img");
img.onerror = function() {
    var style = document.createElement('style');
    style.innerHTML = '.myImage { background-image = url("http://fallback_image.png"); }';
    document.head.appendChild(style);
}
img.src = "main_image.png";

请注意,您可以向使用 javascript 添加的 CSS 块添加多个规则,例如,如果您需要对多个元素执行此操作。

【讨论】:

    【解决方案4】:

    我想要一个不会两次加载图像的解决方案。例如,如果 CDN 总是加载原始图像,那么带有后备的 CDN 就不是很好。所以我最终编写了一个 Javascript 来操作加载的 CSS DOM。

    var cdn = "https://mycdn.net/"; // Original location or thing to find
    var localImageToCssPath = "../"; // Replacement, Css are in /css/ folder.
    
    function replaceStyleRule(allRules){
      var rulesCount = allRules.length;
    
      for (var i=0; i < rulesCount; i++) 
      {
        if(allRules[i].style !== undefined && allRules[i].style !== null &&
            allRules[i].style.backgroundImage !== undefined &&
            allRules[i].style.backgroundImage !== null &&
            allRules[i].style.backgroundImage !== "" &&
            allRules[i].style.backgroundImage !== "none" &&
            allRules[i].style.backgroundImage.indexOf(cdn) > -1
                )
          {
            var tmp = allRules[i].style.backgroundImage.replace(cdn, localImageToCssPath);
            //console.log(tmp);
            allRules[i].style.backgroundImage = tmp;
          }
          if(allRules[i].cssRules !== undefined && allRules[i].cssRules !== null){
            replaceStyleRule(allRules[i].cssRules);
          }
    
      }
    }
    function fixBgImages(){
      var allSheets = document.styleSheets;
      if(allSheets===undefined || allSheets===null){
        return;
      }
      var sheetsCount = allSheets.length;
      for (var j=0; j < sheetsCount; j++) 
      {
        var allRules = null;
        try{
            allRules = allSheets[j].cssRules;
        } catch(e){
            // Access can be denied
        }
        if(allRules!==undefined && allRules!==null){
            replaceStyleRule(allRules);
        }
      }
    }
    
    // use fixBgImages() in e.g. onError
    

    【讨论】:

      【解决方案5】:

      你可以使用css的背景图片,并在隐藏的图片标签和onError中使用相同的图片URL,更改图片URL并使其显示

      <div
        style={{ backgroundImage: `url(${imageSrc})` }}
      >
        <img
          style={{ display: "none" }}
          src={imageSrc}
          onError={(e) => {
            e.currentTarget.src = brokenImageFallbackUrl;
            e.currentTarget.style.display = "block";
            // or keep this image hidden and set the backgroundImage of the parent div
          }}
        />
      </div>
      

      【讨论】:

        猜你喜欢
        • 2012-07-23
        • 1970-01-01
        • 2018-10-10
        • 1970-01-01
        • 2022-06-12
        • 2014-01-30
        • 2014-06-17
        • 2022-01-12
        • 1970-01-01
        相关资源
        最近更新 更多