detect width change in a div and trigger a function Knockout JS

142 views Asked by At

How do I detect when the width of a div with id X changes? I have a function 'wrapLines' which needs to be called whenever this div container's width changes. because of following reasons

  1. whether the window got resized
  2. or any other reason like a collapsible menu opening up causing x div to decrease in width

Application uses Knockout JS and OJET(Oracle JET). so there is view and viewModel defined for html and respective js. Please help.

I tried to use window.resize like mentioned below but it doesn't work-

$("#" + x).on('resize', function(event) {
    //call wrapLines function         
});

The code below works but only for case 1. I need case 2 to pass.

$(window).on('resize', function(event) {
   //call wrapLines function               
});
2

There are 2 answers

0
Ghost On BEST ANSWER

Use the ResizeObserver API.

const elem = document.getElementById("element");
let prevWidth;
new ResizeObserver(([change]) => {
  if ((prevWidth = change.contentRect.width) == prevWidth) {
    console.log(prevWidth);
  }
}).observe(elem);
#element {
   resize: horizontal;
   overflow: hidden;
   border: 1px solid black;
}
<div id="element">I can be resized!</div>

0
Martlark On

I've used the ResizeObserver to create a KnockoutJS binding handler to deal with change events and update an observable with the new width. Please see jsfiddle example: https://jsfiddle.net/martlark/L03wtzqb/36/

HTML:

<textarea id="element" data-bind="resizeWidth: width, value: value"></textarea>
<h4>
Width
</h4>
<span data-bind="text: width"></span>

Binding handler:

ko.bindingHandlers.resizeWidth = {
  update: function(element, valueAccessor, allBindings) {
    const value = valueAccessor();

    new ResizeObserver(([change]) => {
        value(change.contentRect.width);
    }).observe(element);
  }
};

View controller:

class ViewModel {
  constructor() {
    this.value = ko.observable('something');
    this.width = ko.observable(0);
    this.width.subscribe(newValue=>{console.log('resize', newValue)})
  }
}

viewModel = new ViewModel()
ko.applyBindings(viewModel);