Знание видового экрана, необходимое для понимания гибкого.js

JavaScript HTML CSS
Знание видового экрана, необходимое для понимания гибкого.js

область просмотра изучить интерпретацию гибкого.js

www.quirksmode.org/mob...
www.quirksmode.org/mob...
www.quirksmode.org/mob...
www.w3cplus.com/mobile...

В этой статье представлены три области просмотра окна просмотра.visual layout ideal, а принцип реализации решения Taobao flexible.js анализируется через эти три области просмотра.

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

На экране впервые представлены два понятия. "пиксель css", "пиксель устройства"

Пиксели CSS совпадают с единицами измерения ширины, определенными в таблице стилей.

Можно понять, что пиксели CSS и пиксели устройства представляют собой отношения приспособления. При коэффициенте масштабирования 200% 1 пиксель css содержит 4 пикселя устройства. .

Эффект масштабирования заключается в изменении того, сколько пикселя css может поместиться в пикселе устройства.

Сторона ПК

В обычных условиях один пиксель CSS равен одному пикселю устройства. При масштабе 200 % один пиксель CSS равен четырем пикселям устройства. (в 2 раза больше ширины и в 2 раза больше высоты)

window.innerWidth

Экраны и страницы имеют множество свойств.

  • screen.width

  • window.innerWidth

  • document.documentElement.clientWidth

  • document.documentElement.offsetwidth

  • Ждать

Единицей значения этих свойств являются пиксели. Разница в том, что некоторые из этих значений свойств измеряются в «пикселях устройства», а большинство — в «пикселях CSS».

window.innerWidth измеряет ширину окна браузера. Единицей измерения являются css пиксели.

Пример окна.innerWidth.

Это происходит при 100% увеличении. Ширина заголовка 1220px, что почти заполняет ширину экрана браузера.Значение window.innerWidth равно 1231px.По этой ситуации легко доказать, что единицей измерения window.innerWidth являются css пиксели.

Теперь увеличьте эту страницу до 200%.

Мы обнаружили, что текущая ширина window.innerWidth стала вдвое меньше, чем была только что. Это связано с тем, что единицей измерения этого свойства являются пиксели CSS (сколько пикселей CSS включено), и измеряется интуитивно понятный размер пикселей CSS, и его можно сравнить с размером CSS DOM на странице.

Глядя на нашу страницу, заголовок по-прежнему имеет размер 1220 пикселей и не изменился. Но то, что отображается в браузере, — это только половина того, что было только что. Судя интуитивно, текущее значение ширины CSS в окне браузера составляет половину от предыдущего значения. И это значение является размером текущего значения window.innerWidth.

Размер css элемента dom не изменяется численно, в то время как размер устройства в пикселях является физической величиной и не меняется, поэтому он также соответствует вышеизложенному. Масштабирование на самом деле меняет то, сколько пикселей устройства может содержать один пиксель CSS.

область просмотра, используемая для ограничения блочного элемента верхнего уровня на веб-сайте.<html>.

По умолчанию ширина "body" берется из "HTML", а ширина "HTML" берется из "viewport", а ширина "viewport" точно равна ширине окна "браузера".

«viewport» можно рассматривать как более высокий элемент, чем «html», независимо от того, установили ли мы ширину «html»,document.documentElement.clientWidthВсе полученное — это ширина «окна просмотра». а такжеwindow.innerWidthМожно получить ширину окна «Браузер». Разница между ними на стороне ПК только вwindow.innerWidthСодержит ширину полосы прокрутки.

Существует проблема с этим определением.Красный фон установлен на ширину 100%, а внутренний элемент установлен на минимальную ширину 980 пикселей.Когда экран уменьшается ниже 980, появится горизонтальная полоса прокрутки, но перемещение полосы прокрутки справа обнаружит, что фон отсутствует. Это связано с тем, что ширина 100% на самом деле является максимальной шириной окна браузера. Когда размер окна браузера меньше 980 пикселей, красный фон также уменьшится до размера менее 980 пикселей, поэтому свайп вправо будет казаться пустым.

offsetWidth

document.documentElement.offsetWidthЭто свойство получает ширину html. (Измерение в IE - это область просмотра)

Если html рассматривается как элемент блочного уровня, ширина html по умолчанию равна 100% родительского элемента, а высота по умолчанию распределяется между дочерними элементами.
Так что по умолчанию значение offsetWidth наследуется от ширины области просмотра, а ширина области просмотра равна ширине окна браузера.
Значение offsetHeight по умолчанию определяется высотой дочернего элемента.
Когда высота или ширина html указаны явно, offsetHeight/width принимает явно заданное значение.

Другая ситуация — установка html на 100%, что на самом деле означает установку высоты html на 100% от высоты области просмотра Аналогично, высота области просмотра равна высоте окна браузера. Можно получить с помощью window.innerHeight.

Резюме на стороне ПК

  1. window.innerWidthЕдиницей измерения является «CSS-пиксель», а концепция представления — это количество DOM размером с CSS-пиксель, которое содержит текущее окно браузера.

  2. По умолчанию ширина "body" берется из "HTML", а ширина "HTML" берется из "viewport", а ширина "viewport" точно равна ширине окна "браузера".

мобильный

  • layout viewport

  • visual viewport

вьюпорт компоновки и визуальный вьюпорт

Концепция окна просмотра макета на самом деле такая же, как и окно просмотра на стороне ПК.используется как «верхний» элемент html. Наследовать ширину от html. Каждый элемент в html размещается на основе области просмотра макета. Но в отличие от ПК, ширина области просмотра на ПК определяется шириной окна браузера, и пользователь может вручную перетаскивать окно, чтобы изменить ширину. Однако браузеры на разных платформах на мобильной стороне отображают разные области просмотра макета.

iOS980px, android800px.

Думайте о визуальном окне просмотра как о поле, покрывающем экран телефона.Это поле имеет функцию, аналогичную масштабированию на стороне ПК, а единицей измерения этого поля также являются пиксели CSS. Это означает, что количество пикселей CSS, которое мы можем видеть, когда область просмотра макета неизменна, зависит от того, насколько увеличено поле. по умолчанию. Большинство мобильных браузеров масштабируют поле визуального окна просмотра таким же образом, как окно просмотра макета.

Возьмем, к примеру, устройство ios, окно просмотра макета имеет фиксированное значение 980 пикселей, и когда страница открывается по умолчанию, визуальное окно просмотра масштабирует поле до 980 пикселей. Таким образом, мы можем видеть весь контент.

По умолчанию ширина элемента html берется из вьюпорта макета, поэтому макет разных типов браузеров разный, ios980px, android800px.

Таким образом, без установки каких-либо условий, div шириной 1220px выглядит так в симуляторе ios.

Ширина html наследуется от окна просмотра макета, 980px. Дополнительные 240 пикселей находятся за пределами окна просмотра макета, и их нужно увидеть, сдвинув экран.

На стороне ПК мы проходимdocument.documentElement.clientWidthПолучите ширину области просмотра.

Но на мобильной стороне есть два вьюпорта, макет и визуал Как получить значения?

Как упоминалось ранее, концепция области просмотра макета аналогична области просмотра на стороне ПК, которая используется для ограничения ширины html-элементов. То есть элемент html выложен с окном просмотра макета в качестве системы отсчета. Итак, вотdocument.documentElement.clientWidthМожно получить ширину окна просмотра макета.

на стороне ПК черезwindow.innerWidthЧтобы измерить ширину окна браузера и на мобильной стороне, поле, имитируемое визуальным окном просмотра, упомянутым ранее, эквивалентно окну браузера. Так что на мобильной стороне вы можете пройтиwindow.innerWidthчтобы получить ширину визуального окна просмотра. Его значение меняется в зависимости от уровня масштабирования. Значение чтения — это значение пикселей CSS в направлении x текущего экрана.

Что касается ПК, мы подытожилиwindow.innerWidthа такжеdocument.documentElement.clientWidthВ случае разных зумов он отличается только шириной полосы прокрутки. Но на мобильном,window.innerWidth(visual viewport)а такжеdocument.documentElement.clientWidth(layout viewport)Значения отличаются в случае масштабирования. Причина в том, что мобильныйdocument.documentElement.clientWidth(layout viewport)всегда фиксируется.

метатег окна просмотра

width:控制 layout viewport 的大小。
height:和 width 相对应,指定高度。
initial-scale:初始缩放比例,也即是当页面第一次 load 的时候缩放比例。
maximum-scale:允许用户缩放到的最大比例。
minimum-scale:允许用户缩放到的最小比例。
user-scalable:用户是否可以手动缩放

width устанавливает ширину окна просмотра макета

Почему это свойство должно быть установлено?

Мы упоминали ранее, что на исходной странице визуальная область просмотра автоматически масштабирует область просмотра до той же ширины, что и область просмотра макета, чтобы можно было увидеть весь контент, и пользователь естественным образом увеличивает масштаб страницы, но при столкновении с длинными текстовые абзацы, необходимо провести пальцем влево и вправо по экрану, чтобы прочитать его полностью. Эту оптимизацию можно выполнить без метатега области просмотра.

Установите ширину html на 375 пикселей, чтобы текст полностью отображался на странице, и не нужно было скользить влево и вправо при увеличении.

Но содержимое слишком мало при инициализации и его нелегко читать.

Поэтому Apple предложила мета вьюпорта, чтобы решить эту проблему.

Одной из целей является возможность вручную установить значение окна просмотра макета.

Поскольку такую ​​большую ширину в пикселях нельзя использовать на мобильной стороне, просто уменьшите значение области просмотра макета, и визуальная область просмотра автоматически масштабируется для отображения всего содержимого области просмотра макета на экране.

Но мы также упоминали ранее, что ширина области просмотра макета ограничивает ширину элемента HTML. Следовательно, ширину элемента в элементе html необходимо установить не больше, чем значение ширины окна просмотра макета, чтобы гарантировать его полное отображение в визуальном окне просмотра.



В настоящее время в метатеге окна просмотра установлено только поле width = 300. В зависимости от явления масштабирования ширина визуального окна просмотра и окна просмотра макета одинаковы.

В соответствии с этим явлением нам нужно только установить одинаковую ширину области просмотра в соответствии с шириной, запланированной в проекте дизайна. Опираясь на принцип масштабирования, на всех моделях может быть представлена ​​одинаковая ширина. (Высота адаптируется к ширине)

Однако текущая область просмотра устанавливает только ширину, а пользователи текущей страницы по-прежнему могут масштабировать вручную. Чтобы запретить масштабирование вручную, необходимо добавить поле.

<meta name="viewport" content="width=375" user-scalable=no>

но этоuser-scalable=noПоля накладывают ограничения на функцию автоматического масштабирования некоторых собственных браузеров Android и некоторых веб-представлений Android.
Ширина области просмотра макета, установленная в этом примере, составляет 375 пикселей.

То, что должно было просто заполнить экран контентом, теперь имеет левую и правую полосы прокрутки. Причина этого явления заключается в том, что ширина области просмотра макета установлена ​​на 375 пикселей от значения ширины мета области просмотра, но значение визуальной области просмотра составляет только 360 пикселей, поэтому на экране может отображаться только 360 пикселей контента, и остальное нужно смахивать влево и вправо.

Что касается того, почему он здесь 360px, а не другие значения. Давайте посмотрим на концепцию идеального просмотра просмотра.

ideal viewport

В начале упоминалась концепция визуального вьюпорта и вьюпорта компоновки. Эти два значения связаны с фактическим размером страницы, но эта идеальная область просмотра, говоря наиболее интуитивно понятным языком, представляет собой размер экрана, соответствующий каждой модели, и, конечно же, он также измеряется в пикселях CSS.


Возьмем, к примеру, Note2, который только что показан на GIF-анимации.Значение идеального окна просмотра составляет 360 пикселей, и это значение тесно связано со значением масштабирования и визуальным окном просмотра. используется в качестве эталонного значения. («идеальное окно просмотра», «значение масштабирования» и «визуальное окно просмотра» тесно связаны)

visual viewport width = ideal viewport width / zoom factor

Это значение масштабирования коэффициента масштабирования также упоминалось ранее и в большинстве случаев рассчитывается автоматически. В качестве примера возьмем примечание 2. Ширина окна просмотра макета установлена ​​на 375 пикселей (user-scalable=no не задано), а ширина текущего идеального окна просмотра составляет 360 пикселей.

<meta name="viewport" content="width=375">

Визуальный экран автомасштабирования страницы рассчитывается равным 375. Таким образом, в это время визуальное окно просмотра экрана может видеть все содержимое ширины окна просмотра макета.

После установки

<meta name="viewport" content="width=375, user-scalable=no">

После этого в некоторых собственных браузерах Android и веб-просмотрах Android значение масштабирования не будет рассчитываться автоматически, а будет иметь фиксированное значение, равное 1.
Согласно приведенной выше формуле расчета,
visual viewport width = 360 / 1 = 360px
То есть страница отображается следующим образом

Поскольку значение масштабирования не увеличивается автоматически, вы можете динамически установить значение масштабирования через js, чтобы увидеть, можно ли решить эту проблему.

Давайте посмотрим на атрибут метаданных окна просмотра:initial-scaleЭто значение может явно задавать значение масштабирования. Помните, что в соответствии с приведенной выше формулой значение масштабирования масштабируется относительно идеальной ширины окна просмотра.

специальное значение шириныwidth=device-width. Установив это значение, браузер установит ширину области просмотра макета текущей страницы на ширину идеальной области просмотра устройства. И значение layout viewport мы можем передатьdocument.documentElement.clientWidthполучать.

Установка директивы initial-scale на самом деле делает две вещи:

  1. Установка начального коэффициента масштабирования страницы на осмысленное значение, рассчитанное относительно идеального окна просмотра, дает ширину визуального окна просмотра.

  2. Установите значение ширины видового экрана макета в соответствии с только что рассчитанным значением ширины визуального видового экрана.

С этими понятиями давайте начнем наш тест.

<meta name="viewport" content="width=device-width, initial-scale = 1, user-scalable=no" />// 目的是讲当前页面的layout viewport设置成ideal viewport width
var idaelViewport = document.documentElement.clientWidth; // 取得当前页面的ideal viewport width
var visualViewport = 375;
alert(idaelViewport)
var zoomView = idaelViewport/visualViewport;  // 动态计算缩放值
$('.j_Viewport').attr('content', 'user-scalable=no, initial-scale='+zoomView ); // 动态设置viewport meta
alert(zoomView)

Проблема в том, что в некоторых андроидах начальный масштаб может быть установлен только в значения вьюпорта макета и визуального вьюпорта расчетным путем, когда начальный масштаб установлен в 1, и это также не работает в этой схеме.

Основываясь на приведенных выше знаниях, очень просто посмотреть на принцип реализации гибкого.js, созданного Taobao.

В общем, flexible.js сделал несколько вещей. Возьмем в качестве примера iphone 5. Идеальная ширина области просмотра для iphone 5 составляет 320.

  1. Определяется устройствомdpr

if (isIPhone) {
   // iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案
   if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {                
       dpr = 3;
   } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
       dpr = 2;
   } else {
       dpr = 1;
   }
} else {
   // 其他设备下,仍旧使用1倍的方案
   dpr = 1;
}
scale = 1 / dpr;

Разделите разные модели iphone на 1, 2, 3
Установите униформу dpr Android на 1
В среде iphone5 dpr=2, масштаб=0,5.

  1. Установите для атрибута data-dpr значение html

docEl.setAttribute('data-dpr', dpr);
  1. Динамически устанавливаемая мета вьюпорта

 metaEl = doc.createElement('meta');
 metaEl.setAttribute('name', 'viewport');
 metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
 if (docEl.firstElementChild) {
     docEl.firstElementChild.appendChild(metaEl);
 } else {
     var wrap = doc.createElement('div');
     wrap.appendChild(metaEl);
     doc.write(wrap.innerHTML);
 }

<meta name="viewport" content="initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no">

Теперь, в среде iphone5, установка initial-scale=0.5 сама по себе имеет два эффекта, как упоминалось ранее. В соответствии с формулой

visual viewport width = ideal viewport width / zoom factor

Вы можете получить ширину визуального окна просмотра = 320/0,5 = 640, что означает, что значения ширины визуального окна просмотра и ширины окна просмотра макета страницы равны 640 пикселей.

В то же время ширина html также установлена ​​​​на 640 пикселей.

Теперь эта библиотека задала ширину html на текущем устройстве, масштабировать нельзя, значения ширины визуального вьюпорта и ширины вьюпорта макета тоже одинаковые, отображаются полностью.

Следующий шаг — разобраться с размером элементов на странице.

  1. Используйте rem для установки размера элемента страницы

function refreshRem(){
   var width = docEl.getBoundingClientRect().width;
   if (width / dpr > 540) {
       width = 540 * dpr;
   }
   var rem = width / 10;
   docEl.style.fontSize = rem + 'px';
   flexible.rem = win.rem = rem;
}

в этом кодеdocEl.getBoundingClientRect().width;Получается ширина html, которая является максимальной шириной текущей страницы.
var rem = width / 10;
Затем возьмите значение width/10, чтобы получить ссылочный номер.Для iphone это значение равно rem=640/10 = 64.
docEl.style.fontSize = rem + 'px';Установите Размер шрифта HTML-элемента на 64 пикселя.

Принцип работы rem заключается в том, что он вычисляется относительно значения fontSize элемента html.

Функция этой библиотеки, вероятно, завершена.Конечная цель нескольких частей логики - установить значение fontSize hmtl равным 64px.Как это работает?

Наброски дизайна, которые мы обычно получаем, имеют размер 750 пикселей.По умолчанию набросок дизайна делится на 10 частей.Пиксель 75 пикселей соответствует rem.Соответствующий rem равен 30/75=0,4rem. Затем определите ширину изображения как 0,4 rem на соответствующей странице.

Вот как работает flexible.js.

Оригинал статьи, при перепечатке указывать источник.

Если у вас есть какие-либо вопросы или комментарии по поводу моего понимания выше, пожалуйста, не стесняйтесь обращаться ко мне в частном порядке ~Weibo — Сиам, который пишет интерфейс

Категории