【问题标题】:Get final size of background image获取背景图像的最终尺寸
【发布时间】:2015-05-02 07:11:32
【问题描述】:

即使应用了background-size 属性,是否有一种简单的方法可以使用 Javascript 或 jQuery 获取背景图像的最终高度和宽度?

我的意思是,我知道我可以获取背景图片 url 并将其加载到 Image 对象,然后获取宽度和高度。但它是源图像的大小。如果有人用 CSS 缩放它,那么大小就会改变

我怎样才能找到它的最终尺寸?

@编辑

它与标记为相似的问题不同,因为它没有说明如果有人更改了background-size,如何以像素为单位获取大小

【问题讨论】:

  • 这不适合你吗? document.getElementById("myImage").style.offsetHeight; document.getElementById("myImage").style.offsetWidth;
  • 这将返回元素的大小,而不是背景图像的大小,并且样式中没有属性offsetHeightoffsetWidth。它的高度和宽度。如果我没有误会,只有在您之前通过 css 应用它们时才会返回它们。 offsetWidth 和 offsetHeight 返回元素大小,而不是背景图片的
  • 我唯一能想到的就是读取$("img").css("background-size") 属性并解析它。只能是cover // Element widthcontain // largest image dimension 或静态值(px、em 或 %)。
  • 我想我得计算一下。检查它是否是 % 并将百分比应用于元素大小,如果它是包含或覆盖,检查哪个维度更小或更大,并祈祷'em','rem''vh'等,如果应用(我不是确定是不是),会自动转换为像素(注意css中有些东西是转换的,比如background-position,如果你用'em'至少chrome把它转换成像素)

标签: javascript jquery css background-image background-size


【解决方案1】:

使用getComputedStyle,我创建了这个脚本,它返回给定元素背景的宽度和高度,以像素为单位。它适用于:

  • 尺寸(宽度或高度)设置为auto,无论是明确地还是因为没有给出特定值(宽度和高度默认为auto
  • 尺寸设置为百分比%
  • 尺寸设置为像素px
  • 维度设置为之前的任意组合。 (width: 100px; height: autowidth: auto; height: 32.4%height: 100px; width: 2%width: 21.2%
  • background-size 设置为covercontain

如果background-size 设置为外部 CSS 文件内联 CSS内联标题 CSS如果根本没有设置(意思是宽高是auto)。

这是一个 JsFiddle(带有封面示例)

http://jsfiddle.net/gp4e9d3z/3/

这是 StackOverflow 的代码 sn-p(带有 percentage auto 单位)

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]
    };
}

// Stuff for debugging

function updateData() {
    var background = getBackgroundSize(document.body);
    document.getElementById('width').innerHTML = background.width + 'px';
    document.getElementById('height').innerHTML = background.height + 'px';
    document.getElementById('winWidth').innerHTML = getComputedStyle(document.body).width;
    document.getElementById('winHeight').innerHTML = getComputedStyle(document.body).height;
}
// Execute onload, so that the background image is already loaded.
window.onload = window.onresize = updateData;
html, body {
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
}
body {
    background: url('http://hdwallpapersfit.com/wp-content/uploads/2015/03/images-7.jpg');
    background-size: 80% auto;
}
div {
    background: rgba(0, 0, 0, 0.5);
    color: #fff;
}
<div id="data">
    Background width: <span id="width"></span>
    <br>
    Background height: <span id="height"></span>
    <hr>
    Body width: <span id="winWidth"></span>
    <br>
    Body height: <span id="winHeight"></span>
</div>

【讨论】:

  • 绝对数量和细节必须加一。
  • 无话可说。完美。
【解决方案2】:

使用 JSFiddle Here,我发现更改容器的高度或宽度会强制将图像缩放到最大的高度或宽度。这意味着背景的一个边缘的测量值将等于容器的尺寸之一。使用这个和一些比例,我们可以计算出图像的尺寸。

// let .container  represent element containing the image
var image; // the image object to the background image
var dim_h, dim_w; // the height and width of the actual image


height = $(".container").height();
width = $(".container").width();

if (height >= width)
{
  dim_h = height;
  dim_w = (height / image.height) * image.width;
}
else
{
  dim_w = width;
  dim_h = (width / image.width) * image.height;
}

// dim_w and dim_h contain the width and height of the actual 
// background image after scaling

上面的代码使用下面的比例来计算。

(element_height / image_height) == (element_width / image_width)

我认为它应该会给你想要的答案。

【讨论】:

  • 我想要背景图片
  • 背景图片的大小不就是其中包含的元素的大小吗?
  • 如果我使用background-size: cover 会怎样?不会改变背景图片的大小吗?
  • 根据 w3c 网站here。据我了解,如果您使用cover,则背景会缩放以适合元素的背景区域,因此它应该等于包含它的元素的大小。
  • @MigaraLiyanagamage 不相关但要小心,w3school 不是 w3c
猜你喜欢
  • 1970-01-01
  • 2011-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-23
  • 1970-01-01
相关资源
最近更新 更多