jQuery tiene el resize()
evento -, pero solo funciona con window.
jQuery(window).resize(function() { /* What ever */ });
¡Esto funciona bien! Pero cuando quiero agregar el evento a un elemento div, no funciona.
P.ej
jQuery('div').resize(function() { /* What ever */ });
Quiero iniciar una devolución de llamada cuando el tamaño de un elemento div haya cambiado. No quiero iniciar un evento de tamaño variable, solo un evento para verificar si el tamaño de un elemento div ha cambiado.
¿Existe alguna solución para hacer esto?
javascript
jquery
TJR
fuente
fuente
Respuestas:
DIV
no dispara unresize
evento, por lo que no podrá hacer exactamente lo que ha codificado, pero podría considerar monitorear las propiedades del DOM .Si en realidad está trabajando con algo como resizables, y esa es la única forma de que un div cambie de tamaño, entonces su complemento de cambio de tamaño probablemente implementará una devolución de llamada propia.
fuente
Solo estaba interesado en un disparador cuando se cambiaba el ancho de un elemento (no me importa la altura), así que creé un evento jquery que hace exactamente eso, usando un elemento iframe invisible.
$.event.special.widthChanged = { remove: function() { $(this).children('iframe.width-changed').remove(); }, add: function () { var elm = $(this); var iframe = elm.children('iframe.width-changed'); if (!iframe.length) { iframe = $('<iframe/>').addClass('width-changed').prependTo(this); } var oldWidth = elm.width(); function elmResized() { var width = elm.width(); if (oldWidth != width) { elm.trigger('widthChanged', [width, oldWidth]); oldWidth = width; } } var timer = 0; var ielm = iframe[0]; (ielm.contentWindow || ielm).onresize = function() { clearTimeout(timer); timer = setTimeout(elmResized, 20); }; } }
Requiere el siguiente CSS:
iframe.width-changed { width: 100%; display: block; border: 0; height: 0; margin: 0; }
Puedes verlo en acción aquí widthChanged violín
fuente
var ss = document.createElement('style'); ss.type = "text/css"; ss.innerHTML = "iframe.width-changed {width: 100%;display: block;border: 0;height: 0;margin: 0;}"; document.body.appendChild(ss);
// this is a Jquery plugin function that fires an event when the size of an element is changed // usage: $().sizeChanged(function(){}) (function ($) { $.fn.sizeChanged = function (handleFunction) { var element = this; var lastWidth = element.width(); var lastHeight = element.height(); setInterval(function () { if (lastWidth === element.width()&&lastHeight === element.height()) return; if (typeof (handleFunction) == 'function') { handleFunction({ width: lastWidth, height: lastHeight }, { width: element.width(), height: element.height() }); lastWidth = element.width(); lastHeight = element.height(); } }, 100); return element; }; }(jQuery));
fuente
Creé el complemento jquery jquery.resize , use resizeObserver si es compatible o una solución basada en el evento de desplazamiento marcj / css-element-queries , sin setTimeout / setInterval.
Usas solo
jQuery('div').on('resize', function() { /* What ever */ });
o como complemento de cambio de tamaño
jQuery('div').resizer(function() { /* What ever */ });
Creé esto para jQuery Terminal y lo extraje en un repositorio separado y un paquete npm, pero mientras tanto cambié a iframe oculto porque tuve problemas con el cambio de tamaño si el elemento estaba dentro de iframe. Puedo actualizar el complemento en consecuencia. Puede ver el complemento de cambio de tamaño basado en iframe en el código fuente de jQuery Terminal .
EDITAR : la nueva versión usa iframe y cambia el tamaño de su objeto de ventana porque las soluciones anteriores no funcionaban cuando la página estaba dentro de iframe.
EDIT2 : debido a que el iframe de respaldo no puede usarlo con controles de formulario o imágenes, debe agregarlo al elemento contenedor.
EDIT3: hay una mejor solución usando resizeObserver polyfill que usa el observador de mutación (si resizeObserver no es compatible) y funciona incluso en IE. También tiene mecanografía de TypeScript.
fuente
que hay de esto:
divH = divW = 0; jQuery(document).ready(function(){ divW = jQuery("div").width(); divH = jQuery("div").height(); }); function checkResize(){ var w = jQuery("div").width(); var h = jQuery("div").height(); if (w != divW || h != divH) { /*what ever*/ divH = h; divW = w; } } jQuery(window).resize(checkResize); var timer = setInterval(checkResize, 1000);
Por cierto, le sugiero que agregue una identificación al div y cambie $ ("div") a $ ("# yourid"), será más rápido y no se romperá cuando luego agregue otros divs
fuente
resize
que se dispara el evento de la ventana . Es muy posible que el tamaño del div cambie sin ser seguido inmediatamente por un cambio de tamaño de la ventana, en cuyo caso la/* what ever */
parte no sería evaluada.$(window).resize
escucha el acto de cambiar físicamente el tamaño de la ventana del navegador, por ejemplo, arrastrando la esquina inferior derecha. No hay eventos DOM que desencadenan este evento,overflow:hidden
o no. Esta respuesta no resuelve su problema. Tendría más sentido ejecutar este código en un temporizador que adjuntarlo a un detector de eventos aleatorio que probablemente nunca se activará. Sería mejor aún si pudiera usar el monitoreo de propiedades DOM y recurrir a un temporizador (o generar manualmente algún evento en los lugares donde el tamaño de div puede cambiar).Hay un complemento realmente agradable, fácil de usar y liviano (utiliza eventos nativos del navegador para la detección) para JavaScript básico y para jQuery que se lanzó este año. Funciona perfectamente:
https://github.com/sdecima/javascript-detect-element-resize
fuente
Solo se admite la ventana, sí, pero puede usar un complemento para ello: http://benalman.com/projects/jquery-resize-plugin/
fuente
Para una integración de Google Maps, estaba buscando una forma de detectar cuándo un div ha cambiado de tamaño. Dado que los mapas de Google siempre requieren las dimensiones adecuadas, por ejemplo, ancho y alto, para poder renderizarse correctamente.
La solución que se me ocurrió es una delegación de un evento, en mi caso un clic de pestaña. Esto podría ser un cambio de tamaño de ventana, por supuesto, la idea sigue siendo la misma:
if (parent.is(':visible')) { w = parent.outerWidth(false); h = w * mapRatio /*9/16*/; this.map.css({ width: w, height: h }); } else { this.map.closest('.tab').one('click', function() { this.activate(); }.bind(this)); }
this.map
en este caso es mi mapa div. Dado que mi padre es invisible en la carga, el ancho y la altura calculados son 0 o no coinciden. Al usar.bind(this)
puedo delegar la ejecución del script (this.activate
) a un evento (click
).Ahora estoy seguro de que lo mismo se aplica a los eventos de cambio de tamaño.
$(window).one('resize', function() { this.div.css({ /*whatever*/ }); }.bind(this));
¡Espero que ayude a cualquiera!
fuente
Simplemente pruebe esta función (puede que no solo funcione para divs):
function resized(elem, func = function(){}, args = []){ elem = jQuery(elem); func = func.bind(elem); var h = -1, w = -1; setInterval(function(){ if (elem.height() != h || elem.width() != w){ h = elem.height(); w = elem.width(); func.apply(null, args); } }, 100); }
Puedes usarlo así
resized(/*element*/ '.advs-columns-main > div > div', /*callback*/ function(a){ console.log(a); console.log(this); //for accessing the jQuery element you passed }, /*callback arguments in array*/ ['I\'m the first arg named "a"!']);
ACTUALIZACIÓN: también puede usar un observador más progresivo (puede funcionar para cualquier objeto, no solo para elementos DOM):
function changed(elem, propsToBeChanged, func = function(){}, args = [], interval = 100){ func = func.bind(elem); var currentVal = {call: {}, std: {}}; $.each(propsToBeChanged, (property, needCall)=>{ needCall = needCall ? 'call' : 'std'; currentVal[needCall][property] = new Boolean(); // is a minimal and unique value, its equivalent comparsion with each other will always return false }); setInterval(function(){ $.each(propsToBeChanged, (property, needCall)=>{ try{ var currVal = needCall ? elem[property]() : elem[property]; } catch (e){ // elem[property] is not a function anymore var currVal = elem[property]; needCall = false; propsToBeChanged[property] = false; } needCall = needCall ? 'call' : 'std'; if (currVal !== currentVal[needCall][property]){ currentVal[needCall][property] = currVal; func.apply(null, args); } }); }, interval); }
Solo inténtalo:
var b = '2', a = {foo: 'bar', ext: ()=>{return b}}; changed(a, { // prop name || do eval like a function? foo: false, ext: true }, ()=>{console.log('changed')})
Registrará 'cambiado' cada vez que cambie b, a.foo o a.ext directamente
fuente
setInterval
puede resultar bastante caro, ya que sigue intentando cambiar el tamañoconsole.log
justo antes del$.each
, verá que se imprime cada100ms
, como lo configuró en elinterval
setInterval
funciona. Es como un correo electrónico "vivo": hace ping constantemente al servidor. Lo sé. ¿Y qué? ¿Actuación? Lea mi comentario arriba. ¿Preocupado por algo más? Escríbeme, amigo mío.Puede cambiar su texto, contenido o atributo según el tamaño de la pantalla: HTML:
<p class="change">Frequently Asked Questions (FAQ)</p> <p class="change">Frequently Asked Questions </p>
Javascript:
<script> const changeText = document.querySelector('.change'); function resize() { if((window.innerWidth<500)&&(changeText.textContent="Frequently Asked Questions (FAQ)")){ changeText.textContent="FAQ"; } else { changeText.textContent="Frequently Asked Questions (FAQ)"; } } window.onresize = resize; </script>
fuente
Si solo desea cambiar el tamaño del div en sí, debe especificarlo en estilo css. Necesita agregar desbordamiento y cambiar el tamaño de la propiedad .
A continuación se muestra mi fragmento de código
#div1 { width: 90%; height: 350px; padding: 10px; border: 1px solid #aaaaaa; overflow: auto; resize: both; } <div id="div1"> </div>
fuente