0

你能告诉我为什么我0在 safari 中得到背景图像吗?我225px在 chrome 和 firefox 中得到宽度,在 safari 中得到零

这是我的代码 https://codesandbox.io/s/lucid-spence-cuyf7?file=/index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Static Template</title>
    <style>
      .img {
        background: url("./download.jpeg") no-repeat left;
      }
    </style>
  </head>
  <body>
    <div class="img" alt="" />
    <button onclick="abc()">click</button>
    <script>
      function getBackgroundSize(elem) {
        // This:
        //       * Gets elem computed styles:
        //             - CSS background-size
        //             - element's width and height
        //       * Extracts background URL
        var computedStyle = getComputedStyle(elem),
          image = new Image(),
          src = computedStyle.backgroundImage.replace(
            /url\((['"])?(.*?)\1\)/gi,
            "$2"
          ),
          cssSize = computedStyle.backgroundSize,
          elemW = parseInt(computedStyle.width.replace("px", ""), 10),
          elemH = parseInt(computedStyle.height.replace("px", ""), 10),
          elemDim = [elemW, elemH],
          computedDim = [],
          ratio;
        // Load the image with the extracted URL.
        // Should be in cache already.
        image.src = src;
        // Determine the 'ratio'
        ratio =
          image.width > image.height
            ? image.width / image.height
            : image.height / image.width;
        // Split background-size properties into array
        cssSize = cssSize.split(" ");
        // First property is width. It is always set to something.
        computedDim[0] = cssSize[0];
        // If height not set, set it to auto
        computedDim[1] = cssSize.length > 1 ? cssSize[1] : "auto";
        if (cssSize[0] === "cover") {
          // Width is greater than height
          if (elemDim[0] > elemDim[1]) {
            // Elem's ratio greater than or equal to img ratio
            if (elemDim[0] / elemDim[1] >= ratio) {
              computedDim[0] = elemDim[0];
              computedDim[1] = "auto";
            } else {
              computedDim[0] = "auto";
              computedDim[1] = elemDim[1];
            }
          } else {
            computedDim[0] = "auto";
            computedDim[1] = elemDim[1];
          }
        } else if (cssSize[0] === "contain") {
          // Width is less than height
          if (elemDim[0] < elemDim[1]) {
            computedDim[0] = elemDim[0];
            computedDim[1] = "auto";
          } else {
            // elem's ratio is greater than or equal to img ratio
            if (elemDim[0] / elemDim[1] >= ratio) {
              computedDim[0] = "auto";
              computedDim[1] = elemDim[1];
            } else {
              computedDim[1] = "auto";
              computedDim[0] = elemDim[0];
            }
          }
        } else {
          // If not 'cover' or 'contain', loop through the values
          for (var i = cssSize.length; i--; ) {
            // Check if values are in pixels or in percentage
            if (cssSize[i].indexOf("px") > -1) {
              // If in pixels, just remove the 'px' to get the value
              computedDim[i] = cssSize[i].replace("px", "");
            } else if (cssSize[i].indexOf("%") > -1) {
              // If percentage, get percentage of elem's dimension
              // and assign it to the computed dimension
              computedDim[i] = elemDim[i] * (cssSize[i].replace("%", "") / 100);
            }
          }
        }
        // If both values are set to auto, return image's
        // original width and height
        if (computedDim[0] === "auto" && computedDim[1] === "auto") {
          computedDim[0] = image.width;
          computedDim[1] = image.height;
        } else {
          // Depending on whether width or height is auto,
          // calculate the value in pixels of auto.
          // ratio in here is just getting proportions.
          ratio =
            computedDim[0] === "auto"
              ? image.height / computedDim[1]
              : image.width / computedDim[0];
          computedDim[0] =
            computedDim[0] === "auto" ? image.width / ratio : computedDim[0];
          computedDim[1] =
            computedDim[1] === "auto" ? image.height / ratio : computedDim[1];
        }
        // Finally, return an object with the width and height of the
        // background image.
        return {
          width: computedDim[0],
          height: computedDim[1]
        };
      }

      function abc() {
        console.log(getBackgroundSize(document.querySelector(".img")));
      }
    </script>
  </body>
</html>

有什么建议吗??

4

1 回答 1

0

就像评论建议您需要等待图像加载一样。在这里,我为图像对象添加了一个事件侦听器。

也许图像已经在缓存中,但您需要等待图像加载到这个特定对象中。

var onImageLoad = e => {
  let image = e.target;
  let ratio =
    image.width > image.height ?
    image.width / image.height :
    image.height / image.width;
  console.log(ratio);
};

function getBackgroundSize(elem) {
  var computedStyle = getComputedStyle(elem),
    image = new Image(),
    src = computedStyle.backgroundImage.replace(
      /url\((['"])?(.*?)\1\)/gi,
      "$2"
    ),
    cssSize = computedStyle.backgroundSize,
    elemW = parseInt(computedStyle.width.replace("px", ""), 10),
    elemH = parseInt(computedStyle.height.replace("px", ""), 10),
    elemDim = [elemW, elemH],
    computedDim = [];
    
  image.addEventListener('load', onImageLoad);
  image.src = src;
}

function abc() {
  getBackgroundSize(document.querySelector(".img"));
}
.img {
  background: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwIiBoZWlnaHQ9IjEwMCIgdmlld0JveD0iMCAwIDEwIDEwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDxyZWN0IHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCIgZmlsbD0iZ3JheSIgLz4KPC9zdmc+") no-repeat left;
  width: 200px;
  height: 200px;
}
<div class="img"></div>
<button onclick="abc()">click</button>

于 2021-08-26T08:35:36.360 回答