Фоновое изображение скачет, когда адресная строка скрывает iOS / Android / Mobile Chrome

174

В настоящее время я разрабатываю адаптивный сайт с помощью Twitter Bootstrap.

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

Это почти идеально, за исключением одного вопроса. При использовании iOS Safari, Android Browser или Chrome на Android фон слегка подпрыгивает, когда пользователь прокручивает страницу вниз и скрывает адресную строку.

Сайт находится здесь: http://lt2.daveclarke.me/

Посетите его на мобильном устройстве и прокрутите вниз, и вы увидите, как изображение изменяется / перемещается.

Код, который я использую для фонового DIV, выглядит следующим образом:

#bg1 {
    background-color: #3d3d3f;
    background-repeat:no-repeat;
    background-attachment:fixed;
    background-position:center center;
    -webkit-background-size: cover;
    -moz-background-size: cover;
    -o-background-size: cover;
    background-size: cover; position:fixed;
    width:100%;
    height:100%;
    left:0px;
    top:0px;
    z-index:-1;
    display:none;
}

Все предложения приветствуются - это делает мою голову некоторое время !!

Дэйв Кларк
источник
Ваша ссылка требует авторизации ... также, покажите нам код пожалуйста!
Шон Тейлор
Добавлена ​​новая ссылка и показан код для позиционирования фона и т. Д.
Дейв Кларк,
1
Если у вас возникла эта проблема, вы можете проверить developers.google.com/web/updates/2016/12/url-bar-resizing . Эта проблема (вроде) решена сейчас, но все еще затрагивает элементы, которые имеют position: fixed.
Адам Рейс
@AdamReis Наконец-то! Спасибо за публикацию
Дэйв Кларк

Ответы:

106

Эта проблема вызвана сужением / сдвигом полос URL-адресов и изменением размера div # bg1 и # bg2, поскольку они имеют высоту 100% и «фиксированы». Так как фоновое изображение установлено на «покрытие», оно будет регулировать размер / положение изображения по мере увеличения области содержания.

Исходя из отзывчивости сайта, фон должен масштабироваться. Я принимаю два возможных решения:

1) Установите высоту # bg1, # bg2 равной 100vh. В теории это элегантное решение. Однако в iOS есть ошибка vh ( http://thatemil.com/blog/2013/06/13/viewport-relative-unit-strangeness-in-ios-6/ ). Я попытался использовать максимальную высоту, чтобы предотвратить проблему, но она осталась.

2) Размер области просмотра, определяемый Javascript, не зависит от панели URL. Поэтому Javascript можно использовать для установки статической высоты на # bg1 и # bg2 в зависимости от размера области просмотра. Это не лучшее решение, так как это не чистый CSS, и при загрузке страницы наблюдается небольшой скачок изображения. Однако это единственное жизнеспособное решение, которое я вижу, учитывая «vh» ошибки iOS (которые, похоже, не исправлены в iOS 7).

var bg = $("#bg1, #bg2");

function resizeBackground() {
    bg.height($(window).height());
}

$(window).resize(resizeBackground);
resizeBackground();

Кстати, я видел очень много проблем с этими изменяющимися панелями URL в iOS и Android. Я понимаю цель, но им действительно нужно продумать странную функциональность и хаос, которые они приносят на сайты. Последнее изменение - вы больше не можете «скрывать» строку URL при загрузке страницы на iOS или Chrome, используя приемы прокрутки.

РЕДАКТИРОВАТЬ: Хотя приведенный выше скрипт отлично работает для предотвращения изменения размера фона, он вызывает заметный разрыв, когда пользователи прокручивают страницу вниз. Это потому, что он поддерживает размер фона до 100% высоты экрана минус строка URL. Если мы добавим 60px к высоте, как предполагает швейцарец, эта проблема исчезнет. Это означает, что мы не видим нижние 60 пикселей фонового изображения при наличии панели URL, но это не позволяет пользователям когда-либо видеть пробел.

function resizeBackground() {
    bg.height( $(window).height() + 60);
}
Джейсон
источник
Спасибо за это. Завтра я приведу это в порядок и расскажу, как у меня получится :)
Дэйв Кларк,
5
Это замечательно. Я реализовал ваше второе решение, которое работало почти идеально, с небольшим зазором между нижним колонтитулом и фоновым изображением. Я изменил вашу четвертую строку кода на: bg.height(jQuery(window).height() + 60);которая прекрасно работает на всех моих устройствах! Спасибо :)
Дейв Кларк
6
ошибка iOS vh исправлена ​​в iOS8, но проблема на Android нет. Я использую vhединицы и, конечно 100vh, больше, когда адресная строка скрыта. Глупо, что этот скачок происходит после остановки прокрутки. Это выглядит просто глючно. В итоге я использовал переход на высоту, чтобы он выглядел намеренно.
Задачи из
1
Я смог решить эту проблему, переместив фон с bodyобертки, <div>оборачивающей содержимое всей страницы. Никаких прыжковых фонов на iOS или Android!
Мариус Шульц
2
Решение JS не работает для меня (Android). Подтвердил, что скрипт устанавливает высоту, но проблема не устранена.
января
61

Я обнаружил, что ответ Джейсона не совсем подходит для меня, и я все еще прыгал. Javascript гарантировал отсутствие пробела в верхней части страницы, но фон все еще прыгал, когда адресная строка исчезала / появлялась снова. Так же как и исправление Javascript, я применил transition: height 999999sк div. Это создает переход с такой длительностью, что фактически замораживает элемент.

AlexKempton
источник
24
Вы, сэр, заслуживаете +1 за реальное нестандартное мышление. К сожалению, это не позволяет настроить размер div для любых изменений размера экрана, в том числе для примеров, вызванных поворотом экрана.
тобик
+1 за креативность! Возможно, придется использовать это сейчас в качестве составных частей проблемы, если вы используете vwили vhдля установки размера шрифта внутри этого родительского контейнера.
robabby
6
@tobik Тем не менее можно уменьшить скачок, вызванный изменением области просмотра, установив
примерно
7
попробуйте повернуть телефон сейчас
cuddlecheek
1
@tobik это на самом деле делает его скорее функцией, чем ошибкой;) хорошее мышление
dimitrieh
23

У меня похожая проблема в заголовке нашего сайта.

html, body {
    height:100%;
}
.header {
    height:100%;
}

Это закончится скачкообразной прокруткой на Android Chrome, потому что .header-container перемасштабируется после того, как url-bar скрывается и палец убирается с экрана.

CSS-решение:

Добавление следующих двух строк предотвратит скрытие панели URL и вертикальную прокрутку:

html {
    overflow: hidden;
}
body {
    overflow-y: scroll;
    -webkit-overflow-scrolling:touch;
}
мат
источник
4
Да, это решает проблему, как вы говорите, но отстой, что навигационная панель всегда отображается. На некоторых телефонах это может занимать много места на экране!
Дейв Кларк
1
Это правда, чтобы предотвратить это, вы можете дополнительно использовать обходной путь JavaScript. Но этот пример работает без JS вообще.
Мат
3
Прокрутка полностью отключена, когда я попробовал это решение.
Nithin Baby
1
Спасибо, это отлично сработало в моей ситуации! Следует упомянуть для всех, кто может пропустить это, чтобы теги html и body были установлены на 100% высоты, чтобы это работало (сначала я просто просмотрел ваш ответ и перешел к первому упоминанию «решения»).
gburning
-webkit-overflow-scrolling не должен использоваться на производственных сайтах. developer.mozilla.org/en-US/docs/Web/CSS/…
Фредрик Вестерлунд
16

Проблема может быть решена с помощью медиа-запроса и некоторой математики. Вот решение для ориентации портрета:

@media (max-device-aspect-ratio: 3/4) {
  height: calc(100vw * 1.333 - 9%);
}
@media (max-device-aspect-ratio: 2/3) {
  height: calc(100vw * 1.5 - 9%);
}
@media (max-device-aspect-ratio: 10/16) {
  height: calc(100vw * 1.6 - 9%);
}
@media (max-device-aspect-ratio: 9/16) {
  height: calc(100vw * 1.778 - 9%);
}

Поскольку vh изменится после исчезновения панели URL, вам нужно определить высоту другим способом. К счастью, ширина области просмотра постоянна, и мобильные устройства имеют только несколько различных форматов изображения; если вы можете определить ширину и соотношение сторон, небольшая математика даст вам высоту окна просмотра именно так, как должен работать vh . Вот процесс

1) Создайте серию медиазапросов для соотношений сторон, на которые вы хотите ориентироваться.

  • используйте device-aspect-ratio вместо aspect-ratio, так как последнее изменится при исчезновении панели URL

  • Я добавил «max» в device-aspect-ratio, чтобы нацелить любые соотношения сторон, которые оказываются между самыми популярными. Они не будут такими точными, но они будут только для меньшинства пользователей и все еще будут довольно близки к правильному vh.

  • запомните медиа-запрос, используя горизонтальный / вертикальный, поэтому для переноса вам нужно будет перевернуть цифры

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

  • Поскольку вы знаете ширину и отношение ширины к высоте, вы просто умножаете нужный вам% (100% в вашем случае) на отношение высоты / ширины.

3) Вы должны определить высоту URL-бара, а затем минус это от высоты. Я не нашел точных измерений, но я использую 9% для мобильных устройств в альбомной ориентации, и это, кажется, работает довольно хорошо.

Это не очень элегантное решение, но другие варианты тоже не очень хороши, учитывая, что они:

  • Ваш сайт кажется глючным для пользователя,

  • имеющие элементы неправильного размера, или

  • Использование JavaScript для некоторых основных стилей,

Недостатком является то, что некоторые устройства могут иметь разную высоту или соотношение сторон по URL-адресу, чем самые популярные. Однако, используя этот метод, если только небольшое количество устройств переносит / вычитает несколько пикселей, мне кажется, что это намного лучше, чем всем, у кого размер веб-сайта изменяется при перелистывании.

Чтобы сделать это проще, я также создал миксин SASS:

@mixin vh-fix {
  @media (max-device-aspect-ratio: 3/4) {
    height: calc(100vw * 1.333 - 9%);
  }
  @media (max-device-aspect-ratio: 2/3) {
    height: calc(100vw * 1.5 - 9%);
  }
  @media (max-device-aspect-ratio: 10/16) {
    height: calc(100vw * 1.6 - 9%);
  }
  @media (max-device-aspect-ratio: 9/16) {
    height: calc(100vw * 1.778 - 9%);
  }
}
Джордан Лос
источник
2
Очень креативно! Не фанат 9%, хотя думаю.
w00t 30.01.16
1
Очень просто и умно! Вы можете добавить параметр в vh-fix для имитации исходного поведения: @mixin vh-fix($vh: 100)=>height: calc(100vw * (1.333 * $vh / 100) - 9%)
mjsarfatti
1
Выше должно быть:height: calc(100vw * (1.333 * #{$vh} / 100) - 9%)
mjsarfatti
В моем случае это сработало очень хорошо, и даже лучше, когда я удалил -9%.
Бен Флеминг
12

Все ответы здесь используют windowвысоту, которая зависит от строки URL. Все забыли оscreen высоте?

Вот мое решение jQuery:

$(function(){

  var $w = $(window),
      $background = $('#background');

  // Fix background image jump on mobile
  if ((/Android|iPhone|iPad|iPod|BlackBerry/i).test(navigator.userAgent || navigator.vendor || window.opera)) {
    $background.css({'top': 'auto', 'bottom': 0});

    $w.resize(sizeBackground);
    sizeBackground();
  }

  function sizeBackground() {
     $background.height(screen.height);
  }
});

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

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

Кроме того, все это предполагает #background что элемент фиксированной позиции заполняет окно.

Для пуристов JavaScript (предупреждение - не проверено):

var background = document.getElementById('background');

// Fix background image jump on mobile
if ((/Android|iPhone|iPad|iPod|BlackBerry/i).test(navigator.userAgent || navigator.vendor || window.opera)) {
  background.style.top = 'auto';
  background.style.bottom = 0;

  window.onresize = sizeBackground;
  sizeBackground();
}

function sizeBackground() {
  background.style.height = screen.height;
}

РЕДАКТИРОВАТЬ: Извините, что это не отвечает непосредственно на вашу конкретную проблему с более чем одним фоном. Но это один из первых результатов при поиске этой проблемы фиксированных фоновых прыжков на мобильных устройствах.

cr0ybot
источник
2
Я попробовал миллион таких ответов, и это, безусловно, лучший вариант. Первоначально я пытался использовать это только для <body>, поскольку это имело фон. Использование div, чтобы обернуть всю страницу вызвало другие проблемы. Использование пустого div с z-index: -1 в качестве фона, казалось бы, лучшее решение в сочетании с вышеизложенным. Я снял мобильное обнаружение, так как выполнение этого на рабочем столе не повредит моему сайту. Нет математики (которая может угадать размер вкладок неправильно), не требуется обработчик для изменения размера. Фон - это весь экран, закрепленный на дне. Готово. Любить это!
Эван Ланглуа
9

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

1) Элементы с установленной высотой 100vh изменения размера каждый раз, когда изменяется размер области просмотра, включая те случаи, когда это вызвано (не) появлением панели URL.

2) $(window).height() возвращает значения, на которые также влияет размер строки URL.

Одно из решений состоит в том, чтобы «заморозить» элемент, используя transition: height 999999sпредложенный в ответе AlexKempton . Недостатком является то, что это эффективно отключает адаптацию ко всем изменениям размера области просмотра, в том числе вызванным поворотом экрана.

Поэтому мое решение - управлять изменениями области просмотра вручную с помощью JavaScript. Это позволяет мне игнорировать небольшие изменения, которые могут быть вызваны строкой URL, и реагировать только на большие.

function greedyJumbotron() {
    var HEIGHT_CHANGE_TOLERANCE = 100; // Approximately URL bar height in Chrome on tablet

    var jumbotron = $(this);
    var viewportHeight = $(window).height();

    $(window).resize(function () {
        if (Math.abs(viewportHeight - $(window).height()) > HEIGHT_CHANGE_TOLERANCE) {
            viewportHeight = $(window).height();
            update();
        }
    });

    function update() {
        jumbotron.css('height', viewportHeight + 'px');
    }

    update();
}

$('.greedy-jumbotron').each(greedyJumbotron);

РЕДАКТИРОВАТЬ: Я на самом деле использую эту технику вместе с height: 100vh. Страница отображается правильно с самого начала, а затем включается JavaScript и начинает управлять высотой вручную. Таким образом, не происходит мерцания во время загрузки страницы (или даже после).

tobik
источник
1
Я использовал нечто подобное, но вместо установки height: 100vhв исходном CSS, я устанавливаю, min-height:100vhа затем изменяю размер окна, вычисляю min-heightи устанавливаю его на высоту порта просмотра. Это удобно, когда ваш сайт просматривается на крошечных экранах, а его содержимое слишком велико, чтобы поместиться в окне просмотра. SetTimeout debounce / throttle для события resize помогает повысить производительность в некоторых браузерах (изменение размера срабатывает очень часто)
Troy Morehouse,
Я думаю, что в определенный момент я также попытался использовать min-heightвместо этого, но затем я столкнулся с проблемой, когда мне нужно было вертикально центрировать внутренний контент. Каким-то образом вертикальное центрирование может стать сложным, когда внешний элемент heightустановлен в auto. Поэтому я придумал фиксированную минимальную высоту, которой должно быть достаточно, чтобы вместить любой возможный контент, и установил ее в исходном CSS. Так как min-heightимеет более высокий приоритет, чем height, он работает довольно хорошо.
Тобик
Ах да, у меня была та же проблема, но я исправил ее, изменив jumbotron на, display: tableа затем установив внутренний контейнер на display: table-cellwith vertical-align: middle. Работал как шарм.
Трой Морхауз
В самом деле? Потому что я попробовал тот же подход, но потерпел неудачу. Я действительно не помню, в чем была проблема, но это может иметь отношение к делу: stackoverflow.com/questions/7790222/…
tobik
Просто убедитесь, что вы избегаете процентных отступов или полей. Вызвало несколько странных проблем с рендерингом в IE8, хотя современные браузеры были в порядке.
Трой Морехаус
8

Решение , которое я сейчас использую, чтобы проверить userAgentна , $(document).readyчтобы увидеть , если это один из оскорбляющих браузеров. Если это так, выполните следующие действия:

  1. Установите соответствующие высоты для текущей высоты области просмотра, а не «100%»
  2. Сохранить текущее горизонтальное значение области просмотра
  3. Затем, $(window).resizeтолько обновите соответствующие значения высоты, если новое горизонтальное измерение области просмотра отличается от его начального значения
  4. Сохраните новые горизонтальные и вертикальные значения

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

Да, и адресная строка влияет $(window).height. См .: Изменения в адресной строке браузера Mobile Webkit (chrome) $ (window) .height (); Создание размера фона: каждый раз, когда JS "Window" width-height vs "screen" width-height?

член парламента
источник
Я не пробовал это, но ваш первый пункт не будет работать для iOS? ( thatemil.com/blog/2013/06/13/… )
Дэйв Кларк,
Я устанавливал его ценность на первом этапе, но я удивлен, что вы нашли ответ Джейсона, чтобы решить проблему. Как отмечалось, я обнаружил, что вместе с другим пользователем в предыдущем вопросе, который я связал, значение метода $ (window) .height () изменяется, когда адресная строка в chrome на android видна или не видна. Я собрал этот маленький сайт, который просто отображает результат $ (window) .height () в виде предупреждения, и он определенно предоставляет разные значения на моем nexus 4 в chrome, когда адресная строка не видна: stormy-meadow-5908 .herokuapp.com
mp
Это 100% устраняет проблему на моем устройстве Android, хотя я вижу похожую проблему на своем iPad, которая, похоже, не устраняет, и я до сих пор нахожусь.
Дэйв Кларк
Можете ли вы предоставить некоторый код для вашего решения, и я попробую его?
Дэйв Кларк
4

Я нашел действительно простое решение без использования Javascript:

transition: height 1000000s ease;
-webkit-transition: height 1000000s ease;
-moz-transition: height 1000000s ease;
-o-transition: height 1000000s ease;

Все, что это делает, это задерживает движение, так что это невероятно медленно, что это не заметно.

Пав Сидху
источник
@ Tyguy7 Он отлично работает , когда ваш рост не установлен на фиксированное значение, то есть 100%, 100vh. IE8 - единственный крупный браузер, который не поддерживает переходы.
Пав Сидху
Отличное и простое решение!
zdarsky.peter
3
Это прекрасно работает, пока вы не на устройстве, где вы можете перейти от портрета к ландшафту. Когда это происходит, дизайн разрушен.
Надя Ник
@NagyNick, это не было такой большой проблемой для меня. Вы можете обнаружить изменение ориентации в Javascript и настроить фоновое изображение.
Пав Сидху
3

Мое решение включало немного JavaScript. Оставьте 100% или 100vh на div (это позволит избежать появления div при начальной загрузке страницы). Затем, когда страница загрузится, возьмите высоту окна и примените ее к рассматриваемому элементу. Избегает прыжка, потому что теперь у вас есть статическая высота на вашем div.

var $hero = $('#hero-wrapper'),
    h     = window.innerHeight;

$hero.css('height', h);
Тодд миллер
источник
3

Я создал ванильное решение Javascript для использования единиц VH. Использование VH практически везде происходит за счет минимизации адресных строк при прокрутке. Чтобы исправить джанк, который показывает, когда страница перерисовывается, у меня есть этот js, который будет захватывать все ваши элементы, используя единицы VH (если вы дадите им класс .vh-fix), и давать им встроенную высоту пикселей. По сути заморозить их на высоте, которую мы хотим. Вы можете сделать это при повороте или изменении размера области просмотра, чтобы оставаться отзывчивым.

var els = document.querySelectorAll('.vh-fix')
if (!els.length) return

for (var i = 0; i < els.length; i++) {
  var el = els[i]
  if (el.nodeName === 'IMG') {
    el.onload = function() {
      this.style.height = this.clientHeight + 'px'
    }
  } else {
    el.style.height = el.clientHeight + 'px'
  }
}

Это решило все мои варианты использования, надеюсь, это поможет.

Компьютерщик Devigner
источник
3

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

//remove height property from file css because we will set it to first run of page
//insert this snippet in a script after declarations of your scripts in your index

var setHeight = function() {    
  var h = $(window).height();   
  $('#bg1, #bg2').css('height', h);
};

setHeight(); // at first run of webpage we set css height with a fixed value

if(typeof window.orientation !== 'undefined') { // this is more smart to detect mobile devices because desktop doesn't support this property
  var query = window.matchMedia("(orientation:landscape)"); //this is is important to verify if we put 
  var changeHeight = function(query) {                      //mobile device in landscape mode
    if (query.matches) {                                    // if yes we set again height to occupy 100%
      setHeight(); // landscape mode
    } else {                                                //if we go back to portrait we set again
      setHeight(); // portrait mode
    }
  }
  query.addListener(changeHeight);                          //add a listner too this event
} 
else { //desktop mode                                       //this last part is only for non mobile
  $( window ).resize(function() {                           // so in this case we use resize to have
    setHeight();                                            // responsivity resisizing browser window
  }); 
};
линотип
источник
1
Вы вызываете setHeight () внутри метода changeHeight, если запрос совпадает, а также если он не совпадает. Так что просто удалите оператор if, так как он не нужен.
Деннис Мейснер,
2

Это лучшее решение (самое простое) из всех, что я пробовал.

... И это не сохраняет родной опыт адресной строки !

Вы можете установить высоту с помощью CSS, например, 100%, а затем установить высоту 0,9 * от высоты окна в пикселях с использованием JavaScript при загрузке документа.

Например, с помощью jQuery:

$("#element").css("height", 0.9*$(window).height());

)

К сожалению, нет ничего, что работает с чистым CSS: P, но также имейте это в виду vhи глючит vwна iPhone - используйте проценты.


источник
1

Я установил свой элемент ширины с помощью JavaScript. После того, как я установил de vh.

HTML

<div id="gifimage"><img src="back_phone_back.png" style="width: 100%"></div>

CSS

#gifimage {
    position: absolute;
    height: 70vh;
}

Javascript

imageHeight = document.getElementById('gifimage').clientHeight;

// if (isMobile)       
document.getElementById('gifimage').setAttribute("style","height:" + imageHeight + "px");

Это работает для меня. Я не использую jquery и т. Д. потому что я хочу загрузить его как можно скорее.

Йохан Хоксма
источник
1

Потребовалось несколько часов, чтобы понять все детали этой проблемы и определить наилучшую реализацию. Оказывается, по состоянию на апрель 2016 года только iOS Chrome имеет эту проблему. Я пробовал на Android Chrome и iOS Safari - оба были в порядке без этого исправления. Итак, исправление для iOS Chrome, которое я использую:

$(document).ready(function() {
   var screenHeight = $(window).height();
   $('div-with-background-image').css('height', screenHeight + 'px');
});
littlequest
источник
1

Простой ответ, если ваш фон позволяет, почему бы не установить background-size: что-то, что просто покрывает ширину устройства медиа-запросами и использовать рядом с: after position: fixed; взломать здесь .

IE: background-size: 901px; для любых экранов <900 пикселей? Не идеальный или отзывчивый, но на мобильном мне показалось обаяние <480px, так как я использую абстрактную фоновую музыку.

EasterMedia
источник
0

Я использую этот обходной путь: исправить высоту bg1 при загрузке страницы с помощью:

var BG = document.getElementById('bg1');
BG.style.height = BG.parentElement.clientHeight;

Затем присоедините прослушиватель события resize к Window, который делает это: если разница в высоте после изменения размера меньше 60px (что-либо больше, чем высота панели URL), тогда ничего не делайте, а если она больше 60px, тогда снова установите высоту bg1 на высоту его родителя! полный код:

window.addEventListener("resize", onResize, false);
var BG = document.getElementById('bg1');
BG.style.height = BG.parentElement.clientHeight;
var oldH = BG.parentElement.clientHeight;

function onResize() {
    if(Math.abs(oldH - BG.parentElement.clientHeight) > 60){
      BG.style.height = BG.parentElement.clientHeight + 'px';
      oldH = BG.parentElement.clientHeight;
    }
}

PS: эта ошибка так раздражает!

AadityaTaparia
источник
0

Похоже на ответ @AlexKempton. (не могу прокомментировать извините)

Я использовал длинные задержки перехода, чтобы предотвратить изменение размера элемента.

например:

transition: height 250ms 600s; /*10min delay*/

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

Крис Андерсон
источник
0

Для тех, кто хотел бы слушать фактическую внутреннюю высоту и вертикальную прокрутку окна, пока мобильный браузер Chrome переводит строку URL с показа на скрытый и наоборот, единственное решение, которое я нашел, - это установить функцию интервала и измерить несоответствие window.innerHeight с его предыдущим значением.

Это вводит этот код:

var innerHeight = window.innerHeight;
window.setInterval(function ()
{
  var newInnerHeight = window.innerHeight;
  if (newInnerHeight !== innerHeight)
  {
    var newScrollY = window.scrollY + newInnerHeight - innerHeight;
    // ... do whatever you want with this new scrollY
    innerHeight = newInnerHeight;
  }
}, 1000 / 60);

Я надеюсь, что это будет удобно. Кто-нибудь знает лучшее решение?

Эдуард Мерсье
источник
0

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

var lastHeight = '';

$(window).on('resize', function () {
    // remove height when normal resize event is fired and content redrawn
    if (lastHeight) {
        $('#bg1').height(lastHeight = '');
    }
}).on('touchmove', function () {
    // when window height changes adjust height of the div
    if (lastHeight != window.innerHeight) {
        $('#bg1').height(lastHeight = window.innerHeight);
    }
});

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

Тем не менее, жаль, что мы должны придумать такие патчи, где position: fixedдолжны работать простые .

Павел
источник
0

Благодаря поддержке пользовательских свойств (переменных) CSS в iOS вы можете установить их с помощью JS и использовать их только на iOS.

const iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
if (iOS) {
  document.body.classList.add('ios');
  const vh = window.innerHeight / 100;
  document.documentElement.style
    .setProperty('--ios-10-vh', `${10 * vh}px`);
  document.documentElement.style
    .setProperty('--ios-50-vh', `${50 * vh}px`);
  document.documentElement.style
    .setProperty('--ios-100-vh', `${100 * vh}px`);
}
body.ios {
    .side-nav {
        top: var(--ios-50-vh);
    }
    section {
        min-height: var(--ios-100-vh);
        .container {
            position: relative;
            padding-top: var(--ios-10-vh);
            padding-bottom: var(--ios-10-vh);
        }
    }
}
Стивен Соусье
источник
0

Мой ответ для всех, кто приходит сюда (как я), чтобы найти ответ на ошибку, вызванную скрытым адресом голым / интерфейсом браузера.

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

// Keep track of window width
let myWindowWidth = window.innerWidth;

window.addEventListener( 'resize', function(event) {

    // If width is the same, assume hiding address bar
    if( myWindowWidth == window.innerWidth ) {
         return;
    }

    // Update the window width
    myWindowWidth = window.innerWidth;

    // Do your thing
    // ...
});
Эрик Дж.
источник