是否有任何跨浏览器的JavaScript用于使vh和vw单元工作

时间:2012-12-19 09:01:05

标签: javascript jquery css css3

  

注意:在我输入此问题时,我遇到了this   问题建议使用@media query,但被问到   2011 ...

如您所知,CSS3引入了新的Viewport-percentage length unitsvhvw,我认为这对于可靠的响应式布局非常有用,所以我的问题是,是否有任何JavaScript / jQuery替代方案?除了将它用于字体大小之外,是否可以安全地使用尺寸元素?像例子

div {
   height: 6vh;
   width: 20vh;  /* Note am using vh for both, do I need to use vw for width here? */
}

8 个答案:

答案 0 :(得分:15)

更新5: .css(属性)修复 像fancyBox这样的插件使用.css('margin-right')来获取元素的右边距,使用.css('margin-right', '12px')来设置元素的右边距。这被打破了,因为没有检查props是否是一个字符串,并且是否有多个参数给出。通过检查props是否为字符串来修复它。如果是,并且有多个参数,则将参数重写为对象,否则不使用parseProps( $.extend( {}, props ) )

更新4:响应式布局的插件https://github.com/elclanrs/jquery.columns(正在进行中)

我给了这个(长期)尝试。首先是CSS示例:http://jsbin.com/orajac/1/edit#css。 (调整输出面板的大小)。请注意,font-size不适用于视口单元,至少在最新的Chrome上是如此。

这是我尝试用jQuery做的事情。与字体一起使用的jQuery演示版位于http://jsbin.com/izosuy/1/edit#javascript。没有广泛测试它,但它似乎适用于大多数属性,因为它只是将值转换为像素,然后通过调用window.resize上的插件不断更新。

更新:更新了可与多种浏览器配合使用的代码。如果您使用的是Chrome以外的任何内容,请在本地进行测试,因为jsBin对window.resize的行为有点奇怪。

更新2:扩展原生css方法。

更新3:处理插件内部的window.resize事件,以便现在无缝集成。

要点(在本地测试): https://gist.github.com/4341016

/*
 * CSS viewport units with jQuery
 * http://www.w3.org/TR/css3-values/#viewport-relative-lengths
 */
;(function( $, window ){

  var $win = $(window)
    , _css = $.fn.css;

  function viewportToPixel( val ) {
    var percent = val.match(/[\d.]+/)[0] / 100
      , unit = val.match(/[vwh]+/)[0];
    return (unit == 'vh' ? $win.height() : $win.width()) * percent +'px';
  }

  function parseProps( props ) {
    var p, prop;
    for ( p in props ) {
      prop = props[ p ];
      if ( /[vwh]$/.test( prop ) ) {
        props[ p ] = viewportToPixel( prop );
      }
    }
    return props;
  }

  $.fn.css = function( props ) {
    var self = this
      , originalArguments = arguments
      , update = function() {
          if ( typeof props === 'string' || props instanceof String ) {
            if (originalArguments.length > 1) {
              var argumentsObject = {};
              argumentsObject[originalArguments[0]] = originalArguments[1];
              return _css.call(self, parseProps($.extend({}, argumentsObject)));
            } else {
              return _css.call( self, props );
            }
          } else {
            return _css.call( self, parseProps( $.extend( {}, props ) ) );
          }
        };
    $win.resize( update ).resize();
    return update();
  };

}( jQuery, window ));

// Usage:
$('div').css({
  height: '50vh',
  width: '50vw',
  marginTop: '25vh',
  marginLeft: '25vw',
  fontSize: '10vw'
});

答案 1 :(得分:14)

我在Android 4.3股票浏览器中遇到此问题(不支持vw,vh等)。 我解决这个问题的方法是使用'rem'作为字体大小的单位并动态地改变< html>使用javascript的字体大小

function viewport() {
    var e = window, a = 'inner';
    if (!('innerWidth' in window )) {
        a = 'client';
        e = document.documentElement || document.body;
    }
    return { width : e[ a+'Width' ] , height : e[ a+'Height' ] };
}
jQuery(window).resize(function(){
    var vw = (viewport().width/100);
    jQuery('html').css({
        'font-size' : vw + 'px'
    });
});

在您的CSS中,您可以使用'rem'代替px,ems等

.element {
    font-size: 2.5rem; /* this is equivalent to 2.5vw */
}

以下是代码的演示:http://jsfiddle.net/4ut3e/

答案 2 :(得分:7)

我写了小助手来处理这个问题。它在所有主流浏览器上都受支持并使用jQuery 这是:

SupportVhVw.js

function SupportVhVw() {

    this.setVh = function(name, vh) {

        jQuery(window).resize( function(event) {
            scaleVh(name, vh);
        });

        scaleVh(name, vh);
    }

    this.setVw = function(name, vw) {

        jQuery(window).resize( function(event) {
            scaleVw(name, vw);
        });

        scaleVw(name, vw);
    }

    var scaleVw = function(name, vw) {

        var scrWidth = jQuery(document).width();
        var px = (scrWidth * vw) / 100;
        var fontSize = jQuery(name).css('font-size', px + "px");
    }


    var scaleVh = function(name, vh) {

        var scrHeight = jQuery(document).height();

        var px = (scrHeight * vh) / 100;
        var fontSize = jQuery(name).css('font-size', px + "px");
    }
};

如何在HTML中使用它的简单示例:

<head>

    <title>Example</title>

    <!-- Import all libraries -->
    <script type="text/javascript" src="js/libs/jquery-1.10.2.min.js"></script>
    <script type="text/javascript" src="js/libs/SupportVhVw.js"></script>

</head>
<body>

                    <div id="textOne">Example text one (vh5)</div>
                    <div id="textTwo">Example text two (vw3)</div>
                    <div id="textThree" class="textMain">Example text three (vh4)</div>
                    <div id="textFour" class="textMain">Example text four (vh4)</div>

            <script type="text/javascript">

                    // Init object
                    var supportVhVw = new SupportVhVw();

                    // Scale all texts
                    supportVhVw.setVh("#textOne", 5);
                    supportVhVw.setVw("#textTwo", 3);
                    supportVhVw.setVh(".textMain", 4);

            </script>

</body>

可在GitHub上找到:
https://github.com/kgadzinowski/Support-Css-Vh-Vw

JSFiddle上的示例: http://jsfiddle.net/5MMWJ/2/

答案 3 :(得分:4)

Vminpoly是我所知道的唯一的polyfill - 它在发展之下但是在这篇文章中起作用。静态polyfill也是Jquery Columns-prefix-free项目的一部分。

答案 4 :(得分:2)

我为这个WITH PURE CSS做了一个非常丑陋但完美的工作方法(不需要JS)。 我遇到了一个充满&#39; vw&#39;的CSS样式表。需要为原生Android浏览器重写的声明(也适用于高度和顶部/底部属性)(版本4.3及以下版本不支持&#39; vw&#39;单位)。

而不是将所有内容重写为百分比,而不是相对于父亲的宽度(所以DOM中的深度,最复杂的计算),这会让我头疼甚至在我达到第一个{height:Xvw之前声明,我自己生成了以下样式表: http://splendige.pl/vw2rem.css

我猜你们都熟悉&#39; em&#39;单位(如果不是:http://www.w3schools.com/cssref/css_units.asp)。经过一些测试后,我发现旧的Android浏览器(以及其他所有浏览器)完全支持“#re; rem”。单位,与&#39; em&#39;相同,但相对于ROOT元素字体大小声明(在大多数情况下,是html标记)。

因此,最简单的方法是声明html标签的字体大小等于视口宽度的1%,例如: 19.2px用于1920px视口,并在整个1920-320px范围内使用大量媒体查询。通过这种方式,我制作了&#39; rem&#39;单位等于&#39; vw&#39;在所有分辨率中(步长为10px,但你甚至可以尝试为每1px声明html {font-size})。然后我只是批量替换&#39; vw&#39;与&#39; rem&#39;并欣赏Android 4.3原生浏览器的工作布局。

更重要的是,您可以重新声明字体大小,甚至是整个身体标签(以您想要的任何单位:px,em,pt等),它不会影响&#39; rem&#39;平等到&#39;&#39;在整个样式表中。

希望这会有所帮助。我知道它看起来有点傻,但就像一个魅力。记住:如果某些东西看起来很愚蠢,但有效,那就不愚蠢了:)

答案 5 :(得分:1)

&#34; jquery.columns&#34;是迄今为止最好的解决方案。

https://github.com/elclanrs/jquery.columns

您只需要2行代码即可转换&#34; vh&#34;进入&#34;全浏览器规模&#34;。

在html中声明一个类:

<img src="example.jpg" class="width50vh" />

然后在javascript:

$('.width50vh').css({width: '50vw'});

答案 6 :(得分:0)

我发布了一个很小的库,可以简化视口相对尺寸的使用。请记住,它不是polyfill,因此它要求您在要调整大小的元素上应用类。例如,<div class="vh10 vw30">hello</div>将填充10%的高度和30%的宽度。

检查出来:https://github.com/joaocunha/v-unit

答案 7 :(得分:0)

我发现的最简单,最优雅的解决方案是简单地创建一个高度为1vh的div;宽度:1vw;当页面加载时,使用getBoundingClientRect()将这些值捕获为像素。然后在文档中添加一个侦听器,以侦听屏幕大小调整并在调整屏幕大小时更新大小。

我将值保存为vh和vw的像素,然后每当我需要使用vh时,我只会说100 * vh,这将给我100vh。

这里是实现的代码段,我的回答是在普通js中,不需要jquery。

function getViewportUnits(){
  const placeholder = document.getElementById("placeholder");
  const vh = placeholder.getBoundingClientRect().height;
  const vw = placeholder.getBoundingClientRect().width;
  console.log({vh: vh, vw: vw});
}
#placeholder{
  background: red;
  height: 1vh;
  width: 1vw;
}
<body onload="getViewportUnits()">
<div id="placeholder"></div>