当标题下面的内容不可见时如何隐藏标题

发布于 2025-01-09 16:01:05 字数 2460 浏览 0 评论 0原文

我有一个 JavaScript 应用程序,其中有一个很长的“日项目”列表,由指定月份的标题分隔,如下所示:

<h3>January 2022</h3>
<div class="item" data-visitors='1'>2022-01-01</div>
<div class="item" data-visitors='0'>2022-01-02</div>
<div class="item" data-visitors='1'>2022-01-03</div>
...etc until
<div class="item" data-visitors='15'>2022-01-31</div>

<h3>February 2022</h3>
<div class="item" data-visitors='0'>2022-02-01</div>
<div class="item" data-visitors='1'>2022-02-02</div>
<div class="item" data-visitors='19'>2022-02-03</div>
...etc until
<div class="item" data-visitors='0'>2022-02-28</div>

<h3>March 2022</h3>
<div class="item" data-visitors='0'>2022-03-01</div>
<div class="item" data-visitors='11'>2022-03-02</div>
<div class="item" data-visitors='5'>2022-03-03</div>
...etc until
<div class="item" data-visitors='2'>2022-03-28</div>

项目数量约为 6.500 个,其中有约 200 个标题。我故意不在这里编写我的代码,因为它很混乱,并且在我看来无关紧要。这里有趣的是生成的 DOM。

在(普通)JavaScript 中使用过滤器,根据 data-visitors 值,我将一些 div 更改为 style.display='none'。例如,所有具有“item”类且 data-visitors 值低于 15 的 div 将获得 style.display='none'

这实际上会使 html 文件的视图看起来像这样

2022 年 1 月

2022 年 2 月

2022-02-03

2022 年 3 月

在这里,我想隐藏“2022 年 1 月”和“2022 年 3 月”标题(h3),因为它们没有可见的项目(HTML-div 仍然存在,但如上所述 带有 display:none)。在我的申请中,此列表范围从 2004 年到 2022 年,因此有很多空月份。

我的问题:当月份标题下方不再显示任何内容时,如何隐藏月份标题?

由于这些列表是动态创建的:

我能做什么:向月份 h3 标题和 div 添加类、id、数据属性等

我不能做什么 >:将 h3 和 div 包裹在包裹 div 中,或在所有

周围添加包裹 div。

我的结论是,我不是一个经验丰富的 JavaScript 程序员:div 不是 h3 的子级,所以我不能使用类似的东西。兄弟姐妹也不会工作。

用伪代码思考,我会想象在 h3 标签上放置一个 id='2022-02' ,以及一些 data-attr-year-month-item='2022-02 ' 在 div 上。然后,查询类似的内容(这只是化妆代码):

if ((document.querySelectorAll("[attr-year-month-item='2022-02']").display=='none').length == (document.querySelectorAll("[attr-year-month-item='2022-02']").length)) {

document.getElementById('2022-02').style.display='none'

}

换句话说,如果 style.display='none' 的 div 的长度等于该月所有 div 的长度,那么标题应该被隐藏。

我需要帮助的是,如何在 vanilla JavaScript 中编写此 if 语句才能正常工作?

I have an application in JavaScript with a very long list of 'Day-items', separated by a header specifying the month, like so:

<h3>January 2022</h3>
<div class="item" data-visitors='1'>2022-01-01</div>
<div class="item" data-visitors='0'>2022-01-02</div>
<div class="item" data-visitors='1'>2022-01-03</div>
...etc until
<div class="item" data-visitors='15'>2022-01-31</div>

<h3>February 2022</h3>
<div class="item" data-visitors='0'>2022-02-01</div>
<div class="item" data-visitors='1'>2022-02-02</div>
<div class="item" data-visitors='19'>2022-02-03</div>
...etc until
<div class="item" data-visitors='0'>2022-02-28</div>

<h3>March 2022</h3>
<div class="item" data-visitors='0'>2022-03-01</div>
<div class="item" data-visitors='11'>2022-03-02</div>
<div class="item" data-visitors='5'>2022-03-03</div>
...etc until
<div class="item" data-visitors='2'>2022-03-28</div>

The number of items are about 6.500 with some 200 headlines. I purposely do not write my code here as it is messy, and irrelevant in my opinion. It is the produced DOM that is interesting here.

Using filters in (vanilla) JavaScript, based on data-visitors value I change some divs to style.display='none'. For example, all divs with class 'item' with a data-visitors value below 15 will get a style.display='none'.

This will practically make the view of the html-file look like this

January 2022

February 2022

2022-02-03

March 2022

Here, I would like to hide "January 2022" and "March 2022" headlines (h3's) as there are no items visible for them (HTML-divs still exist but, as mentioned, with a display:none). In my application, this list ranges from 2004 to 2022 so there are a lot of empty months.

My question: How can I hide the month headers when there is no content underneath them visible any longer?

Due to how theses lists are being dynamically created:

What I can do: Add classes, ids, data-attributes etc to both month h3 headlines as well as divs

What I cannot do: Wrap h3 and the divs in a wrapping div, or add a wrapping div around all the <div class='item'>.

My conclusions, and I am not an experienced programmer in JavaScript: The divs are not children of the h3 so I cannot use anything like that. Siblings would not work either.

Thinking in pseudo-code, I would imagine putting a id='2022-02' on the h3-tag, and some data-attr-year-month-item='2022-02' on the div's. Then, query something like (this is just make-up-code):

if ((document.querySelectorAll("[attr-year-month-item='2022-02']").display=='none').length == (document.querySelectorAll("[attr-year-month-item='2022-02']").length)) {

document.getElementById('2022-02').style.display='none'

}

In other words, if the length of the divs that have style.display='none' equals the length of all the divs in that month, then the headline should be hidden.

What I would like help with is, how do I write this if-statement in vanilla JavaScript so that it works?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我的痛♀有谁懂 2025-01-16 16:01:05

您可以从下到上遍历项目,检查 h3 之后的所有组是否都被隐藏,然后隐藏 h3

let hideH3 = true;
[...document.querySelectorAll('.item')].reverse()
.forEach(i => {
  const hide = i.dataset.visitors < 15;
  hideH3 &= hide;
  if (hide) i.classList.add('hidden');
  const next = i.previousElementSibling;
  if (next.nodeName == 'H3') {
    if (hideH3) next.classList.add('hidden');
    else hideH3 = true;
  }
});
.hidden {display:none}
<h3>January 2022</h3>
<div class="item" data-visitors='1'>2022-01-01</div>
<div class="item" data-visitors='0'>2022-01-02</div>
<div class="item" data-visitors='1'>2022-01-03</div>

<h3>February 2022</h3>
<div class="item" data-visitors='0'>2022-02-01</div>
<div class="item" data-visitors='1'>2022-02-02</div>
<div class="item" data-visitors='19'>2022-02-03</div>
<div class="item" data-visitors='0'>2022-02-28</div>

<h3>March 2022</h3>
<div class="item" data-visitors='0'>2022-03-01</div>
<div class="item" data-visitors='11'>2022-03-02</div>
<div class="item" data-visitors='5'>2022-03-03</div>
<div class="item" data-visitors='5'>2022-03-28</div>

You might traverse the items from the bottom to the top, checking if all of the group after h3 were hidden, then hide the h3:

let hideH3 = true;
[...document.querySelectorAll('.item')].reverse()
.forEach(i => {
  const hide = i.dataset.visitors < 15;
  hideH3 &= hide;
  if (hide) i.classList.add('hidden');
  const next = i.previousElementSibling;
  if (next.nodeName == 'H3') {
    if (hideH3) next.classList.add('hidden');
    else hideH3 = true;
  }
});
.hidden {display:none}
<h3>January 2022</h3>
<div class="item" data-visitors='1'>2022-01-01</div>
<div class="item" data-visitors='0'>2022-01-02</div>
<div class="item" data-visitors='1'>2022-01-03</div>

<h3>February 2022</h3>
<div class="item" data-visitors='0'>2022-02-01</div>
<div class="item" data-visitors='1'>2022-02-02</div>
<div class="item" data-visitors='19'>2022-02-03</div>
<div class="item" data-visitors='0'>2022-02-28</div>

<h3>March 2022</h3>
<div class="item" data-visitors='0'>2022-03-01</div>
<div class="item" data-visitors='11'>2022-03-02</div>
<div class="item" data-visitors='5'>2022-03-03</div>
<div class="item" data-visitors='5'>2022-03-28</div>

我家小可爱 2025-01-16 16:01:05

您必须以编程方式设置可见性,那么为什么不在设置时这样做呢?就像

let element = document.getElementByID('firsth3');
let h3 = element;
while ( element.id != 'lastdiv' ) {
  element = element.nextElementSibling;
  if ( element.tagName == 'H3' ) {
    h3 = element;
  } else if ( element.dataset.visitors > 15 ) {
    element.styyle.display = 'block';
    h3.style.display = 'block';
  }
}

你给所有东西一个显示:最初没有并用 id 标记第一个和最后一个元素。

You have to set the visibility programatically so why not do this while you are at it? Something like

let element = document.getElementByID('firsth3');
let h3 = element;
while ( element.id != 'lastdiv' ) {
  element = element.nextElementSibling;
  if ( element.tagName == 'H3' ) {
    h3 = element;
  } else if ( element.dataset.visitors > 15 ) {
    element.styyle.display = 'block';
    h3.style.display = 'block';
  }
}

where you give everything a display: none initially and mark the first and last elements with ids.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文