2012-12-19 35 views
48

注:好,而我打字这个问题我碰到this 问题这表明使用@media query但被要求回到 2011来了......是否有任何跨浏览器的JavaScript制作VH和VW单位工作

正如你所知道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? */ 
} 
+0

我能找到的最接近的是'rem'单元的填充 - https://github.com/chuckcarpenter/REM-unit-polyfill 。我找不到'vh' /'vw',但考虑到'rem'的存在,我会想象它是可能的。 – SDC

+0

这个也可能有助于查找 - https://github.com/heygrady/Units - 我看到它在文档中提到了'vh' /'vw'单元。我不认为这是你想要的直接polyfill。 – SDC

+3

这是一个由19.2k编辑的10.9k问题,由15.4k .. aaaaah回答 – Ben

回答

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' 
 
});

+0

这对铬22,但在17.0.1 :)失败,但不错的尝试+1 ...想要一个跨浏览器,雅我可以离开IE7,8肯定..但至少ff,铬,歌剧(不会工作,很好),ie9/10 –

+0

@ Mr.Alien:这是线路'prop = viewportToPixel(道具)'的问题。我改成了'prop [p] = viewportToPixel(prop)',现在在所有浏览器中都可以正常工作。测试一下! http://jsbin.com/ugefub/1/edit#javascript – elclanrs

+0

@ Mr.Alien:另外,jsBin在Chrome浏览器以外的所有浏览器中都会用'window.resize'搞怪。在本地尝试,在FF,Opera和Chrome AFAIK中可以正常工作。这是一个主旨https://gist.github.com/4341016 – elclanrs

4

Vminpoly是我所知道的唯一填充工具 - 这是在农业开发,但可以作为这一职位的。作为Jquery Columns-prefix-free项目的一部分,还有静态多边填充。

+3

哈哈。 jQuery专栏是从这个问题诞生的。 – elclanrs

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/

+0

很简单,几乎可以工作! :) 谢谢! – Anze

+4

关于'rem's,有一些Android版本(不记得是哪一个)有最小的字体大小(在我的例子中是8px)。因此,如果您的根字体大小最终小于8像素,则会自动舍入为8像素,并有可能破坏您的布局。 – rachel

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

为什么要处理attachEvent和addEventListener并导入jQuery? – rlemon

+0

这是一个小错误,与正确的代码行为无关。如果代码运行良好并易于使用,我不会看到投票的理由:/我已经解决了我的问题。 –

+1

我没有倒下,我只是问。它自己处理这些情况看起来很愚蠢,然后在其他地方使用jQuery。 – rlemon

0

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

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

+0

只有这个问题,它不支持字体大小,边框,填充等。 – foreyez

+0

是的,有一个问题打开添加它:https://github.com/joaocunha/v-unit/issues/7 –

1

“jquery.columns” 是迄今为止最好的解决方案。

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

你只需要2行代码把“VH”变成了“全浏览器规模”。在JavaScript

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

然后:

在HTML声明一个类

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

如何这项工作如果'vw'和'vh'不被支持? Javascript css内部是否设置了“50vw”以外的其他内容?如果没有,你只需在一个不受支持的单元中设置一个值,我不会看到这个工作。 – Zelphir

+0

是的,它也适用于较旧的IE。 jquery.columns覆盖jquery的css()函数,并在声明期间将'vw'转换为像素。 – stonyau

2

我刚刚作出了一个非常难看,但完全工作的办法解决这个纯CSS(没有JS需要)。 我遇到了一个CSS样式表,其中包含了需要为本机Android浏览器重写的'vw'声明(也适用于高度和顶部/底部属性)(它在4.3及以下版本中不支持'vw'单元)。

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

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

因此,最简单的工作方式是声明等于视口宽度1%的html标记的字体大小,例如, 19.2px为1920px视口,并使用大量的媒体查询整个1920-320px范围。通过这种方式,我在所有分辨率下将'rem'单位设置为'vw'(步长为10px,但您甚至可以尝试每隔1px宣布html {font-size})。然后我用“rem”批量替换'vw',并欣赏Android 4.3本地浏览器的工作布局。你可以重新声明字体大小,即使是整个身体标记(无论你想要的单位:px,em,pt等),它都不会影响'rem'等于'vw'在整个样式表中。

希望这会有所帮助。我知道它看起来有点傻,但像魅力一样。请记住:如果有些东西看起来很蠢,但起作用,它并不愚蠢:)

+2

您可以再次上传vw2rem样式表吗?链接找不到。谢谢。 – lowtechsun

相关问题