【问题标题】:How to detect when the div element width change (not window resize) in JS?如何在 JS 中检测 div 元素宽度何时更改(不是窗口调整大小)?
【发布时间】:2020-06-11 15:45:18
【问题描述】:

我有一个场景,如果 div 元素宽度发生变化,我需要执行一些功能。那么有什么方法可以检测到元素宽度的变化(不是调整窗口大小)。

例如, 我有一个宽度为 300 像素的 DIV 元素,我的窗口在渲染页面时为 800 像素。当我触发一个函数时,我将 div 元素宽度更改为 400px,因此对于默认宽度更改我需要执行一些操作,那么有什么方法可以在纯 JavaScript 中检测元素大小的变化?

【问题讨论】:

  • 如何改变宽度?你设置了内联样式吗?
  • 是的,我正在这样做style.width = "400px"
  • 您始终可以从更改宽度的同一位置触发自定义事件,并在其他地方监听该事件。

标签: javascript html css ecmascript-6


【解决方案1】:

您可以使用MutationObserver。考虑以下示例,当您手动调整 <p> 标记的大小或单击“调整大小”按钮时,该示例将通知您。任何属性突变都会触发观察者,因此您需要根据需要进行过滤。

const p = document.querySelector("p");
const button = document.querySelector("button");

const p$ = new MutationObserver((mutationList, observer) => {
  for (mutation of mutationList) {
    console.log(mutation);
  }
});

p$.observe(p, {
  attributes: true,
  childList: false,
  subtree: false
});

button.addEventListener("click", () => {
  p.style.width = "100px";
});
.wrapper {
  width: 400px;
}

.resizable {
  resize: both;
  overflow: scroll;
  border: 1px solid black;
}
<div class="wrapper">
  <p class="resizable">Hello</p>
  <button>Resize</button>
</div>

【讨论】:

  • 这行得通,除非使用的值是动态的或样式表定义的(例如%vhvwanimationtransition@mediavar()等)
  • @FZs 嗯,是的,你是对的。我会等待 OP 说是否需要解决这些情况。您可以添加 animationiteration 或其他动画事件侦听器。基于% 的会特别棘手。
  • @zero298,正如你所提到的,有没有办法检查父处理程序宽度的变化,当 div 将成为父级的 100% 宽度时?。
【解决方案2】:

您可以使用MutationObserver 实例并查找style 属性的任何更改

var element = document.getElementById('d');

var observer = new MutationObserver(function() {
   console.log("You changed the style") 
});


observer.observe(element, { attributeFilter: ['style'] });


setTimeout(()=>{
   element.style.width = '400px';
}, 2000)
#d {
   width: 300px;
   height: 300px;
   background: #9bc;
}
&lt;div id="d"&gt;&lt;/div&gt;

如果您改为应用具有给定宽度的 class,则在 attributeFilter 中监听类的任何更改。

【讨论】:

  • 这行得通,除非使用的值是动态的或样式表定义的(例如%vhvwanimationtransition@mediavar()等)
  • 是的,它是根据他们在评论中指定的 OP 的特定用例量身定制的
【解决方案3】:

完美的解决方案是ResizeObserver,但到目前为止,它有not-too-good cross-browser support

但是,它可以在最新的 Chrome、FF 和其他一些版本中运行:

const elem = document.querySelector('#sizeobserver')

new ResizeObserver(console.log).observe(elem)
#sizeobserver {
   resize: both;
   overflow: hidden;
   border: 1px solid black;
}
&lt;div id="sizeobserver"&gt;Resize me!&lt;/div&gt;

要忽略高度变化,您可以检查contentRectwidth 属性。现在只记录宽度的变化:

const elem = document.querySelector('#sizeobserver')
{ // <--Just to encapsulate prevWidth
  let prevWidth
  new ResizeObserver(changes => {
    for(const change of changes){
      if(change.contentRect.width === prevWidth) return
      prevWidth = change.contentRect.width

      //Code here:
      console.log(change)
    }
  }).observe(elem)
}
#sizeobserver {
   resize: both;
   overflow: hidden;
   border: 1px solid black;
}
&lt;div id="sizeobserver"&gt;Resize me!&lt;/div&gt;

【讨论】:

    猜你喜欢
    • 2014-01-15
    • 2011-02-15
    • 2013-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多