Есть ли какой-либо кросс-браузерный javascript для работы модулей vh и vw

Примечание: Хорошо, когда я печатал этот вопрос, я столкнулся с этимвопрос, который предлагает использовать @media query, но был запрошен в 2011...

Как вы знаете, CSS3 вводит новые единицы измерения длины в разрезе Viewport, vh и vw, которые, по моему мнению, действительно полезны для твердый отзывчивый макет, так что мой вопрос в том, есть ли альтернатива JavaScript/jQuery для этого? Более того, помимо использования его для размеров шрифтов, безопасно ли использовать его для определения размеров? Пример

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

Ответ 1

Обновление 5:.css(свойство) fix Плагины типа 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: Расширение метода native 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'
});

Ответ 2

Я столкнулся с этой проблемой с браузером Android 4.3 (не поддерживает vw, vh и т.д.). Способ, которым я решил это, - использовать "rem" в качестве единицы размера шрифта и динамически изменять <html> font-size с 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/

Ответ 3

Я написал небольшую помощницу для решения этой проблемы. Он поддерживается во всех основных браузерах и использует 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/

Ответ 4

Vminpoly - это единственный polyfill, который я знаю - он разрабатывается, но работает на этом посту. Существуют статические полисы как часть столбцов Jquery Columns и - prefix-free.

Ответ 5

Я только что сделал очень уродливое, но отлично работающее обходное решение для этого С ЧИСТЫМ CSS (не нужно JS). Я столкнулся с таблицей стилей CSS, полной деклараций "vw" (также для высот и свойств top/bottom), которые необходимо было переписать для собственного Android-браузера (который в версиях 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).

Таким образом, самый простой способ сделать эту работу - объявить размер шрифта для тега html, равный 1% ширины видового экрана, например. 19.2px для просмотра 1920px и использовать множество медиа-запросов для всего диапазона 1920-320px. Таким образом, я сделал единицу "rem" равной "vw" во всех разрешениях (шаг 10px, но вы даже можете попробовать объявить html {font-size} для каждого 1px). Затем я просто заменил "vw" на "rem" и восхищался рабочим макетом в собственном браузере Android 4.3.

Кроме того, вы можете повторно обновить размер шрифта даже для всего тега тела (в любых единицах, которые вы хотите: px, em, pt и т.д.), и это НЕ влияет на равенство "rem" на "vw" в вся таблица стилей.

Надеюсь, это поможет. Я знаю, что это выглядит глупо, но работает как шарм. Помните: если что-то выглядит глупо, но работает, это не глупо:)

Ответ 6

"jquery.columns" пока является лучшим решением.

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

Вам нужно всего две строки кодов, чтобы превратить "vh" в "вс-браузерную шкалу".

Объявить класс в html:

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

Затем в javascript:

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

Ответ 7

Я опубликовал крошечную библиотеку, которая упрощает использование относительных размеров видовых экранов. Имейте в виду, что это не polyfill, поэтому вам необходимо применить классы к элементам, которые вы хотите изменить. Например, <div class="vh10 vw30">hello</div> будет заполнять 10% высоты и 30% от ширины.

Проверьте это: https://github.com/joaocunha/v-unit