【问题标题】:execute a function only if condition is satisfied inside for loop仅当在 for 循环中满足条件时才执行函数
【发布时间】:2022-01-04 19:34:32
【问题描述】:

我是 js 新手,我正在尝试按类名遍历元素并使用 javascript 更改元素的文本内容。以下是我到目前为止所拥有的,但这不起作用。

<script type="text/javascript">
function dformat(i) {
    var hasDate = document.getElementsByClassName("dformat")[i].textContent.trim().includes("/");
    if(hasDate === false) {
       window.setTimeout(dformat, 100); /* this checks the flag every 100 milliseconds*/
    } else {
       dateString = document.getElementsByClassName("dformat")[i].textContent.trim();
       const options = { year: 'numeric', month: 'short', day: 'numeric' };
       let dateArr = dateString.split("/");
       var sMonth = dateArr[0];
       var sDay = dateArr[1];
       var sYear = dateArr[2];
       let newDateString = sYear + "/" + sMonth + "/" + sDay
       let newDate = new Date(newDateString);
       document.getElementsByClassName("dformat")[i].textContent=newDate.toLocaleDateString('en-us', options);
    }
}

var ditems = document.getElementsByClassName("dformat");
for (var i = 0; i < ditems.length; i++) {
  dformat(i);   
}
</script>

以下是其中一个元素的示例

<span class="dformat">26/06/1992</span>

预期的输出将是更改每个元素上的文本,类为 dformat

更新: 我在单个元素上尝试了与 getelementbyid 相同的函数(即没有 for 循环)并得到了预期的结果。我在按类名而不是按 id 对单个元素执行相同操作时遇到了麻烦。

【问题讨论】:

  • @Randy Casburn 我在单个元素上尝试了与 getelementbyid 相同的函数(即没有 for 循环),日期结果与预期结果一样有效。我在按类名而不是按 id 对单个元素执行相同操作时遇到了麻烦。
  • 我不确定我理解循环调用函数的动机。如果您打算处理每一个,为什么不循环遍历从.getElementsByClassName() 返回的集合?
  • newDateString 在我测试时持有 Date 构造函数的无效输入,你是如何设法用这个构造一个日期的,例如。 '1992/26/06',再加上 Randy 所说,您需要每个 like 构造,而不是简单地使用外部 for 循环来传递索引这是可行的方法-let newDate = new Date(sYear, sMonth, sDay);

标签: javascript html


【解决方案1】:

您的 for 循环没有问题,问题在于您的 Date 反对构造。 Dates 不能使用 YYYY/MM/DD 格式创建。 (参见警告部分here)您需要做的是将年、月和日作为参数传递给构造函数。

let newDate = new Date(sYear, sMonth, sDay);

其他一些注意事项...

您不需要每次都使用document.getElementsByClassName 来查找元素。您可以简单地将元素直接传递给函数。

function dformat(e) {
  dateString = e.textContent.trim();
  if (!dateString.includes('/')) {
    window.setTimeout(dformat, 100, e);
    return;
  }
  const options = { year: 'numeric', month: 'short', day: 'numeric' };
  let dateArr = dateString.split("/");
  var sMonth = dateArr[0];
  var sDay = dateArr[1];
  var sYear = dateArr[2];
  let newDate = new Date(sYear, sMonth, sDay);
  e.textContent=newDate.toLocaleDateString('en-us', options);
}

var ditems = document.getElementsByClassName("dformat");
for (var i = 0; i < ditems.length; i++) {
  dformat(ditems[i]);   
}

这里有一段代码 sn-p 展示了这个操作。

function dformat(e) {
  dateString = e.textContent.trim();
  if (!dateString.includes('/')) {
    window.setTimeout(dformat, 100, e);
    return;
  }
  const options = { year: 'numeric', month: 'short', day: 'numeric' };
  let dateArr = dateString.split("/");
  var sMonth = dateArr[0];
  var sDay = dateArr[1];
  var sYear = dateArr[2];
  let newDate = new Date(sYear, sMonth, sDay);
  e.textContent=newDate.toLocaleDateString('en-us', options);
}

var ditems = document.getElementsByClassName("dformat");
for (var i = 0; i < ditems.length; i++) {
  dformat(ditems[i]);   
}
<span class="dformat">26/06/1992</span>
<br>
<span class="dformat">27/06/1992</span>
<br>
<span class="dformat">28/06/1992</span>
<br>
<span class="dformat">29/06/1992</span>

其次,如果你使用setTimeout,你需要将元素传递给函数。正如你所拥有的那样,该函数将在没有参数的情况下被调用,因此如果它发现没有/ 的东西就会中断。你可以在上面看到我是如何解决这个问题的。

我有点怀疑以这种方式使用setTimeout。这只允许跨度被格式化一次,如果你真的想要持续监控,那么你需要在主脚本的函数定义之外不断地setTimeout。或者,如果您只需要等待文档准备好,您应该将脚本放在 HTML 内容之后,这不会有问题。 (见here)。我不会进一步推测,因为这不是这个问题的目的,但我想让你知道那里似乎有问题。

【讨论】:

    【解决方案2】:

    我的猜测是某些值会给你一个例外。

    试试这个:

    var ditems = document.getElementsByClassName("dformat");
    for (var i = 0; i < ditems.length; i++) {
      try {
        dformat(i);   
      }
      catch (error) {
        console.error(error);
      }
    }
    

    如果有效,将 i 记录在异常中以查看失败值。

    【讨论】:

      【解决方案3】:

      setTimeout() 会忘记你在哪个索引上运行dformat。您应该使用setTimeout(dformat, 100, i) 将参数传递给下一次调用,这样您就可以同时运行多个独立的等待。

      【讨论】:

        猜你喜欢
        • 2019-04-02
        • 2020-01-10
        • 1970-01-01
        • 2017-08-13
        • 2021-12-07
        • 1970-01-01
        • 1970-01-01
        • 2017-02-03
        • 1970-01-01
        相关资源
        最近更新 更多