¿Cómo detectar el cambio de dimensión de DIV?

Resuelto William X asked hace 13 años • 28 respuestas

Tengo el siguiente html de muestra, hay un DIV que tiene un ancho del 100%. Contiene algunos elementos. Al cambiar el tamaño de las ventanas, los elementos internos pueden reposicionarse y la dimensión del div puede cambiar. Estoy preguntando si es posible enganchar el evento de cambio de dimensión del div. ¿y como hacer eso? Actualmente vinculo la función de devolución de llamada al evento de cambio de tamaño de jQuery en el DIV de destino; sin embargo, no se genera ningún registro de consola, consulte a continuación:

Antes de cambiar el tamaño ingrese la descripción de la imagen aquí

<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>
William X avatar Jun 27 '11 19:06 William X
Aceptado

Un estándar más nuevo para esto es la API Resize Observer, con buena compatibilidad con el navegador.

function outputsize() {
 width.value = textbox.offsetWidth
 height.value = textbox.offsetHeight
}
outputsize()

new ResizeObserver(outputsize).observe(textbox)
Width: <output id="width">0</output><br>
Height: <output id="height">0</output><br>
<textarea id="textbox">Resize me</textarea><br>
Expandir fragmento

Cambiar el tamaño del observador

Documentación: https://developer.mozilla.org/en-US/docs/Web/API/Resize_Observer_API

Especificación: https://wicg.github.io/ResizeObserver

Soporte actual: http://caniuse.com/#feat=resizeobserver

Polyfills: https://github.com/pelotoncycle/resize-observer https://github.com/que-etc/resize-observer-polyfill https://github.com/juggle/resize-observer

Daniel Herr avatar Sep 04 '2016 00:09 Daniel Herr

Existe un método muy eficaz para determinar si se ha cambiado el tamaño de un elemento.

http://marcj.github.io/css-element-queries/

Esta biblioteca tiene una clase ResizeSensorque se puede utilizar para la detección de cambios de tamaño.
Utiliza un enfoque basado en eventos, por lo que es increíblemente rápido y no desperdicia tiempo de CPU.

Ejemplo:

new ResizeSensor(jQuery('#divId'), function(){ 
    console.log('content dimension changed');
});

No utilice el complemento jQuery onresize , ya que se utiliza setTimeout()en combinación con la lectura de DOM clientHeight/ clientWidthpropiedades en un bucle para comprobar si hay cambios.
Esto es increíblemente lento e inexacto ya que causa cambios en el diseño .

Divulgación: estoy directamente asociado con esta biblioteca.

Marc J. Schmidt avatar Oct 17 '2013 04:10 Marc J. Schmidt

A largo plazo, podrá utilizar ResizeObserver.

new ResizeObserver(callback).observe(element);

Desafortunadamente, actualmente no es compatible de forma predeterminada con muchos navegadores.

Mientras tanto, puede utilizar funciones como la siguiente. Desde entonces, la mayoría de los cambios en el tamaño de los elementos provendrán del cambio de tamaño de la ventana o de cambiar algo en el DOM. Puede escuchar el cambio de tamaño de la ventana con el evento de cambio de tamaño de la ventana y puede escuchar los cambios de DOM usando MutationObserver.

A continuación se muestra un ejemplo de una función que le devolverá la llamada cuando el tamaño del elemento proporcionado cambie como resultado de cualquiera de esos eventos:

var onResize = function(element, callback) {
  if (!onResize.watchedElementData) {
    // First time we are called, create a list of watched elements
    // and hook up the event listeners.
    onResize.watchedElementData = [];

    var checkForChanges = function() {
      onResize.watchedElementData.forEach(function(data) {
        if (data.element.offsetWidth !== data.offsetWidth ||
            data.element.offsetHeight !== data.offsetHeight) {
          data.offsetWidth = data.element.offsetWidth;
          data.offsetHeight = data.element.offsetHeight;
          data.callback();
        }
      });
    };

    // Listen to the window's size changes
    window.addEventListener('resize', checkForChanges);

    // Listen to changes on the elements in the page that affect layout 
    var observer = new MutationObserver(checkForChanges);
    observer.observe(document.body, { 
      attributes: true,
      childList: true,
      characterData: true,
      subtree: true 
    });
  }

  // Save the element we are watching
  onResize.watchedElementData.push({
    element: element,
    offsetWidth: element.offsetWidth,
    offsetHeight: element.offsetHeight,
    callback: callback
  });
};
nkron avatar Sep 22 '2015 05:09 nkron