【问题标题】:Retrieve computed value from background-size:cover/contain从背景大小检索计算值:覆盖/包含
【发布时间】:2014-10-18 23:48:51
【问题描述】:

使用background-size:cover 用 400x200 背景图像覆盖浏览器的视口:

html, body {height:100%;}
body {background:url("http://lorempixel.com/g/400/200/") center no-repeat; background-size:cover;}

我想通过 javascript 检索应用于图片的计算 background-size 值,例如 1536px 768px

现场演示:http://s.codepen.io/abernier/fullpage/rHkEv

NB:我只想阅读它,没有时间计算它(因为浏览器已经在某种程度上)

【问题讨论】:

  • 嗯,这是一个聪明的问题,恐怕没有办法做你想要达到的目标!为潜力点赞。
  • 我认为没有 API 可以检索该因素。
  • 我认为他已经知道如何计算它,但很想知道是否有可能获得浏览器计算的数字。
  • 顺便说一句:我认为没有办法达到这个数字。
  • 我知道你可以使用window.devicePixelRatio 来获取屏幕本身的像素比,我想知道特定DOM元素是否存在类似的东西?

标签: javascript css


【解决方案1】:

我知道我参加聚会很晚了,但我已经使用下面的代码来解决这个问题。

    var backgroundImage = new Image();
    backgroundImage.src = $('my_div_id').css('background-image').replace(/"/g,"").replace(/url\(|\)$/ig, "");

    backgroundImage.onload = function() {
        var width = this.width;
        var height = this.height;

        var object = $('#my_div_id');

        /* Step 1 - Get the ratio of the div + the image */
        var imageRatio = width/height;
        var coverRatio = object.outerWidth()/object.outerHeight();

        /* Step 2 - Work out which ratio is greater */
        if (imageRatio >= coverRatio) {
            /* The Height is our constant */
            var coverHeight = object.outerHeight();
            var scale = (coverHeight / height);
            var coverWidth = width * scale;
        } else {
            /* The Width is our constant */
            var coverWidth = object.outerWidth();
            var scale = (coverWidth / width);
            var coverHeight = height * scale;
        }
        var cover = coverWidth + 'px ' + coverHeight + 'px';
        alert('scale: ' + scale + ', width: ' + coverWidth + ', height: ' + coverHeight + ', cover property: ' + cover);
    };

详细的演练可以在这里找到http://www.gene.co.uk/get-computed-dimensions-background-image-background-size-cover/

【讨论】:

  • 我投了赞成票,因为真正认为这个答案是最符合问题的答案。解决方案测试 - 运作良好。只是链接坏了,但那是次要的。
  • 直播链接 — gene.co.uk/blog/…
  • 一年多过去了,这是整个互联网上对这个问题的最佳答案。
【解决方案2】:

您可以使用 Image 对象来获取背景图像文件的尺寸,然后将其与元素的大小进行比较

var element = ...

var img = new Image()
img.onload = compare;
img.src = 'path/to/your/background-image'

function compare() {
  var fx = element.offsetWidth/img.width;
  var fy = element.offsetHeight/img.height;
  console.log(fx, fy);
}

然后根据 background-size 属性的值,您可以获得准确的比例因子

function compare() {
  var fx = element.offsetWidth/img.width;
  var fy = element.offsetHeight/img.height;

  var bs = window.getComputedStyle(element, null).backgroundSize;
  switch (bs) {
    case 'cover': console.log(Math.min(fx, fy)); break;
    case 'contain': console.log(Math.max(fx, fy)); break;
    case '100% 100%': console.log(fx, fy);
    default: console.log("Umm...");
  }
}

默认情况更复杂。由于背景大小的每个部分都可以以单位数表示,因此正确处理这些单位的代码会有点乱七八糟。

基于jQuery的fiddle

【讨论】:

    【解决方案3】:

    background-size 属性指定背景图像的大小,而不是其“缩放系数”。你能从这个属性中得到的唯一东西就是它的大小。如果存在这样的因素,它将在 another 属性 (-ies) 中。你挖错地方了。

    回答这个问题我不得不问自己另一个问题。 这个数字存在吗?

    让我们首先想象一下,它的值是 2.135(是原始值的两倍)。如果我将cover 更改为100% 100%,该号码会发生什么情况。在这种情况下,说“水平缩放系数”与cover 保持相同,而“垂直”缩放系数变化不同。你希望这个数字是多少?应该怎么改?

    一个因素可能会改变而另一个因素可能不会改变这一事实让我假设它们可能(并且应该)是单独的值(谁知道呢,可能是“-vendor-background-size-x-zoom-factor”和“ -vendor-background-size-y-zoom-factor" 两者都可能有正值和负值,并且两者都不包含在任何 css 规范中,并且都将保留在浏览器的引擎盖下,假设它们是 css 属性的形式,而不是简单的变量或谁知道什么)。

    实际上它当然可能会更复杂一些))

    【讨论】:

    • 我想说的是,即使你设法通过 javascript 解码 cover - 你会得到类似 150px 20px 的东西,这不是你想要的缩放因子。
    • 当我将cover(可以在这里看到:jsfiddle.net/skip405/AyBEN)更改为100% 100%jsfiddle.net/skip405/AyBEN/1)时,这个缩放因子的存在受到质疑。尝试比较两个图像并尝试在 second 上找到缩放因子。如果您在眼前用两个小提琴重读我的答案-可能会变得更清楚。
    • 我怀疑它是放大,@abernier,在我看来,无论我指定什么属性,浏览器都会使用相同的方法扭曲图像:)。而不是cover - 看看它的兄弟(250px 250px) - jsfiddle.net/skip405/AyBEN/2。而不是100% 100% 看看250px 150px - jsfiddle.net/skip405/AyBEN/3。你认为如果属性中的数字相等,它缩放,如果它们不相等,它扭曲?我严重怀疑。一直都是失真,IMO
    • 你是对的。为了澄清,我刚刚改述了这个问题。谢谢
    【解决方案4】:

    这还不是答案,但我正在进行测试......

    我对类似属性 background-position 进行了一个小测试,它也接受 关键字,例如 centerleft...(这意味着 %),就像 background-size 对 @ 所做的那样987654326@/contain

    让我们用沙盒化一个 div

    var div = document.createElement('div');
    div.style.cssText = "background-position:center 3%;";
    document.body.appendChild(div);
    

    现在让我们检索 center 值:

    window.getComputedStyle(div, null)
          .getPropertyCSSValue('background-position-x')
          .getFloatValue(CSSPrimitiveValue.CSS_PERCENTAGE);
    

    你猜怎么着?

    50
    

    不幸的是,

    var div = document.createElement('div');
    div.style.cssText = "background-size:cover;";
    document.body.appendChild(div);
    window.getComputedStyle(div, null)
          .getPropertyCSSValue('background-size')
          .getFloatValue(CSSPrimitiveValue.CSS_PERCENTAGE);
    

    抛出错误:

    InvalidAccessError:参数或操作不受支持 底层对象。

    【讨论】:

    • 有趣。我尝试了几件事,但看起来我们只能从中获得“封面”,关键字不会转换为实际数字。如果您尝试设置类似background-size: 10px 20px 的内容,您实际上会看到CSSValueList 带有两个单独的CSSPrimitiveValue,类型为CSS_PXcoverCSS_IDENT 类型——我希望有人告诉我它是什么。
    【解决方案5】:

    简短的回答是浏览器不提供获取背景图像比例因子的计算值的方法,但您可以根据in the spec描述的规则自行计算。

    【讨论】:

    • 很多工作。我想知道是否有人创建了规范的 JS“模拟”。
    【解决方案6】:

    您可以检查 div 和原始图像的大小,找出 div 的宽度或高度是否按比例变短,这意味着图像被拉伸到较小边的 100%。例如: 如果容器 div 是 600px X 500px 并且图像的大小是 600px X 400px 图像将调整大小以覆盖整个 div 因此它将调整大小为自动 X 500px,这意味着图像的缩放将为 500/400 = 1.25

    【讨论】:

    • OP 明确表示他们不想自己计算比例因子,而是简单地通过 API 调用检索它。 (如果存在的话。)
    • 如果您在 javascript 中使用它,这是我认为可以做到的唯一方法。
    【解决方案7】:

    没有办法做到这一点,因为它需要加载图像才能为您提供准确的值。即使该值已公开,您也必须等待window.load 事件才能检索它...此时自行计算该值会更快。

    更新:从the CSS spec 开始,背景大小在不同条件下的表现不同 - 图像是否具有固有尺寸/比率(jpeg/svg)或没有(css 渐变),两个值是否设置为“自动”(其中如果它被视为“包含”),“背景重复”值之一是否设置为“圆形”,是否有多个背景......你明白了。

    此外,背景尺寸 需要布局(随布局而变化),但不在 list of properties 中,后者是在布局后计算为实际的“使用”值。这很重要,因为getComputedStyle 返回实际的“使用”值,但“背景大小”没有经过计算值 -> 使用值的过程。

    再加上在加载图像之前您甚至无法获得值的事实......我仍然认为您自己计算它听起来是您最好的选择。

    【讨论】:

    • 不知道为什么投反对票。甚至没有人提到您必须等待图像加载的事实。这就像在图像加载之前尝试获取常规 <img /> 的宽度。你必须等待 - 没有办法。
    【解决方案8】:

    尝试:

    background-size: contain

    这将根据设备像素比率放大/缩小并适合背景大小。这里不需要 javascript 或任何计算,因为浏览器将自行执行其余任务。

    【讨论】:

      【解决方案9】:

      检查此代码:

      body{background: url('images/bg.jpg') no-repeat fixed; display: block;height: auto;max-width: 100%;}
      body{background-size:cover}
      

      注意:background-size:cover 是单独定义的

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-05-04
        • 1970-01-01
        • 2019-01-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-25
        相关资源
        最近更新 更多