【问题标题】:Compare date values "instantly" on user input在用户输入时“立即”比较日期值
【发布时间】:2018-10-25 21:14:54
【问题描述】:

这个问题可能与另一个问题类似:

HTML Comparing 2 Dates with Javascript

但我不想使用button,只需让它即时。

我有 2 个 date 类型的输入,我想在它们之间进行比较。

<div>
  <label style="font-family: 'Segoe UI';">Select a date.</label>
  <br><br>
  <span style="font-family: 'Segoe UI';">Since</span>&nbsp;
  <input type="date" name="since"  id="since" required="required" style="font-family: 'Segoe UI';"/>&nbsp;&nbsp;

  <span style="font-family: 'Segoe UI';">Until</span>&nbsp;
  <input type="date" name="until" id="until" required="required" style="font-family: 'Segoe UI';"/>
  <br><br>
  <button style="font-size: 14px; font-family: 'Segoe UI';" onclick="Validate()">COMPARE THIS</button>
</div>

<script type="text/javascript">
  function Validate(){
    var date1 = new Date(document.getElementById('since').value);
    var date2 = new Date(document.getElementById('until').value);
  
    if(date2 < date1) {

        alert('The date cannot be less than the first date that you selected');
        return false;

    }else{
        alert("It's OK");
        return true;
    }
  }
</script>

现在条件完美运行,它比较两个日期并在第二个日期小于第一个日期时显示错误。但这是使用按钮来触发比较。

是否可以在没有按钮触发比较的情况下比较输入日期?并使用HTMLSelectElement.setCustomValidity() 方法?

【问题讨论】:

  • 我会向你推荐 moment.js,它非常受欢迎的库 date1.isBefore(date2) 返回布尔值
  • 怎么会涉及到php?我会删除标签
  • “没有按钮来完成这项工作” - 是的,在调用 validate() 的两个输入上设置一个 onKeyDown(或 keyup..)侦听器。但是消息不应该是一个警报,而是一条消息,和/或输入周围的红色边框。
  • @Jeff。可以如果我输入日期,但如果我只选择日期它不会显示消息错误。
  • But I don't want to use a button, simply make it instant. 尽快?

标签: javascript html date input


【解决方案1】:

我认为您可以使用 onchange 事件来执行此操作。我稍微修改了您的 sn-p 并为何时不验证设置了一个简单的条件。您可以将其调整为更复杂。

<div>
  <label style="font-family: 'Segoe UI';">Select a date.</label>
  <br><br>
  <span style="font-family: 'Segoe UI';">Since</span>&nbsp;
  <input onchange="Validate()" type="date" name="since"  id="since" required="required" style="font-family: 'Segoe UI';"/>&nbsp;&nbsp;

  <span style="font-family: 'Segoe UI';">Until</span>&nbsp;
  <input onchange="Validate()" type="date" name="until" id="until" required="required" style="font-family: 'Segoe UI';"/>
</div>

<script type="text/javascript">
  function Validate(){
    var input1 = document.getElementById('since').value;
    var input2 = document.getElementById('until').value;
  if(input1 != "" && input2 != ""){
      var date1 = new Date(input1);
      var date2 = new Date(input2);

      if(date2 < date1) {

          alert('The date cannot be less than the first date that you selected');
          return false;

      }else{
          alert("It's OK");
          return true;
      }
    }
  }
</script>

【讨论】:

    【解决方案2】:

    您需要注意与&lt;input type="date"&gt; 一起使用的事件以避免意外后果。只要用户在日期的最后一个空白部分输入任何数字,inputchange 事件就会触发(由于对 &lt;input type="date"&gt; 的支持参差不齐,因此跨浏览器不一定一致)。

    例如(在 Chrome 中),如果用户输入“12”作为月份,“31”作为日期,然后在年份输入“2”(打算输入“2018”),则inputchange 事件将在输入“2”后立即触发,在您的场景中,验证功能将在用户完成输入年份之前将“12/31/0002”与另一个日期进行比较(这将在用户尝试输入剩余年份数字时重复发生)。根据您将验证结果通知用户的方式,您可能能够优雅地解决此问题,但如果您使用alert(),它就不会很漂亮。

    因此,使用blur 之类的事件来触发验证比较可能更安全。比如:

    const since = document.querySelector('#since');
    const until = document.querySelector('#until');
    const message = document.querySelector('#message');
    const compareDates = () => {
      const sval = since.value;
      const uval = until.value;
      if (sval && uval && (uval < sval)) {
        message.innerHTML = 'The "Until" date must come after the "Since" date.';
      } else {
        message.innerHTML = '';
      }
    };
    
    since.addEventListener('blur', compareDates);
    until.addEventListener('blur', compareDates);
    #message {
      margin: 8px 0;
      color: red;
    }
    <label for="since">Since</label>
    <input type="date" name="since" id="since" required>
    <label for="until">Until</label>
    <input type="date" name="until" id="until" required>
    <div id="message"></div>

    【讨论】:

    • 如果用户返回第一个输入,使用这样的警报会使用户陷入永无止境的循环。在第二个输入上触发一个模糊事件,显示警报。一旦它被解除,就会触发另一个模糊事件,等等。ad infinitum
    • @RobG - 好点。编辑了答案以删除通知用户日期“正常”的不必要警报,因此现在 sn-p 仅在“直到”日期在“开始”日期之前触发警报(并避免人们陷入困境运行 sn-p 时烦人的循环)。
    • 未修复。在第一个输入中输入 2018-10-10,在第二个输入中输入 2018-10-11,返回到第一个并输入 2018-10-12,点击 tab... ;-) 如果您不使用警报,则更容易修复。
    • @RobG - 哇......我仍然想弄清楚为什么alert() 会以这种方式与focus 事件交互。现在只需将它添加到我的原因列表中,为什么alert() 除了动态检查之外没有什么用处。这次真的修复了答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-25
    • 1970-01-01
    • 2019-08-24
    • 1970-01-01
    • 2023-03-13
    • 2015-08-30
    相关资源
    最近更新 更多