it-swarm.com.ru

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

Примечание: Ok, когда я печатал этот вопрос, я наткнулся на это вопрос, который предлагает использовать @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? */
}
48
Mr. Alien

Обновление 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, который продолжает обновляться.

Update: Обновлен код для работы со многими браузерами. Локально тестируйте, если вы используете что-то кроме Chrome, потому что jsBin немного странно работает с window.resize.

Обновление 2: Расширить собственный метод css.

Update 3: Обрабатывать событие window.resize внутри плагина, чтобы интеграция теперь была бесшовной.

The Gist (для локального тестирования):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'
});

15
elclanrs

Я сталкиваюсь с этой проблемой при использовании стандартного браузера 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/

14
Alexandru Bangală

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

7
Konrad G

Vminpoly единственный полифилл, о котором я знаю, - он находится в стадии разработки, но работает с этого поста. Есть статические полифилы как часть проектов Jquery Columns и -prefix-free .

4
RobW

Я только что сделал очень уродливый, но отлично работающий обходной путь для этого WITH PURE 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', но относятся к объявлению font-size элемента ROOT (в большинстве случаев, тег HTML).

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

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

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

2
k0m0r

«jquery.columns» - это пока лучшие решения.

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

Вам нужно всего 2 строки кодов, чтобы превратить «vh» в «масштаб для всех браузеров».

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

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

Тогда в JavaScript:

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

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

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

0
João Cunha

Самое простое и изящное решение, которое я нашел, - просто создать div с высотой: 1vh; и ширина: 1vw; и когда страница загружается, возьмите эти значения в виде пикселей с помощью getBoundingClientRect (). затем добавьте слушателя к документу, чтобы прослушать изменение размера экрана и обновить размер при изменении размера экрана.

Я сохраняю значение в пикселях vh и vw, а затем всякий раз, когда мне нужно использовать vh, я просто говорю 100 * vh, что дает мне 100vh.

Вот фрагмент кода для его реализации, мой ответ в Vanilla 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>

0
Chance