MutationObserver: Как наблюдать мутации в ширине / высоте гибкого ребенка? - PullRequest
0 голосов
/ 17 января 2019

Учитывая следующую структуру DOM ...

<div id="outer-container">
  <div class="side-panel"><div width="200px"/></div>
  <div id="content"><!-- some content --></div>
  <div class="side-panel"><div width="100px"/></div>
</div>

Со следующими правилами CSS ...

#outer-container {
  display: 'flex';
  align-items: 'stretch';
  width: '100vw';
  height: '100vh';
}

.side-panel {
  flex-shrink: 0;
}

#content {
  display: 'flex';
  flex-direction: 'column';
  align-items: 'stretch';
  flexGrow: 1;
}

Как я могу наблюдать мутации в ширину / высоту #content?

Обычно это делается путем наблюдения мутаций в атрибуте style и проверки границ элемента (или некоторого другого варианта), когда стиль изменился. Однако, будучи гибким контейнером и потомком, я замечаю, что когда я проверяю ширину / высоту элемента, они не определяются.

Изменение размера #content не приводит к событиям от моего MutationObserver (который использует следующую конфигурацию: {attributes: true, attributeFilter: ['style']})

Мой пример использования здесь - превратить боковые панели в выдвижные ящики, когда ширина #content уменьшается ниже некоторого определенного порога. Я работаю с React, однако это похоже на проблему с html / js.

Помощь с благодарностью!

PS: я пытался установить flex-basis на #content на выбранный мной порог, но это не помогло. Интересно, стоит ли мне определять width вместо flex-basis ... однако я не уверен, приведет ли это к нежелательному поведению при изгибе.

1 Ответ

0 голосов
/ 17 января 2019

Вы можете использовать свойства offsetWidth / offsetHeight , метод getBoundingClientRect () или getComputedStyle () метод внутри функции говорит: checkWidth() затем вызывайте функцию всякий раз, когда событие или функция изменяет размеры вашего элемента.

Например, событие resize изменит размеры вашего элемента, поэтому запускайте эту функцию при возникновении события resize.


Проверьте и запустите следующий фрагмент кода , затем измените размер вашего браузера или нажмите кнопку для практического примера того, что я описал выше:

/* JavaScript */

function checkWidth(){
  let e = document.getElementById("content");
  let widthA = window.getComputedStyle(e).width;
  let widthB = e.getBoundingClientRect().width;
  let widthC = e.offsetWidth;

  console.log("getComputedStyle: " + widthA);
  console.log("getBoundingClientRect: " + widthB);
  console.log("offsetWidth: " + widthC);
};

window.addEventListener("resize", checkWidth); //checkWidth() added since "resize" alters your element's dimensions

function editContent(){
  let e = document.getElementById("content");
  e.style.width = "300px";
  
  checkWidth(); //checkWidth() added since editContent() alters your element's dimensions
}

document.getElementById("btn").addEventListener("click", editContent);
/* CSS */

#outer-container {
  display: flex;
  align-items: stretch;
  width: 100vw;
  height: 100vh;
}

.side-panel {
  flex-shrink: 0;
}

#content {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  flex-grow: 1;
}
<!-- HTML -->

<button id="btn">Click Me</button>
<hr/>
<div id="outer-container">
  <div class="side-panel">
    <div style="width: 200px">Left</div>
  </div>
  <div id="content">Middle</div>
  <div class="side-panel">
    <div style="width: 100px">Right</div>
  </div>
</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...