将 window 调整大小和加载页面事件合并到一个函数中

To merge window resizing and loading the page events into one function

我有一个本地 html 页面,为我提供了关于 widthmax-widthmin-width 工作原理的作弊 sheet。它会动态地向您报告 body 和内部 div 的宽度,并相应地更改 div 的背景颜色。

const div = document.querySelector('div');
const body = document.querySelector('body');

const outputDivWidth = document.querySelector('#outputDivWidth');
const outputBodyWidth = document.querySelector('#outputBodyWidth');

function reportWidths() {
  const divWidth = div.offsetWidth;
  const bodyWidth = body.offsetWidth;

  outputDivWidth.textContent = divWidth;
  outputBodyWidth.textContent = bodyWidth;

  if (divWidth >= 500) {
    div.style.backgroundColor = 'rgb(0% 100% 0% / 10%)';
  } else if (divWidth <= 300) {
    div.style.backgroundColor = 'rgb(100% 0% 0% / 10%)';
  } else {
    div.style.backgroundColor = 'rgb(100% 100% 0% / 10%)';
  }
}

reportWidths();
window.addEventListener('resize', () => {
  reportWidths();
});
body {
  outline: blue solid 1px;
}

div {
  outline: red solid 1px;

  /* 500 px if the width of the parent element is ≥ 999 px,
   * 300 px if the width of the parent element is ≤ 600 px,
   * 50% of the width of the parent element otherwise. */
  max-width: 500px; min-width: 300px; width: 50%;
}

p#outputBodyWidth { color: blue; }
p#outputDivWidth { color: red; }
<div>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
  eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
  <p id="outputDivWidth"></p>
</div>
<p id="outputBodyWidth"></p>

这是我不喜欢的部分:

reportWidths();
window.addEventListener('resize', () => {
  reportWidths();
});

在使用使用相同函数的事件侦听器之前使用函数调用对我来说看起来很愚蠢和不专业(注意,我不是真正的网络开发人员),所以我更愿意将其更改为一个-步骤解决方案。但是怎么办?

稍微优雅一点,可以在文档加载事件上调用它。不过,在侦听器中设置函数之前调用函数并没有错。

const div = document.querySelector('div');
const body = document.querySelector('body');

const outputDivWidth = document.querySelector('#outputDivWidth');
const outputBodyWidth = document.querySelector('#outputBodyWidth');

function reportWidths() {
  const divWidth = div.offsetWidth;
  const bodyWidth = body.offsetWidth;

  outputDivWidth.textContent = divWidth;
  outputBodyWidth.textContent = bodyWidth;

  if (divWidth >= 500) {
    div.style.backgroundColor = 'rgb(0% 100% 0% / 10%)';
  } else if (divWidth <= 300) {
    div.style.backgroundColor = 'rgb(100% 0% 0% / 10%)';
  } else {
    div.style.backgroundColor = 'rgb(100% 100% 0% / 10%)';
  }
}

// Calling it on document load instead.
// And since you care about params here, just pass a reference to the function
document.addEventListener("load", reportWidths);
// and also here
window.addEventListener('resize', reportWidths);
body {
  outline: blue solid 1px;
}

div {
  outline: red solid 1px;

  /* 500 px if the width of the parent element is ≥ 999 px,
   * 300 px if the width of the parent element is ≤ 600 px,
   * 50% of the width of the parent element otherwise. */
  max-width: 500px; min-width: 300px; width: 50%;
}

p#outputBodyWidth { color: blue; }
p#outputDivWidth { color: red; }
<div>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
  eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
  <p id="outputDivWidth"></p>
</div>
<p id="outputBodyWidth"></p>

调用函数并将其注册为事件处理程序是正常的。这是两个不同的东西。
也许 reportWidths 在箭头函数中被调用的方式让它看起来像是一个多余的调用。我们不必将其包装在箭头函数中。以下代码实现了相同的目的:

window.addEventListener('resize', reportWidths);
window.addEventListener('load', reportWidths);

这就清楚了为什么我们需要使用该函数两次。


这是另一种方法:

const div = document.querySelector('div');
const body = document.querySelector('body');

const outputDivWidth = document.querySelector('#outputDivWidth');
const outputBodyWidth = document.querySelector('#outputBodyWidth');

function reportWidths() {
  const divWidth = div.offsetWidth;
  const bodyWidth = body.offsetWidth;

  outputDivWidth.textContent = divWidth;
  outputBodyWidth.textContent = bodyWidth;

  if (divWidth >= 500) {
    div.style.backgroundColor = 'rgb(0% 100% 0% / 10%)';
  } else if (divWidth <= 300) {
    div.style.backgroundColor = 'rgb(100% 0% 0% / 10%)';
  } else {
    div.style.backgroundColor = 'rgb(100% 100% 0% / 10%)';
  }
}

window.addEventListener('resize', reportWidths);
window.dispatchEvent(new Event('resize'));
body {
  outline: blue solid 1px;
}

div {
  outline: red solid 1px;

  /* 500 px if the width of the parent element is ≥ 999 px,
   * 300 px if the width of the parent element is ≤ 600 px,
   * 50% of the width of the parent element otherwise. */
  max-width: 500px; min-width: 300px; width: 50%;
}

p#outputBodyWidth { color: blue; }
p#outputDivWidth { color: red; }
<div>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
  eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
  <p id="outputDivWidth"></p>
</div>
<p id="outputBodyWidth"></p>

我们自己抛出 resize 事件,因为它不会在文档加载时引发。


另一种方法是使用 ResizeObserver:

const div = document.querySelector('div');
const body = document.querySelector('body');

const outputDivWidth = document.querySelector('#outputDivWidth');
const outputBodyWidth = document.querySelector('#outputBodyWidth');

function reportWidths() {
  const divWidth = div.offsetWidth;
  const bodyWidth = body.offsetWidth;

  outputDivWidth.textContent = divWidth;
  outputBodyWidth.textContent = bodyWidth;

  if (divWidth >= 500) {
    div.style.backgroundColor = 'rgb(0% 100% 0% / 10%)';
  } else if (divWidth <= 300) {
    div.style.backgroundColor = 'rgb(100% 0% 0% / 10%)';
  } else {
    div.style.backgroundColor = 'rgb(100% 100% 0% / 10%)';
  }
}

new ResizeObserver(reportWidths).observe(body);
body {
  outline: blue solid 1px;
}

div {
  outline: red solid 1px;

  /* 500 px if the width of the parent element is ≥ 999 px,
   * 300 px if the width of the parent element is ≤ 600 px,
   * 50% of the width of the parent element otherwise. */
  max-width: 500px; min-width: 300px; width: 50%;
}

p#outputBodyWidth { color: blue; }
p#outputDivWidth { color: red; }
<div>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
  eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
  <p id="outputDivWidth"></p>
</div>
<p id="outputBodyWidth"></p>

这样我们就不用在两个地方使用处理程序了。