0

could you please tell me why I am getting background image 0 in safari . I am getting 225px width in chrome and firefox and zero in safari

here is my code 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>

any suggestion ? ?

shotgun02
  • 756
  • 4
  • 14
user944513
  • 12,247
  • 49
  • 168
  • 318

1 Answers1

0

Like the comments suggest you need to wait for the image to load. Here I added an event listener for the image object.

And maybe the image is already in the cache, but you need to wait for the image to load into this particular object.

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>
chrwahl
  • 8,675
  • 2
  • 20
  • 30
  • expected output is `225` or `200` ..see after button click – user944513 Aug 26 '21 at 08:43
  • try your solution https://codesandbox.io/s/lucid-spence-cuyf7?file=/index.html – user944513 Aug 26 '21 at 08:44
  • @user944513 I didn't go into details with the calculation of the ratio, but the image is 100x100 and in your code that will return `1`. If you need to add padding, margin or something else I don't know. – chrwahl Aug 26 '21 at 08:59