I have HTML code, it has a div that is 100% wide. It contains several elements. When the window is resized, the inner elements can be regrouped, and the size of the div can change.

Is it possible to connect a resizing div? And how to do it?

Currently, I bind the callback function to the resize jQuery event to the desired div, but the result is not displayed, see Below:

enter image description here enter image description here

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

2 answers 2

There is a very effective method for determining whether an element has been resized.

http://marcj.imtqy.com/css-element-queries/

Library code:

 /** * Copyright Marc J. Schmidt. See the LICENSE file at the top-level * directory of this distribution and at * https://github.com/marcj/css-element-queries/blob/master/LICENSE. */ ; (function(root, factory) { if (typeof define === "function" && define.amd) { define(factory); } else if (typeof exports === "object") { module.exports = factory(); } else { root.ResizeSensor = factory(); } }(this, function() { // Make sure it does not throw in a SSR (Server Side Rendering) situation if (typeof window === "undefined") { return null; } // Only used for the dirty checking, so the event callback count is limited to max 1 call per fps per sensor. // In combination with the event based resize sensor this saves cpu time, because the sensor is too fast and // would generate too many unnecessary events. var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || function(fn) { return window.setTimeout(fn, 20); }; /** * Iterate over each of the provided element(s). * * @param {HTMLElement|HTMLElement[]} elements * @param {Function} callback */ function forEachElement(elements, callback) { var elementsType = Object.prototype.toString.call(elements); var isCollectionTyped = ('[object Array]' === elementsType || ('[object NodeList]' === elementsType) || ('[object HTMLCollection]' === elementsType) || ('[object Object]' === elementsType) || ('undefined' !== typeof jQuery && elements instanceof jQuery) //jquery || ('undefined' !== typeof Elements && elements instanceof Elements) //mootools ); var i = 0, j = elements.length; if (isCollectionTyped) { for (; i < j; i++) { callback(elements[i]); } } else { callback(elements); } } /** * Class for dimension change detection. * * @param {Element|Element[]|Elements|jQuery} element * @param {Function} callback * * @constructor */ var ResizeSensor = function(element, callback) { /** * * @constructor */ function EventQueue() { var q = []; this.add = function(ev) { q.push(ev); }; var i, j; this.call = function() { for (i = 0, j = q.length; i < j; i++) { q[i].call(); } }; this.remove = function(ev) { var newQueue = []; for (i = 0, j = q.length; i < j; i++) { if (q[i] !== ev) newQueue.push(q[i]); } q = newQueue; } this.length = function() { return q.length; } } /** * * @param {HTMLElement} element * @param {Function} resized */ function attachResizeEvent(element, resized) { if (!element) return; if (element.resizedAttached) { element.resizedAttached.add(resized); return; } element.resizedAttached = new EventQueue(); element.resizedAttached.add(resized); element.resizeSensor = document.createElement('div'); element.resizeSensor.className = 'resize-sensor'; var style = 'position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: hidden; z-index: -1; visibility: hidden;'; var styleChild = 'position: absolute; left: 0; top: 0; transition: 0s;'; element.resizeSensor.style.cssText = style; element.resizeSensor.innerHTML = '<div class="resize-sensor-expand" style="' + style + '">' + '<div style="' + styleChild + '"></div>' + '</div>' + '<div class="resize-sensor-shrink" style="' + style + '">' + '<div style="' + styleChild + ' width: 200%; height: 200%"></div>' + '</div>'; element.appendChild(element.resizeSensor); if (element.resizeSensor.offsetParent !== element) { element.style.position = 'relative'; } var expand = element.resizeSensor.childNodes[0]; var expandChild = expand.childNodes[0]; var shrink = element.resizeSensor.childNodes[1]; var dirty, rafId, newWidth, newHeight; var lastWidth = element.offsetWidth; var lastHeight = element.offsetHeight; var reset = function() { expandChild.style.width = '100000px'; expandChild.style.height = '100000px'; expand.scrollLeft = 100000; expand.scrollTop = 100000; shrink.scrollLeft = 100000; shrink.scrollTop = 100000; }; reset(); var onResized = function() { rafId = 0; if (!dirty) return; lastWidth = newWidth; lastHeight = newHeight; if (element.resizedAttached) { element.resizedAttached.call(); } }; var onScroll = function() { newWidth = element.offsetWidth; newHeight = element.offsetHeight; dirty = newWidth != lastWidth || newHeight != lastHeight; if (dirty && !rafId) { rafId = requestAnimationFrame(onResized); } reset(); }; var addEvent = function(el, name, cb) { if (el.attachEvent) { el.attachEvent('on' + name, cb); } else { el.addEventListener(name, cb); } }; addEvent(expand, 'scroll', onScroll); addEvent(shrink, 'scroll', onScroll); } forEachElement(element, function(elem) { attachResizeEvent(elem, callback); }); this.detach = function(ev) { ResizeSensor.detach(element, ev); }; }; ResizeSensor.detach = function(element, ev) { forEachElement(element, function(elem) { if (!elem) return if (elem.resizedAttached && typeof ev == "function") { elem.resizedAttached.remove(ev); if (elem.resizedAttached.length()) return; } if (elem.resizeSensor) { if (elem.contains(elem.resizeSensor)) { elem.removeChild(elem.resizeSensor); } delete elem.resizeSensor; delete elem.resizedAttached; } }); }; return ResizeSensor; })); 

This library has a ResizeSensor class that can be used to determine the size.

It's based on events, so it’s pretty damn fast to detect and not load the processor.

Example:

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

Please do not use the resize plugin for jQuery , as it uses the setTimeout () loop to check for changes.

  • one
    If it's not a secret, where onresize jQuery использует цикл setTimeout() infa onresize jQuery использует цикл setTimeout() ? - diraria
  • @diraria, how do I know? :) I wrote for someone that this is an association? This is a question and answer from enSO - Yuri
  • in general, setTimeout does not use jQuery, but a plugin for it (which, it seems, no one is already using it), I think it is worth clarifying this - diraria
  • one
    @diraria, thanks, clarified - Yuri

The simplest solution:

 var blockWidth = $('.block').outerWidth(); $(window).resize(function() { if (blockWidth != $('.block').outerWidth()) { console.log('resized') } }); 
 .block { max-width:300px; height:100px; background:#000; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="block"></div> 

Specifically on your example:

 var blockWidth = $('#test_div').outerWidth(); $(window).resize(function() { if (blockWidth != $('#test_div').outerWidth()) { console.log('resized') } }); 
 .block { max-width: 300px; height: 100px; background: #000; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <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>