Це дійсно старе питання, але я зрозумів, що опублікую своє рішення щодо цього.
Я намагався використовувати, ResizeSensor
оскільки, здавалося, у всіх досить велика пригніченість. Після впровадження, я зрозумів, що під капотом запит елементів вимагає, щоб відповідний елемент мав позицію relative
або absolute
застосований до нього, що не працювало для моєї ситуації.
Я закінчив обробляти це за допомогою Rxjs interval
замість прямої setTimeout
або requestAnimationFrame
подібної попередньої реалізації.
Що добре в спостережуваному ароматі інтервалу, це те, що ви можете змінити потік, однак будь-який інший спостерігається може бути оброблений. Для мене було достатньо базового втілення, але ви могли зійти з розуму і робити всілякі злиття тощо.
У наведеному нижче прикладі я відстежую внутрішні (зелені) зміни ширини дива. Він має ширину, встановлену на 50%, але максимальну ширину - 200 пікселів. Перетягування повзунка впливає на ширину оболонки (сірого) кольору. Ви можете бачити, що спостережуване справляється лише тоді, коли змінюється ширина внутрішнього діва, що відбувається лише в тому випадку, якщо ширина зовнішнього діва менше 400 пікс.
const { interval } = rxjs;
const { distinctUntilChanged, map, filter } = rxjs.operators;
const wrapper = document.getElementById('my-wrapper');
const input = document.getElementById('width-input');
function subscribeToResize() {
const timer = interval(100);
const myDiv = document.getElementById('my-div');
const widthElement = document.getElementById('width');
const isMax = document.getElementById('is-max');
/*
NOTE: This is the important bit here
*/
timer
.pipe(
map(() => myDiv ? Math.round(myDiv.getBoundingClientRect().width) : 0),
distinctUntilChanged(),
// adding a takeUntil(), here as well would allow cleanup when the component is destroyed
)
.subscribe((width) => {
widthElement.innerHTML = width;
isMax.innerHTML = width === 200 ? 'Max width' : '50% width';
});
}
function defineRange() {
input.min = 200;
input.max = window.innerWidth;
input.step = 10;
input.value = input.max - 50;
}
function bindInputToWrapper() {
input.addEventListener('input', (event) => {
wrapper.style.width = `${event.target.value}px`;
});
}
defineRange();
subscribeToResize();
bindInputToWrapper();
.inner {
width: 50%;
max-width: 200px;
}
/* Aesthetic styles only */
.inner {
background: #16a085;
}
.wrapper {
background: #ecf0f1;
color: white;
margin-top: 24px;
}
.content {
padding: 12px;
}
body {
font-family: sans-serif;
font-weight: bold;
}
<script src="https://unpkg.com/rxjs/bundles/rxjs.umd.min.js"></script>
<h1>Resize Browser width</h1>
<label for="width-input">Adjust the width of the wrapper element</label>
<div>
<input type="range" id="width-input">
</div>
<div id="my-wrapper" class="wrapper">
<div id="my-div" class="inner">
<div class="content">
Width: <span id="width"></span>px
<div id="is-max"></div>
</div>
</div>
</div>