使用 JavaScript 获取 CSS 背景图像的大小?

Posted

技术标签:

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

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

【问题讨论】:

【参考方案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。

【讨论】:

以上是关于使用 JavaScript 获取 CSS 背景图像的大小?的主要内容,如果未能解决你的问题,请参考以下文章

javascript,获取使用包含属性缩放的背景大小

获取背景图像位置(x y和单位)

css 超简单的jQuery背景图像随机幻灯片(使用CSS3进行转换,并通过HTML5`data`属性获取图像路径)。

如何使用javascript从dom中获取点击位置的图片网址?

css 动态背景 - 将Javascript放在页脚和CSS中。确保所有图像文件都以Photoshop文档中的名称命名

css 动态背景 - 将Javascript放在页脚和CSS中。确保所有图像文件都以Photoshop文档中的名称命名