我的 Javascript if 语句使用时间变量在设定的时间段显示不同的消息时执行了不应该执行的代码块

My Javascript if statements using time variables to display different message at set time periods execute a code block when it shouldn't

我正在制作一个 if 语句,该语句使用基于 Date() 函数的变量执行,但 if 语句似乎没有阻止执行,而它应该阻止执行。该代码块旨在在适当的时候显示一组可能的段落中的一个。这是我的脚本

<script>
    const D = new Date();
    var m = D.getMinutes();
    var h = D.getHours();

    function showMessage() {
        if ((0 < h <= 5) || ((h == 6) && (m == 0))) {
            document.getElementById("m1").classList.remove("message");
        } else if (((6 == h) && (m != 0)) || (6 < h < 12) || ((h == 12) && (m == 0))) {
            document.getElementById("m2").classList.remove("message");
        } else if (((12 == h) && (m != 0)) || (12 < h < 18) || ((h == 18) && (m == 0))) {
            document.getElementById("m3").classList.remove("message");
        } else {
            document.getElementById("m4").classList.remove("message");
        }
    }
    showMessage();
</script>

这是相关的 HTML 块:

<div id="messagecontainer">
        <p class="message" id="m1">Good morning, you must be an early bird!</p>
        <p class="message" id="m2">Good morning</p>
        <p class="message" id="m3">Good afternoon</p>
        <p class="message" id="m4">Good evening</p>
</div>

这是使它起作用的 CSS:

.message {
    display: none;
}

如您所见,当从任何段落中删除“消息”class 时,该段落应该会显示出来。我知道这部分有效,但问题是,它总是在不应该显示的时候显示 id="m1" 段落。它应该只从凌晨 1 点(这是我刚刚注意到并会修复的错误)到下午 6 点执行。否则,它应该根据需要转到尽可能多的 else if 语句,直到时间正确并且执行正确的文本块。例如,现在是 3:30pm (15h30m),因此应该显示带有“m3”段落的第三个块。但它仍然是“m1”。

我唯一能想到的是,我以某种方式搞砸了 if 语句的语法,否则变量范围不允许我访问 if 语句中的变量(我相信它们应该是全局的,但我可能是错误的)。谁能看出问题所在?

这与您认为的不同:

(0 < h <= 5)

这将首先评估其中一个条件,然后使用该条件的 结果 来评估第二个条件。所以你基本上是这样做的:

(false <= 5)

true.

显式分隔逻辑条件:

((0 < h) && (h <= 5))

您正在编写一些无法按预期工作的条件(它们在数学符号中有效,但在编写代码时无效)。

以此为例0 < h <= 5。它将分步执行

  1. 0 < 5。这可以是 truefalse
  2. true < 5false < 5,两者最终都会被计算为 true。这是因为 JS 在做布尔或数学运算时如何转换一些值

你需要把所有的东西分成这样的东西 0 < h && h <= 5

第一个 if 语句的结果总是 true

(0 < h <= 5) 等于 ((0 < h) <= 5),您可以检查它是否始终为真

在 JavaScript 中,要检查一个数字是否介于两个数字之间(在常规数学中是 n1 < x < n2),您必须使用 && 运算符

(0 < h) && (h <= 5)

所以:

(0 < h <= 5) || ((h == 6) && (m == 0)) 等于

((0 < h) <= 5) || ((h == 6) && (m == 0)) 这不是您想要的,因为前两个括号将始终产生真值。

你想要的是: ((0 < h) && (h <= 5)) || ((h == 6) && (m == 0))

我建议使用三元简化条件,并使用定义为 class 的“值”,然后就在那里做。

备选方案:使用数据属性切换(第二个示例)

function showMessage() {
  const now = new Date();
  const m = now.getMinutes();
  const h = now.getHours();
  let test = (h <= 5 || (h == 6 && m == 0)) ? "am" :
    ((h >= 6 && h < 12) || (h == 12 && m == 0)) ? "morning" :
    ((h >= 12 && m > 0) || (h > 12 && h < 18) || (h == 18 && m == 0)) ? "afternoon" :
    "evening";
  document.querySelector('.' + test)
    .classList.remove("message");
}
showMessage();
.message {
  display: none;
}
<div id="messagecontainer">
  <p class="message am" id="m1">Good morning, you must be an early bird!</p>
  <p class="message morning" id="m2">Good morning</p>
  <p class="message afternoon" id="m3">Good afternoon</p>
  <p class="message evening" id="m4">Good evening</p>
</div>

备用:

function showMessage() {
  const now = new Date();
  const m = now.getMinutes();
  const h = now.getHours();
  let test = (h <= 5 || (h == 6 && m == 0)) ? "am" :
    ((h >= 6 && h < 12) || (h == 12 && m == 0)) ? "morning" :
    ((h >= 12 && m > 0) || (h > 12 && h < 18) || (h == 18 && m == 0)) ? "afternoon" :
    "evening";
  document.querySelector('.' + test)
    .dataset.toggle = "show";
}
showMessage();
.message {
  display: none;
}

.message[data-toggle="show"] {
  display: block;
}
<div id="messagecontainer">
  <p class="message am">Good morning, you must be an early bird!</p>
  <p class="message morning">Good morning</p>
  <p class="message afternoon">Good afternoon</p>
  <p class="message evening">Good evening</p>
</div>