Resize on div element

JavascriptJquery

Javascript Problem Overview


jQuery has the resize() - event, but it just work with window.

jQuery(window).resize(function() { /* What ever */ });

This works fine! But when I want to add the event to a div element it doesn't work.

E.g.

jQuery('div').resize(function() { /* What ever */ });

I want to start an callback when the size of a div-element has changed. I don't want to start a resizable - event – just a event to check if the size of a div - element has changed.

Is there any solution to do this?

Javascript Solutions


Solution 1 - Javascript

DIV does not fire a resize event, so you won't be able to do exactly what you've coded, but you could look into monitoring DOM properties.

If you are actually working with something like resizables, and that is the only way for a div to change in size, then your resize plugin will probably be implementing a callback of its own.

Solution 2 - Javascript

I was only interested for a trigger when a width of an element was changed (I don' care about height), so I created a jquery event that does exactly that, using an invisible iframe element.

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

It requires the following css :

iframe.width-changed {
    width: 100%;
    display: block;
    border: 0;
    height: 0;
    margin: 0;
}

You can see it in action here widthChanged fiddle

Solution 3 - Javascript

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

Solution 4 - Javascript

I've created jquery plugin jquery.resize it use resizeObserver if supported or solution based on marcj/css-element-queries scroll event, no setTimeout/setInterval.

You use just

 jQuery('div').on('resize', function() { /* What ever */ });

or as resizer plugin

jQuery('div').resizer(function() { /* What ever */ });

I've created this for jQuery Terminal and extracted into separated repo and npm package, but in a mean time I switched to hidden iframe because I had problems with resize if element was inside iframe. I may update the plugin accordingly. You can look at iframe based resizer plugin in jQuery Terminal source code.

EDIT: new version use iframe and resize on it's window object because the previous solutions was not working when page was inside iframe.

EDIT2: Because the fallback use iframe you can't use it with form controls or images, you need to add it to the wrapper element.

EDIT3:: there is better solution using resizeObserver polyfill that use mutation observer (if resizeObserver is not supported) and work even in IE. It also have TypeScript typings.

Solution 5 - Javascript

what about this:

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

BTW I suggest you to add an id to the div and change the $("div") to $("#yourid"), it's gonna be faster, and it won't break when later you add other divs

Solution 6 - Javascript

There is a really nice, easy to use, lightweight (uses native browser events for detection) plugin for both basic JavaScript and for jQuery that was released this year. It performs perfectly:

https://github.com/sdecima/javascript-detect-element-resize

Solution 7 - Javascript

Only window is supported yes but you could use a plugin for it: http://benalman.com/projects/jquery-resize-plugin/

Solution 8 - Javascript

There now exists Resize Observer

You could use it like so:

const resizeObserver = new ResizeObserver((entries) => {
  entries.forEach(console.log);
})
resizeObserver.observe(document.getElementById("ExampleElement"));

Solution 9 - Javascript

For a google maps integration I was looking for a way to detect when a div has changed in size. Since google maps always require proper dimensions e.g. width and height in order to render properly.

The solution I came up with is a delegation of an event, in my case a tab click. This could be a window resize of course, the idea remains the same:

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 in this case is my map div. Since my parent is invisible on load, the computed width and height are 0 or don't match. By using .bind(this) I can delegate the script execution (this.activate) to an event (click).

Now I'm confident the same applies for resize events.

$(window).one('resize', function() {
    this.div.css({ /*whatever*/ });
}.bind(this));

Hope it helps anyone!

Solution 10 - Javascript

Just try this func (it may work not only for 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);
}

You can use it like this

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"!']);

UPDATE: You can also use more progressive watcher (it can work for any objects, not only DOM elements):

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

Just try it:

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

It will log 'changed' every time when you change b, a.foo or a.ext directly

Solution 11 - Javascript

You can change your text or Content or Attribute depend on Screen size: 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>

Solution 12 - Javascript

document.addEventListener('transitionend', function(e) {
  if ($(e.target).is("div")) {
    $("div").text("width: "+$("div").width());
  }
});
$("div").css({"width":"150px"});

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div style="width: 100px;transition-delay: 0.000000001s;">width: 100</div>

Solution 13 - Javascript

If you just want to resize the div itself you need to specify that in css style. You need to add overflow and resize property.

Below is my code snippet

#div1 {
        width: 90%;
        height: 350px;
        padding: 10px;
        border: 1px solid #aaaaaa;
        overflow: auto;
        resize: both;
    }

<div id="div1">

</div>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTJRView Question on Stackoverflow
Solution 1 - JavascriptDavid HedlundView Answer on Stackoverflow
Solution 2 - JavascriptPanos TheofView Answer on Stackoverflow
Solution 3 - JavascriptAkram Kamal QassasView Answer on Stackoverflow
Solution 4 - JavascriptjcubicView Answer on Stackoverflow
Solution 5 - JavascriptGavrielView Answer on Stackoverflow
Solution 6 - JavascriptDrCordView Answer on Stackoverflow
Solution 7 - JavascriptNielsen RamonView Answer on Stackoverflow
Solution 8 - JavascriptSeph ReedView Answer on Stackoverflow
Solution 9 - JavascriptTim VermaelenView Answer on Stackoverflow
Solution 10 - JavascriptKaMeHbView Answer on Stackoverflow
Solution 11 - JavascriptAmranur RahmanView Answer on Stackoverflow
Solution 12 - JavascriptJabrail MammadovView Answer on Stackoverflow
Solution 13 - JavascriptDillip Kumar NayakView Answer on Stackoverflow