Eu tenho o seguinte exemplo html, há um DIV que tem 100% de largura. Ele contém alguns elementos. Ao realizar o redimensionamento das janelas, os elementos internos podem ser reposicionados e a dimensão da div pode mudar. Estou perguntando se é possível conectar o evento de mudança de dimensão da div? e como fazer isso? Atualmente, eu vinculo a função de retorno de chamada ao evento de redimensionamento do jQuery no DIV de destino, no entanto, nenhum log do console é gerado, veja abaixo:
<html>
<head>
<script type="text/javascript" language="javascript" src="http://code.jquery.com/jquery-1.6.1.min.js"></script>
<script type="text/javascript" language="javascript">
$('#test_div').bind('resize', function(){
console.log('resized');
});
</script>
</head>
<body>
<div id="test_div" style="width: 100%; min-height: 30px; border: 1px dashed pink;">
<input type="button" value="button 1" />
<input type="button" value="button 2" />
<input type="button" value="button 3" />
</div>
</body>
</html>
javascript
jquery
html
William Choi
fonte
fonte
setInterval
aqui como uma possível solução. Você sempre pode vincularclearInterval
a um clique no botão para interromper o loop assim que seu trabalho estiver concluído.Respostas:
Existe um método muito eficiente para determinar se o tamanho de um elemento foi alterado.
http://marcj.github.io/css-element-queries/
Esta biblioteca possui uma classe
ResizeSensor
que pode ser usada para a detecção de redimensionamento.Ele usa uma abordagem baseada em eventos, por isso é muito rápido e não perde tempo de CPU.
Exemplo:
Por favor, não use o plugin jQuery onresize, pois ele
setTimeout()
combina com a leitura do DOMclientHeight
/clientWidth
propriedades em um loop para verificar se há alterações.Isso é incrível, lento e impreciso, pois causa uma desorganização no layout .
Divulgação: estou diretamente associado a esta biblioteca.
fonte
requestAnimationFrame
vssetTimeout
é irrelevante, esta biblioteca não se repete .requestAnimationFrame
é usado apenas para rejeitar / acelerar a frequência de chamadas de retorno de chamada, ele não pesquisa . O MutationObserver poderia, teoricamente, ser usado para um efeito semelhante, mas não em navegadores antigos, diferentemente disso. Isso é extremamente inteligente.Um novo padrão para isso é a API Resize Observer, disponível no Chrome 64.
Redimensionar observador
Spec: https://wicg.github.io/ResizeObserver
Polyfills: https://github.com/WICG/ResizeObserver/issues/3
Edição do Firefox: https://bugzil.la/1272409
Problema no Safari: http://wkb.ug/157743
Suporte atual: http://caniuse.com/#feat=resizeobserver
fonte
Você precisa vincular o
resize
evento aowindow
objeto, não a um elemento html genérico.Você pode usar isso:
e dentro da função de retorno de chamada, você pode verificar a nova largura da sua
div
chamadaPortanto, a resposta para sua pergunta é não , você não pode vincular o
resize
evento a uma div.fonte
A longo prazo, você poderá usar o ResizeObserver .
Infelizmente, atualmente não é suportado por padrão em muitos navegadores.
Enquanto isso, você pode usar funções como as seguintes. Desde então, a maioria das alterações no tamanho do elemento virá do redimensionamento da janela ou da alteração de algo no DOM. Você pode ouvir o redimensionamento da janela com o evento de redimensionamento da janela e as alterações do DOM usando o MutationObserver .
Aqui está um exemplo de uma função que retornará a ligação quando o tamanho do elemento fornecido for alterado como resultado de um desses eventos:
fonte
body
exemplo, é possível assistir diretamente a um elemento. Isso é realmente mais eficiente e eficiente do que observar todo o corpo.O ResizeSensor.js faz parte de uma enorme biblioteca, mas reduzi sua funcionalidade para ISTO :
Como usá-lo:
fonte
parseInt( getComputedStyle(element) )
Eu não recomendo o
setTimeout()
hack, pois diminui o desempenho! Em vez disso, você pode usar observadores de mutação DOM para ouvir a alteração do tamanho da Div.JS:
HTML:
Aqui está o violino
Tente alterar o tamanho da div.
Você também pode agrupar seu método no
debounce
método para melhorar a eficiência.debounce
acionará seu método a cada x milissegundos em vez de acionar a cada milissegundo que o DIV está sendo redimensionado.fonte
A melhor solução seria usar as chamadas consultas de elemento . No entanto, eles não são padrão, não existe especificação - e a única opção é usar uma das bibliotecas / polyfills disponíveis, se você quiser seguir esse caminho.
A idéia por trás das consultas de elemento é permitir que um determinado contêiner na página responda ao espaço fornecido a ele. Isso permitirá escrever um componente uma vez e soltá-lo em qualquer lugar da página, enquanto ajusta seu conteúdo para o tamanho atual. Não importa qual é o tamanho da janela. Essa é a primeira diferença que vemos entre consultas de elemento e consultas de mídia. Todo mundo espera que, em algum momento, seja criada uma especificação que padronize as consultas de elementos (ou algo que atinja o mesmo objetivo) e as torne nativas, limpas, simples e robustas. A maioria das pessoas concorda que as consultas de mídia são bastante limitadas e não ajudam no design modular e na capacidade de resposta verdadeira.
Existem alguns polyfills / bibliotecas que resolvem o problema de maneiras diferentes (podem ser chamadas de soluções alternativas em vez de soluções):
Eu já vi outras soluções propostas para problemas semelhantes. Geralmente eles usam temporizadores ou o tamanho da janela / janela de visualização embaixo do capô, o que não é uma solução real. Além disso, acho que idealmente isso deve ser resolvido principalmente em CSS, e não em javascript ou html.
fonte
Encontrei esta biblioteca para trabalhar quando a solução de MarcJ não funcionou:
https://github.com/sdecima/javascript-detect-element-resize
É muito leve e detecta até redimensionamentos naturais via CSS ou simplesmente o carregamento / renderização de HTML.
Exemplo de código (extraído do link):
fonte
Dê uma olhada neste http://benalman.com/code/projects/jquery-resize/examples/resize/
Tem vários exemplos. Tente redimensionar sua janela e veja como os elementos dentro dos elementos do contêiner foram ajustados.
Exemplo com js fiddle para explicar como fazê-lo funcionar.
Dê uma olhada neste violino http://jsfiddle.net/sgsqJ/4/
Nesse evento resize () é vinculado a um elemento que possui a classe "test" e também ao objeto window e no redimensionamento de retorno de chamada do objeto $ ('. Test'). Resize () é chamado.
por exemplo
fonte
Você pode usar
iframe
ouobject
usarcontentWindow
oucontentDocument
redimensionar. SemsetInterval
ousetTimeout
Os passos:
relative
IFRAME.contentWindow
-onresize
eventoUm exemplo de HTML:
O Javascript:
Exemplo de execução
JsFiddle: https://jsfiddle.net/qq8p470d/
Ver mais:
element-resize-event
fonte
IFRAME.contentWindow
não estará disponível até que oonload
evento seja disparado no iframe. Além disso, convém adicionar o estilovisibility:hidden;
, pois o iframe pode bloquear a entrada do mouse nos elementos por trás dele (parece estar "flutuando" no IE, pelo menos).display
propriedade do elemento.Somente o objeto de janela gera um evento "redimensionar". A única maneira que eu sei de fazer o que você quer fazer é executar um temporizador de intervalo que verifique periodicamente o tamanho.
fonte
fonte
Surpreendentemente, por mais antigo que seja esse problema, ele ainda é um problema na maioria dos navegadores.
Como já foi dito, o Chrome 64+ é lançado com o Resize Observes de forma nativa, no entanto, as especificações ainda estão sendo ajustadas e o Chrome está atualmente (a partir de 2019-01-29) por trás da última edição da especificação .
Eu já vi alguns polifills ResizeObserver bons na natureza, no entanto, alguns não seguem as especificações de perto e outros têm alguns problemas de cálculo.
Eu precisava desesperadamente desse comportamento para criar alguns componentes da Web responsivos que poderiam ser usados em qualquer aplicativo. Para fazê-los funcionar bem, eles precisam conhecer suas dimensões o tempo todo, para que ResizeObservers parecesse ideal e eu decidi criar um polyfill que seguisse as especificações o mais próximo possível.
Repo: https://github.com/juggle/resize-observer
Demonstração: https://codesandbox.io/s/myqzvpmmy9
fonte
Usando o Clay.js ( https://github.com/zzarcon/clay ), é bastante simples detectar alterações no tamanho do elemento:
fonte
Esta postagem do blog me ajudou a detectar com eficiência alterações de tamanho nos elementos DOM.
http://www.backalleycoder.com/2013/03/18/cross-browser-event-based-element-resize-detection/
Como usar este código ...
Código empacotado usado pelo exemplo ...
Nota: AppConfig é um espaço para nome / objeto que eu uso para organizar funções reutilizáveis. Sinta-se livre para pesquisar e substituir o nome por qualquer coisa que você desejar.
fonte
Meu plugin jQuery habilita o evento "redimensionar" em todos os elementos e não apenas no
window
.https://github.com/dustinpoissant/ResizeTriggering
fonte
Você pode tentar o código no seguinte trecho, que cobre suas necessidades usando javascript comum. ( execute o snippet de código e clique no link de página inteira para acionar o alerta de que a div é redimensionada se você quiser testá-la. ).
Você pode verificar o violino também
ATUALIZAR
Updated Fiddle
fonte
Essa é praticamente uma cópia exata da resposta principal, mas, em vez de um link, é apenas a parte do código que importa, traduzida para ser IMO mais legível e fácil de entender. Algumas outras pequenas mudanças incluem o uso de cloneNode () e não a inserção de html em uma string js. Coisas pequenas, mas você pode copiar e colar como está e funcionará.
A maneira como funciona é fazer duas divs invisíveis preencherem o elemento que você está assistindo e, em seguida, colocar um gatilho em cada uma delas e definir uma posição de rolagem que levará a uma mudança de rolagem se o tamanho mudar.
Todo o crédito real é para Marc J, mas se você está apenas procurando pelo código relevante, aqui está:
fonte
Solução Javascript pura, mas funciona apenas se o elemento for redimensionado com o botão redimensionar css :
offsetWidth
eoffsetHeight
armazenados e, se diferente, faça o que deseja e atualize esses valores.fonte
Aqui está uma versão simplificada da solução por @nkron, aplicável a um único elemento (em vez de uma matriz de elementos na resposta do @ nkron, complexidade que eu não precisava).
O ouvinte e o observador de eventos podem ser removidos por:
fonte
fonte
usando a resposta Bharat Patil simplesmente retorne false dentro do retorno de chamada do bind para evitar o erro máximo da pilha, veja o exemplo abaixo:
fonte
Essa é uma pergunta muito antiga, mas achei que postaria minha solução para isso.
Eu tentei usar,
ResizeSensor
já que todo mundo parecia ter uma queda muito grande por isso. Após a implementação, percebi que, sob o capô, a consulta do elemento exige que o elemento em questão tenha posiçãorelative
ou seabsolute
aplique a ele, o que não funcionou para a minha situação.Acabei lidando com isso com um Rxjs em
interval
vez de implementações anteriores diretassetTimeout
ourequestAnimationFrame
semelhantes.O legal do sabor observável de um intervalo é que você pode modificar o fluxo, mas qualquer outro observável pode ser tratado. Para mim, uma implementação básica foi suficiente, mas você pode enlouquecer e fazer todo tipo de fusão, etc.
No exemplo abaixo, estou acompanhando as alterações de largura da div interna (verde). Tem uma largura definida para 50%, mas uma largura máxima de 200px. Arrastar o controle deslizante afeta a largura da div do wrapper (cinza). Você pode ver que o observável é acionado apenas quando a largura da div interna é alterada, o que só acontece se a largura da div externa for menor que 400px.
fonte
Window.onResize
Existe apenas na especificação, mas você sempre pode utilizarIFrame
para gerar um novoWindow
objeto dentro do seu DIV.Por favor, verifique esta resposta . Existe um novo plugin jquery pequeno , portátil e fácil de usar. Você sempre pode verificar o código-fonte para ver como é feito.
fonte
Eu pensei que não poderia ser feito, mas então eu pensei sobre isso, você pode redimensionar manualmente uma div via style = "resize: both;" para fazer isso, clique nele para adicionar uma função onclick para verificar a altura e a largura do elemento e ele funcionou. Com apenas 5 linhas de javascript puro (com certeza pode ser ainda mais curto) http://codepen.io/anon/pen/eNyyVN
fonte