【问题标题】:Get the Size of a CSS Background Image Using JavaScript?使用 JavaScript 获取 CSS 背景图像的大小?
【发布时间】:2011-03-07 02:51:08
【问题描述】:

是否可以使用 JavaScript 来获取 CSS 引用的背景图像的实际大小(以像素为单位的宽度和高度)?

【问题讨论】:

    标签: javascript css image


    【解决方案1】:

    是的,我会这样做......

    window.onload = function () {
      var imageSrc = document
        .getElementById('hello')
        .style.backgroundImage.replace(/url\((['"])?(.*?)\1\)/gi, '$2')
        .split(',')[0];
    
      // I just broke it up on newlines for readability
    
      var image = new Image();
      image.src = imageSrc;
    
      image.onload = function () {
        var width = image.width,
          height = image.height;
        alert('width =' + width + ', height = ' + height);
      };
    };
    

    一些笔记...

    • 我们需要删除 JavaScript 返回的url() 部分以获取正确的图像源。我们需要在, 上拆分,以防元素有多个背景图片。
    • 我们创建一个新的Image 对象并将其src 设置为新图像。
    • 然后我们可以读取宽度和高度。

    jQuery 可能不会那么令人头疼。

    【讨论】:

    • 这里发布的代码和JSbin上的代码不同。你的正则表达式替换有一个错误。这里更正确的版本.replace(/url\(['"]?(.*)['"]?\)/gi, '$1')
    • 由于split,这不处理数据url。我删除了拆分,因为我只使用了一个背景,否则需要使用额外的 if 语句来检查 data: 的存在。
    • document.getElementById('hello').attributes.src.value 为我工作
    • @ZacharyRyanSmith 我刚刚尝试使用背景图像,它似乎没有在attributes 上定义src 属性。您确定这是背景图片,而不是普通的 img 元素吗?
    • 您应该在image.onload 处理程序中设置宽度和高度;如果您不这样做,如果您的互联网连接速度较慢或图像很大,则宽度/高度可以为 0。
    【解决方案2】:

    无法在答案下发表评论,所以这里是包含 background-size 的 jQuery 版本(发布是因为这个问题是谷歌搜索中的第一个问题,可能对我以外的其他人有用):

    function getBackgroundSize(selector, callback) {
      var img = new Image(),
          // here we will place image's width and height
          width, height,
          // here we get the size of the background and split it to array
          backgroundSize = $(selector).css('background-size').split(' ');
    
      // checking if width was set to pixel value
      if (/px/.test(backgroundSize[0])) width = parseInt(backgroundSize[0]);
      // checking if width was set to percent value
      if (/%/.test(backgroundSize[0])) width = $(selector).parent().width() * (parseInt(backgroundSize[0]) / 100);
      // checking if height was set to pixel value
      if (/px/.test(backgroundSize[1])) height = parseInt(backgroundSize[1]);
      // checking if height was set to percent value
      if (/%/.test(backgroundSize[1])) height = $(selector).parent().height() * (parseInt(backgroundSize[0]) / 100);
    
      img.onload = function () {
        // check if width was set earlier, if not then set it now
        if (typeof width == 'undefined') width = this.width;
        // do the same with height
        if (typeof height == 'undefined') height = this.height;
        // call the callback
        callback({ width: width, height: height });
      }
      // extract image source from css using one, simple regex
      // src should be set AFTER onload handler
      img.src = $(selector).css('background-image').replace(/url\(['"]*(.*?)['"]*\)/g, '$1');
    }
    

    或作为 jQuery 插件:

    (function ($) {
    // for better performance, define regexes once, before the code
    var pxRegex = /px/, percentRegex = /%/, urlRegex = /url\(['"]*(.*?)['"]*\)/g;
    $.fn.getBackgroundSize = function (callback) {
      var img = new Image(), width, height, backgroundSize = this.css('background-size').split(' ');
    
      if (pxRegex.test(backgroundSize[0])) width = parseInt(backgroundSize[0]);
      if (percentRegex.test(backgroundSize[0])) width = this.parent().width() * (parseInt(backgroundSize[0]) / 100);
      if (pxRegex.test(backgroundSize[1])) height = parseInt(backgroundSize[1]);
      if (percentRegex.test(backgroundSize[1])) height = this.parent().height() * (parseInt(backgroundSize[0]) / 100);
      // additional performance boost, if width and height was set just call the callback and return
      if ((typeof width != 'undefined') && (typeof height != 'undefined')) {
        callback({ width: width, height: height });
        return this;
      }
      img.onload = function () {
        if (typeof width == 'undefined') width = this.width;
        if (typeof height == 'undefined') height = this.height;
        callback({ width: width, height: height });
      }
      img.src = this.css('background-image').replace(urlRegex, '$1');
      return this;
    }
    })(jQuery);
    

    【讨论】:

    • 可爱! jQuery 插件非常适合我。大家,这个函数给出了缩放后的图像大小。非常感谢!
    • 哎呀!抱歉,它给出了 unscaled 图像大小。但我还是喜欢它!
    • 该正则表达式中存在潜在错误。这是正确的:urlRegex = /url\(['"]*(.*?)['"]*\)/g
    • @neochief 谢谢,已修复,完全忘了有人可以在url() 中使用"
    • 你不能解释一下如何使用它吗?或者举个例子。功能和插件。谢谢。
    【解决方案3】:
    var actualImage = new Image();
    actualImage.src = $('YOUR SELECTOR HERE').css('background-image').replace(/"/g,"").replace(/url\(|\)$/ig, "");
    
    actualImage.onload = function() {
        width = this.width;
        height = this.height;
    }
    

    【讨论】:

    • 如果背景图片被缩放了,你想得到缩放后的宽高值怎么办?
    【解决方案4】:
    var dimension, image;
    
    image = new Image();
    image.src = {url/data}
    image.onload = function() {
        dimension = {
            width: image.naturalWidth,
            height: image.naturalHeight
        };
        console.log(dimension); // Actual image dimension
    };
    

    【讨论】:

    • 尽管这个问题和这个答案有多老,但这对我有用。我还编辑了答案以修复语法问题,并在设置 image.src 变量时使用了 Killah 有用的正则表达式。
    • 使用“naturalWidth”和“naturalHeight”就像一个魅力
    【解决方案5】:

    在 jQuery 中:

    var actualImage = new Image();
    actualImage.src = $('YOUR SELECTOR HERE').css('background-image').replace(/"/g,"").replace(/url\(|\)$/ig, "");
    
    actualImage.width // The actual image width
    actualImage.height // The actual image height
    

    感谢alex的甜蜜正则表达式。

    【讨论】:

    • 除非这在 Chrome 中不起作用。 FF 似乎加载了图像,但 Chrome 没有。所以actualImage的width和height属性总是0。
    【解决方案6】:

    如果你使用 React,你可以创建一个自定义钩子:

    import { useEffect, useState, useCallback, useRef } from 'react'
    
    const urlRgx = /url\((['"])?(.+?)\1\)/
    const getImagePromise = src =>
      new Promise(resolve => {
        const img = new Image()
    
        img.onload = () =>
          resolve({
            src,
            width: img.naturalWidth,
            height: img.naturalHeight
          })
        img.src = src
      })
    const useBackgroundImageSize = (asCallbackFlagOrUrls = false) => {
      const ref = useRef()
      const [images, setImages] = useState(null)
      const callback = useCallback(async () => {
        if (Array.isArray(asCallbackFlagOrUrls)) {
          const imgPromises = asCallbackFlagOrUrls.map(getImagePromise)
          const imgs = await Promise.all(imgPromises)
    
          if (ref?.current) {
            setImages(imgs)
          }
        }
    
        if (typeof asCallbackFlagOrUrls === 'string') {
          const image = await getImagePromise(asCallbackFlagOrUrls)
    
          if (ref?.current) {
            setImages(image)
          }
        }
    
        if (typeof asCallbackFlagOrUrls === 'boolean') {
          if (ref.current) {
            const matches = window
              .getComputedStyle(ref.current)
              .backgroundImage.match(new RegExp(urlRgx, 'g'))
    
            if (Array.isArray(matches)) {
              const imgPromises = matches.map(match =>
                getImagePromise(match.replace(new RegExp(urlRgx), '$2'))
              )
              const imgs = await Promise.all(imgPromises)
    
              if (ref?.current) {
                setImages(imgs.length > 1 ? imgs : imgs[0])
              }
            }
          }
        }
      }, [ref, asCallbackFlagOrUrls])
    
      useEffect(() => {
        if (asCallbackFlagOrUrls !== true) {
          callback()
        }
      }, [asCallbackFlagOrUrls, callback])
    
      return asCallbackFlagOrUrls === true ? [ref, images, callback] : [ref, images]
    }
    
    export { useBackgroundImageSize }
    

    然后像这样使用它:

    const App = () => {
      const [ref, image] = useBackgroundImageSize()
    
      console.log(image) // { width, height, src }
    
      return <div ref={ref} image={image} />
    }
    

    您也可以安装background-image-size-hook 并将其用作依赖项。有关更多使用详情,请参阅README

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-22
      • 1970-01-01
      • 2010-11-23
      • 1970-01-01
      • 2019-08-18
      • 1970-01-01
      • 1970-01-01
      • 2015-09-09
      相关资源
      最近更新 更多