为什么警告框在以下代码中不断触发?

Why does the alert-box keep firing in the following code?

我有以下 HTML 代码:

function presence_check(elem) {
  if ($(elem).val() === "") {
    alert("Please enter something");
    $(elem).focus();
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" placeholder="Don't leave this textbox blank" onblur="presence_check(this)">
<input type="text" placeholder="Secon input box">

如果文本框为空,代码本应提醒用户并重新关注该元素,但它却不断触发 onblur 事件。我看到一些答案说当弹出警告框时,它会删除元素上的焦点,从而触发 onblur 事件。但是,我不明白这是怎么可能的,因为在元素已经失去焦点后调用了 alert() 函数

问题是因为在 blur 上显示了 alert()。然后将焦点 返回 到准备好 blur 的元素,当用户单击对话框中的按钮时再次触发,因此无限循环。您可以在 this fiddle

的控制台输出中看到这种情况发生

这是一个很好的例子,说明为什么您永远不应该在任何系统中使用 alert() - 即使是出于调试目的。使用实际的 HTML 元素向用户显示警告,并使用 console.log()console.dir() 进行调试。下面是如何执行此操作的示例:

$('input.validate').on('blur input', function() {
  var $message = $(this).next('.validation-message');
  if (this.value.trim() === "") {
    $message.show();
    this.focus();
  } else {
    $message.hide();
  }
});
.validation-message {
  display: none;
  color: #C00;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
  <input type="text" placeholder="Don't leave this textbox blank" class="validate" />
  <span class="validation-message">Please enter something</span>
</div>
<div>
  <input type="text" placeholder="Second input box" />
</div>

我还强烈建议您不要在无效时强制将焦点返回到该字段,因为它会阻止用户在您的页面中执行任何其他操作,这是糟糕的用户体验。

当你这样做时,JS 可以简化为:

$('input.validate').on('blur input', function() {
  $(this).next('.validation-message').toggle(this.value.trim() === '');
});