【问题标题】:Invoking the focus method causes onblur to fire endlessly调用 focus 方法会导致 onblur 无休止地触发
【发布时间】:2019-09-16 15:22:59
【问题描述】:

我想在用户转到另一个字段时验证输入框。我有以下代码可以正常工作。

validate = (v) => {
  if (v.value=="yes") return;
  alert("Value must be exactly 'yes'. Please rectify.");
  //v.focus();
}
<p>Enter only 'yes' in this field:</p>
<input onblur='validate(this);' />

但是,如果我添加调用focus 方法的目的是在继续之前向用户突出显示以修复错误,则onblur 方法将被无休止地触发。为什么会这样?

小提琴是https://jsfiddle.net/OldGeezer/8xfLwvn6/4/

在进一步的测试中,我发现如果因为我单击另一个应用程序窗口而失去焦点,则不会发生无休止的onblur。如果我只是单击网页的另一部分(在 Chrome 中),就会发生这种情况。

【问题讨论】:

  • alert() 结束时您失去焦点,您可以使用您当前的代码验证这一点。
  • 顺便说一句,这真的很烦人,请使用其他方法(如表单验证)来执行此操作。 (用户:让我继续,我稍后会解决这个问题!)
  • 不过,我不确定alert() 的规格。所以我不会作为答案发布。

标签: javascript dom dhtml onblur onfocus


【解决方案1】:

根据 w3schools:

注意:警告框将焦点从当前窗口移开,并强制浏览器阅读消息。不要过度使用此方法,因为它会阻止用户在关闭框之前访问页面的其他部分。

链接:https://www.w3schools.com/jsref/met_win_alert.asp

警报将焦点从输入中移开,从而创建一个无限循环。解决方案是以不同的方式显示消息。例如在 span 元素中:

<p>Enter only 'yes' in this field:</p>
<input onblur="validate(this);" />  
<span id="message"></span>

<script>

validate = (v) => {
  if (v.value=="yes") return;
  document.getElementById("message").innerHTML = "Value must be exactly 'yes'. Please rectify.";
  v.focus();
}

</script>

【讨论】:

  • 但是我的alert是在调用focus方法之前。
  • @Old Geezer。顺序无关紧要,因为 javascript 是单线程的,并且所有事件都在您的代码之后处理。 medium.com/front-end-weekly/…
  • @ClaudiaChersin 我在alert 之后添加了console.log 行,并且在alert 对话框关闭之前没有控制台输出。
  • @Old Geezer 是的,当然,console.log 发生在警报关闭后(警报是同步的)。是在validate函数执行结束后才执行的onblur。
【解决方案2】:

您正在做的是不断运行 onblur 函数,您一次又一次地运行它,并且在每次迭代时它都会给您警报。

  1. Input 获得 onblur 事件,显示警报,自动关注输入。
  2. 您单击任意位置,onblur 再次触发,显示警报,并再次专注于输入。

可以这么说,您可以循环执行。

您可以只给它边框颜色,而不是专注于输入。这样你的 onblur 只会触发一次。

【讨论】:

    【解决方案3】:

    使用alert() 会从导致blur 触发的活动元素中移除焦点。因此,根据您的脚本,blur 会连续触发。使用console.log(),它可以帮助您更好地理解这一点。

    【讨论】:

    • console.log 不会触发 blur 所以可能无助于理解某些事情。
    • 为了检查blur是否持续触发,将结果记录到控制台。以后你会知道的。
    • 所有这些答案都集中在(不是双关语)错误的事情上。不是alert 导致它触发blur。它在警报后调用focus。如果您拨打focus 电话,那很好。
    猜你喜欢
    • 2018-12-02
    • 2017-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-14
    相关资源
    最近更新 更多