A imagem de fundo salta quando a barra de endereço oculta iOS / Android / Mobile Chrome

174

Atualmente, estou desenvolvendo um site responsivo usando o Twitter Bootstrap.

O site tem uma imagem de plano de fundo em tela cheia no celular / tablet / computador. Essas imagens giram e desbotam através de cada uma, usando duas divs.

É quase perfeito, exceto um problema. Usando o iOS Safari, o Navegador Android ou o Chrome no Android, o fundo salta levemente quando um usuário rola a página e faz com que a barra de endereços oculte.

O site está aqui: http://lt2.daveclarke.me/

Visite-o em um dispositivo móvel e role para baixo e você verá a imagem redimensionada / movida.

O código que estou usando para o DIV em segundo plano é o seguinte:

#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;
}

Todas as sugestões são bem-vindas - isso está me deixando louco por um tempo!

Dave Clarke
fonte
Seu link requer autenticação ... também, mostre-nos alguns códigos pls!
Shawn Taylor
Novo link adicionado e código mostrado para o posicionamento em segundo plano etc.
Dave Clarke
1
Se estiver com esse problema, convém verificar developers.google.com/web/updates/2016/12/url-bar-resizing . Esse problema (mais ou menos) foi resolvido agora, mas ainda afeta os elementos existentes position: fixed.
Adam Reis
@AdamReis Finalmente! Obrigado por postar
Dave Clarke

Respostas:

106

Esse problema é causado pelas barras de URL encolhendo / deslizando para fora do caminho e alterando o tamanho das divs # bg1 e # bg2, pois elas têm 100% de altura e são "fixas". Como a imagem de fundo está definida como "capa", ela ajusta o tamanho / posição da imagem, pois a área que contém é maior.

Com base na natureza responsiva do site, o plano de fundo deve ser escalado. Tenho duas soluções possíveis:

1) Defina a altura # bg1, # bg2 como 100vh. Em teoria, esta é uma solução elegante. No entanto, o iOS possui um bug vh ( http://thatemil.com/blog/2013/06/13/viewport-relative-unit-strangeness-in-ios-6/ ). Tentei usar uma altura máxima para evitar o problema, mas ele permaneceu.

2) O tamanho da janela de visualização, quando determinado pelo Javascript, não é afetado pela barra de URL. Portanto, o Javascript pode ser usado para definir uma altura estática no # bg1 e # bg2 com base no tamanho da viewport. Esta não é a melhor solução, pois não é CSS puro e há um ligeiro salto de imagem no carregamento da página. No entanto, é a única solução viável que considero considerar os erros "vh" do iOS (que não parecem estar corrigidos no iOS 7).

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

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

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

Em uma nota lateral, vi muitos problemas com essas barras de URL de redimensionamento no iOS e Android. Entendo o objetivo, mas eles realmente precisam pensar nas estranhas funcionalidades e estragos que causam nos sites. A última alteração é que você não pode mais "ocultar" a barra de URL no carregamento da página no iOS ou Chrome usando truques de rolagem.

EDIT: Embora o script acima funcione perfeitamente para impedir o redimensionamento do plano de fundo, ele causa uma lacuna perceptível quando os usuários rolam para baixo. Isso ocorre porque ele mantém o plano de fundo dimensionado para 100% da altura da tela menos a barra de URL. Se adicionarmos 60px à altura, como sugere swiss, esse problema desaparecerá. Isso significa que não conseguimos ver os 60px inferiores da imagem de plano de fundo quando a barra de URL está presente, mas impede que os usuários vejam uma lacuna.

function resizeBackground() {
    bg.height( $(window).height() + 60);
}
Jason
fonte
Obrigado por isso. Amanhã vou dar uma volta e você saberá como eu vou :) :)
Dave Clarke
5
Isso é maravilhoso. Implementei sua segunda solução, que funcionou quase perfeitamente com apenas alguns pixels entre o rodapé e a imagem de fundo. Alterei sua quarta linha de código para: bg.height(jQuery(window).height() + 60);que funciona perfeitamente em todos os meus dispositivos! Obrigado :)
Dave Clarke
6
o bug do iOS vh foi corrigido no iOS8, mas o problema no Android não é. Estou usando vhunidades e, claro, 100vhé maior quando a barra de endereços está oculta. É estúpido que esse salto ocorra após a rolagem parar. Parece apenas com bugs. Acabei usando a transição na altura para parecer intencional.
ProblemsOfSumit
1
Consegui resolver esse problema movendo o plano de fundo de bodypara um invólucro, <div>envolvendo o conteúdo da página inteira. Sem fundos de salto no iOS ou Android!
Marius Schulz
2
A solução JS não está funcionando para mim (Android). Confirmou que o script está definindo a altura, mas o problema persiste.
Jwinn 2/16
61

Eu descobri que a resposta de Jason não estava funcionando muito bem para mim e eu ainda estava dando um pulo. O Javascript garantiu que não houvesse lacunas na parte superior da página, mas o plano de fundo continuava saltando sempre que a barra de endereço desaparecia / reaparecia. Assim como a correção de Javascript, apliquei transition: height 999999sa div. Isso cria uma transição com uma duração tão longa que praticamente congela o elemento.

AlexKempton
fonte
24
Você merece um +1 pelo verdadeiro pensamento pronto para uso. Infelizmente, isso impede o ajuste do tamanho da div para qualquer alteração no tamanho da tela, incluindo exemplos causados ​​pela rotação da tela.
tobik
+1 para criatividade! Pode ser necessário usar isso por enquanto, pois o problema é complexo se você usar vwou vhdefinir o tamanho da fonte dentro desse contêiner pai.
robabby
6
@tobik É ainda possível reduzir o salto provocado pela mudança de exibição, definindo uma solução a 0,5 segundo ou de modo transição
binaryfunt
7
tente rodar o telefone agora
cuddlecheek
1
@tobik isso realmente faz com que seja mais uma característica que um bug;) bom pensar
dimitrieh
23

Eu tenho um problema semelhante no cabeçalho do nosso site.

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

Isso resultará em uma experiência de rolagem irregular no Android Chrome, porque o contêiner .header será redimensionado após a barra de url ocultar e o dedo ser removido da tela.

Solução CSS:

A adição das duas linhas a seguir impedirá que a barra de URL oculte e a rolagem vertical ainda seja possível:

html {
    overflow: hidden;
}
body {
    overflow-y: scroll;
    -webkit-overflow-scrolling:touch;
}
esteira
fonte
4
Sim, isso resolve como você diz, mas é péssimo que a barra de navegação esteja sempre aparecendo. Em alguns telefones, isso pode ocupar um espaço valioso na tela!
21415 Dave
1
Isso é verdade. Para evitar isso, você também pode usar uma solução alternativa para JavaScript. Mas este exemplo funciona sem o JS.
mat
3
O Scroll está desativado completamente quando tentei esta solução.
Nithin Baby
1
Obrigado, isso funcionou muito bem para a minha situação! Deveria ser mencionado para qualquer pessoa que possa sentir falta de que as tags html e body tenham que ser definidas como 100% de altura para que isso funcione (inicialmente eu apenas dei uma olhada na sua resposta e pulei para a primeira menção de "solução").
gburning
-webkit-overflow-scrolling não deve ser usado em sites de produção. developer.mozilla.org/pt-BR/docs/Web/CSS/…
Fredrik Westerlund
16

O problema pode ser resolvido com uma consulta de mídia e um pouco de matemática. Aqui está uma solução para uma orientação portait:

@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%);
}

Como vh mudará quando a barra de URL desaparecer, é necessário determinar a altura de outra maneira. Felizmente, a largura da janela de visualização é constante e os dispositivos móveis têm apenas algumas proporções diferentes; se você pode determinar a largura e a proporção, um pouco de matemática fornecerá a altura da janela de visualização exatamente como vh deve funcionar. Aqui está o processo

1) Crie uma série de consultas de mídia para as proporções que você deseja atingir.

  • use a proporção de aspecto do dispositivo em vez da proporção, pois o último será redimensionado quando a barra de URL desaparecer

  • Adicionei 'max' à proporção de aspecto do dispositivo para segmentar as proporções que se seguem entre as mais populares. Eles não serão tão precisos, mas serão apenas para uma minoria de usuários e ainda estarão bem próximos do vh adequado.

  • lembre-se da consulta de mídia usando horizontal / vertical, portanto, para portait, você precisará inverter os números

2) para cada consulta de mídia, multiplique qualquer porcentagem da altura vertical que você deseja que o elemento esteja em vw pelo inverso da proporção.

  • Como você conhece a largura e a proporção entre largura e altura, basta multiplicar a% desejada (100% no seu caso) pela proporção entre altura / largura.

3) Você precisa determinar a altura da barra de URL e menos a partir da altura. Não encontrei medidas exatas, mas uso 9% para dispositivos móveis em paisagem e isso parece funcionar bastante bem.

Esta não é uma solução muito elegante, mas as outras opções também não são muito boas, considerando que são:

  • Tendo seu site parecido com o usuário,

  • com elementos de tamanho inadequado, ou

  • Usando javascript para obter alguns estilos básicos ,

A desvantagem é que alguns dispositivos podem ter alturas ou proporções de barra de URL diferentes das mais populares. No entanto, usar esse método se apenas um pequeno número de dispositivos sofrer a adição / subtração de alguns pixels, isso me parece muito melhor do que todos os que têm um site redimensionado ao passar o dedo.

Para facilitar, também criei um mixin 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%);
  }
}
Jordan Los
fonte
2
Muito criativo! Não é um fã do palpite de 9%.
W00t
1
Muito simples e inteligente! Você pode adicionar um parâmetro ao vh-fix para simular o comportamento original: @mixin vh-fix($vh: 100)=>height: calc(100vw * (1.333 * $vh / 100) - 9%)
mjsarfatti 02/02
1
A descrição acima deve ser:height: calc(100vw * (1.333 * #{$vh} / 100) - 9%)
mjsarfatti
Para o meu caso de uso, isso funcionou muito bem e ainda melhor depois que eu removi o -9%.
Ben Fleming
12

Todas as respostas aqui estão usando a windowaltura, que é afetada pela barra de URL. Todo mundo se esqueceu da screenaltura?

Aqui está a minha solução 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);
  }
});

A adição da .css()peça está alterando o elemento posicionado absoluto inevitavelmente alinhado na parte superior para alinhado na parte inferior, para que não haja nenhum salto. Embora, suponha que não há razão para não adicionar isso diretamente ao CSS normal.

Precisamos do farejador do agente do usuário, pois a altura da tela nos desktops não seria útil.

Além disso, tudo isso é assumido #backgroundcomo um elemento de posição fixa que preenche a janela.

Para os puristas do JavaScript (aviso - não testado):

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

EDIT: Desculpe, isso não responde diretamente ao seu problema específico com mais de um plano de fundo. Mas este é um dos primeiros resultados ao procurar esse problema de fundos fixos saltando no celular.

cr0ybot
fonte
2
Eu tentei um milhão dessas respostas e esta é de longe a melhor. Originalmente, eu estava tentando usar isso em apenas <body>, pois tinha o fundo. O uso de uma div para quebrar a página inteira causou outros problemas. Usar uma div vazia com z-index: -1 como plano de fundo parecia ser a melhor solução combinada com a anterior. Tirei a detecção móvel, pois fazer isso na área de trabalho não faz mal para o meu site. Sem matemática (que pode adivinhar o tamanho das guias incorretas), sem manipulador necessário para redimensionar. O fundo é apenas a tela inteira, ancorada na parte inferior. Feito. Adoro!
Evan Langlois 22/01
9

Também deparei com esse problema quando estava tentando criar uma tela de entrada que abarcasse toda a janela de exibição. Infelizmente, a resposta aceita não funciona mais.

1) Elementos com a altura definida para 100vhser redimensionado toda vez que o tamanho da janela de visualização mudar, incluindo aqueles casos em que é causado por (des) barra de URL que aparece.

2) $(window).height()retorna valores também afetados pelo tamanho da barra de URL.

Uma solução é "congelar" o elemento, transition: height 999999sconforme sugerido na resposta de AlexKempton . A desvantagem é que isso desativa efetivamente a adaptação a todas as alterações no tamanho da janela de exibição, incluindo aquelas causadas pela rotação da tela.

Portanto, minha solução é gerenciar as alterações na viewport manualmente usando JavaScript. Isso me permite ignorar as pequenas alterações que provavelmente são causadas pela barra de URL e reagir apenas às grandes.

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

Edição: Eu realmente uso essa técnica junto com height: 100vh. A página é renderizada corretamente desde o início e, em seguida, o javascript entra em ação e começa a gerenciar a altura manualmente. Dessa forma, não há oscilações durante o carregamento da página (ou mesmo depois).

tobik
fonte
1
Eu usei algo semelhante, mas em vez de definir height: 100vhno CSS inicial, defino min-height:100vhe, em seguida, redimensiono a janela, calculo o valor min-heighte defino-o na altura da porta de exibição. Isso é útil quando o site é visualizado em telas minúsculas e o conteúdo é muito grande para caber na janela de visualização. A debounce / acelerador setTimeout no redimensionamento evento ajuda a melhorar o desempenho em alguns navegadores (redimensionamento tende a fogo muito frequentemente)
Troy Morehouse
Eu acho que, em um determinado momento, também tentei usar, min-heightmas depois me deparei com um problema quando precisava centralizar verticalmente o conteúdo interno. De alguma forma, a centralização vertical pode ficar complicada quando o elemento externo estiver heightdefinido como auto. Então, criei uma altura mínima fixa que deveria ser suficiente para conter qualquer tipo de conteúdo possível e defini-lo no CSS inicial. Como min-heighttem uma prioridade mais alta do que height, funciona muito bem.
Tobik 07/04
Ah, sim, eu tive o mesmo problema, mas o corrigi alterando o jumbotron para display: tablee configurando o contêiner interno para display: table-cellwith vertical-align: middle. Funcionou como um encanto.
Troy Morehouse
Realmente? Porque tentei a mesma abordagem, mas falhei. Eu realmente não me lembro qual era o problema, mas isso pode ser relevante: stackoverflow.com/questions/7790222/...
tobik
Apenas evite o preenchimento percentual ou as margens. Causou alguns problemas estranhos de renderização no IE8, embora os navegadores modernos estivessem bem.
Troy Morehouse
8

A solução que eu estou usando atualmente é verificar o userAgentsobre $(document).readypara ver se ele é um dos navegadores ofender. Se for, siga estes passos:

  1. Defina as alturas relevantes para a altura atual da janela de visualização em vez de '100%'
  2. Armazenar o valor horizontal da viewport atual
  3. Em seguida, $(window).resizeatualize apenas os valores de altura relevantes se a nova dimensão da viewport horizontal for diferente do valor inicial
  4. Armazene os novos valores horizontais e verticais

Opcionalmente, você também pode testar permitindo redimensionamentos verticais somente quando estiverem além da altura da (s) barra (s) de endereço.

Ah, e a barra de endereço afeta $(window).height. Consulte: A barra de endereço do navegador Mobile Webkit (chrome) altera $ (window) .height (); tornando o tamanho do plano de fundo: a capa é redimensionada toda vez que JS "Window" largura-altura vs "tela" largura-altura?

mp
fonte
Eu não tentei isso, mas o seu primeiro ponto não funcionaria no iOS? ( thatemil.com/blog/2013/06/13/… )
Dave Clarke
Eu estava fixando o valor dele no primeiro passo, mas estou surpreso que você tenha encontrado a resposta de Jason para resolver o problema. Como observado, descobri, junto com o outro usuário na pergunta anterior que vinculei, que o valor do método $ (window) .height () muda quando a barra de endereços no chrome no android é ou não é visível. Juntei este pequeno site que apenas revela o resultado de $ (window) .height () em um alerta e ele definitivamente fornece valores diferentes no meu nexus 4 no chrome quando a barra de endereço é / não é visível: stormy-meadow-5908 .herokuapp.com
mp
Isso 100% corrige o problema no meu dispositivo Android, embora eu esteja vendo um problema semelhante no meu iPad, que não parece corrigir o que ainda estou procurando.
Dave Clarke
Você é capaz de fornecer algum código para sua solução e eu o testarei?
Dave Clarke
4

Encontrei uma solução muito fácil sem o uso de Javascript:

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

Tudo o que isso faz é atrasar o movimento, para que seja incrivelmente lento e não seja perceptível.

Pav Sidhu
fonte
@ Tyguy7 Ele funciona muito bem sempre que sua altura não está definido para um valor fixo, ou seja 100%, 100vh. O IE8 é o único navegador principal que não suporta transições.
Pav Sidhu 02/08
Ótima e simples solução!
Zdarsky.peter
3
Isso funciona muito bem até que você esteja em um dispositivo em que possa mudar de retrato para paisagem. Quando isso acontece, o design fica arruinado.
Nagy Nick
@ NagyNick que não era um problema tão grande para mim. Você pode detectar a mudança de orientação em Javascript e ajustar a imagem de fundo.
Pav Sidhu 10/01
3

Minha solução envolveu um pouco de javascript. Mantenha 100% ou 100vh na div (isso evitará que a div não apareça no carregamento da página inicial). Depois, quando a página carregar, agarre a altura da janela e aplique-a ao elemento em questão. Evita o salto, porque agora você tem uma altura estática no seu div.

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

$hero.css('height', h);
Todd Miller
fonte
3

Criei uma solução javascript de baunilha para usar unidades VH. O uso do VH em praticamente qualquer lugar é efetuado pelas barras de endereço, minimizando a rolagem. Para corrigir o jank que mostra quando a página é redesenhada, eu tenho esses js aqui que capturam todos os seus elementos usando unidades VH (se você der a classe .vh-fix) e oferecem alturas de pixel embutidas. Congelando-os essencialmente na altura que queremos. Você pode fazer isso na rotação ou na alteração do tamanho da janela de exibição para permanecer responsivo.

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

Isso resolveu todos os meus casos de uso, espero que ajude.

Geek Devigner
fonte
3

esta é a minha solução para resolver esse problema, adicionei comentários diretamente no código. Eu testei esta solução e funciona bem. Espero que estejamos úteis para que todos tenham o mesmo problema.

//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
  }); 
};
lino
fonte
1
Você está chamando setHeight () dentro do método changeHeight se a consulta corresponder e também se não corresponder. Portanto, basta remover a instrução if, pois não é necessária.
Dennis Meissner
2

Esta é a melhor solução (mais simples) acima de tudo que tentei.

... E isso não mantém a experiência nativa da barra de endereços !

Você pode definir a altura com CSS como 100%, por exemplo, e depois definir a altura como 0,9 * da altura da janela em px com javascript, quando o documento for carregado.

Por exemplo, com jQuery:

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

)

Infelizmente, não há nada que funcione com CSS: P puro, mas também que seja minucioso vhe com problemas vwnos iPhones - use porcentagens.


fonte
1

Defino meu elemento de largura, com javascript. Depois de definir o 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");

Isso funciona para mim. Eu não uso o jquery ect. porque eu quero que ele carregue o mais rápido possível.

Johan Hoeksma
fonte
1

Demorou algumas horas para entender todos os detalhes desse problema e descobrir a melhor implementação. Acontece que, a partir de abril de 2016, apenas o iOS Chrome tem esse problema. Eu tentei no Android Chrome e no iOS Safari - ambos estavam bem sem essa correção. Portanto, a correção para o iOS Chrome que estou usando é:

$(document).ready(function() {
   var screenHeight = $(window).height();
   $('div-with-background-image').css('height', screenHeight + 'px');
});
littlequest
fonte
1

Resposta simples, se o seu plano de fundo permitir, por que não definir o tamanho do plano de fundo: para algo que cubra a largura do dispositivo com consultas de mídia e use ao lado da posição: depois: fixa; hackear aqui .

IE: tamanho do plano de fundo: 901px; para qualquer tela <900px? Não é perfeito ou responsivo, mas funcionou um charme para mim em dispositivos móveis <480px, pois estou usando um BG abstrato.

EasterMedia
fonte
0

Estou usando esta solução alternativa: Corrija a altura do bg1 no carregamento da página:

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

Em seguida, anexe um ouvinte de evento de redimensionamento à janela que faça isso: se a diferença de altura após o redimensionamento for menor que 60px (qualquer coisa além da altura da barra de URL), não faça nada e se for maior que 60px, defina novamente a altura do bg1 para a altura do pai! código completo:

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: Este bug é tão irritante!

AadityaTaparia
fonte
0

Semelhante à resposta @AlexKempton. (não foi possível comentar, desculpe)

Eu tenho usado longos atrasos de transição para impedir o redimensionamento do elemento.

por exemplo:

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

A desvantagem disso é que ele evita o redimensionamento do elemento, inclusive na rotação do dispositivo; no entanto, você pode usar algumas JS para detectar orientationchangee redefinir a altura, se houver algum problema.

Chris Anderson
fonte
0

Para aqueles que desejam ouvir a altura interna real e a rolagem vertical da janela enquanto o navegador móvel Chrome faz a transição da barra de URLs de mostrada para oculta e vice-versa, a única solução que encontrei é definir uma função de intervalo e medir a discrepância de window.innerHeightcom seu valor anterior.

Isso introduz este código:

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

Espero que isso seja útil. Alguém conhece uma solução melhor?

Édouard Mercier
fonte
0

A solução que tive quando tive um problema semelhante foi definir a altura do elemento para window.innerHeightcada vez que o touchmoveevento era acionado.

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

Isso faz com que o elemento abranja exatamente 100% da tela disponível o tempo todo, nem mais nem menos. Mesmo durante a barra de endereços, ocultando ou mostrando.

No entanto, é uma pena que tenhamos que criar esse tipo de patch, onde o simples position: fixeddeve funcionar.

Paulo
fonte
0

Com o suporte de propriedades customizadas de CSS (variáveis) no iOS, é possível configurá-las com JS e usá-las apenas no 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);
        }
    }
}
Stephen Saucier
fonte
0

Minha resposta é para todos que vêm aqui (como eu) para encontrar uma resposta para um bug causado pelo endereço oculto / interface do navegador.

A barra de endereço oculta faz com que o evento de redimensionamento seja acionado. Mas diferente de outros eventos de redimensionamento, como alternar para o modo paisagem, isso não altera a largura da janela. Portanto, minha solução é conectar-se ao evento resize e verificar se a largura é a mesma.

// 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
    // ...
});
Erik J.
fonte