在JS中将vh单位转换为px

10

很不幸,100vh并不总是等同于浏览器高度的100%,如下例所示。

html,
body {
    height: 100%;
}

body {
    overflow: scroll;
}

.vh {
    background-color: blue;
    float: left;
    height: 50vh;
    width: 100px;
}

.pc {
    background-color: green;
    float: left;
    height: 50%;
    width: 100px;
}
<div class="vh"></div>
<div class="pc"></div>

在 iPhone 6+ 上,上方的位置栏和下方的导航栏会扩张和收缩,但这些部分不包括在滚动时的 100vh 计算中,这一问题更加明显。

在 JS 中,可以使用 window.innerHeight 获取 100% 的实际高度值。

是否有一种方便的方式以计算当前 100vh 转换为像素值的 JS 方法?

我试图避免需要生成带有内联样式的虚拟元素来计算 100vh

对于本问题,假设存在一个敌对环境,其中可能存在 max-widthmax-height 产生不正确的值,并且页面上没有任何具有 100vh 的现有元素。基本上,假设任何可能出错的情况都已经发生,除了原生浏览器函数,这些函数保证是干净的。

目前我能想到的最好方法是:

function vh() {
    var div,
        h;
    div = document.createElement('div');
    div.style.height = '100vh';
    div.style.maxHeight = 'none';
    div.style.boxSizing = 'content-box';
    document.body.appendChild(div);
    h = div.clientHeight;
    document.body.removeChild(div);
    return h;
}

但是对于计算100vh的当前值来说,它似乎过于冗长,而且我不确定它是否存在其他问题。


你为什么需要获取100vh的像素等价值呢? - Charlie
2个回答

4

如何呢:

function viewportToPixels(value) {
  var parts = value.match(/([0-9\.]+)(vh|vw)/)
  var q = Number(parts[1])
  var side = window[['innerHeight', 'innerWidth'][['vh', 'vw'].indexOf(parts[2])]]
  return side * (q/100)
}

使用方法:

viewportToPixels('100vh') // window.innerHeight
viewportToPixels('50vw') // window.innerWidth / 2

2
错误,iOS上的innerHeight不是100vh http://output.jsbin.com/diwoyevive/quiet - yckart
1
@yckart,你说得没错,但解决这个问题可能会很有用:https://medium.com/@susiekim9/how-to-compensate-for-the-ios-viewport-unit-bug-46e78d54af0d;因此,用`innerHeight`替换`100vh`是react-div-100vh组件使用的解决方案。 - Marcel Falliere

0

这个差异来自于滚动条。

您需要将滚动条的高度添加到window.innerHeight中。似乎没有一种非常可靠的方法来实现这一点,可以参考这个问题:

使用JavaScript获取滚动条宽度


除了滚动条之外,还有许多其他浏览器功能会导致100vh与100%高度有很大的差异。 - zzzzBov
还有什么? - Charlie
我在问题中涵盖了一些内容,特别是iPhone的位置和导航栏,它们使100%的高度变小,但不影响100vh。 - zzzzBov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接