目录
实时表单验证:提升用户体验的微妙改进
首页 web前端 js教程 使用JavaScript即时表单验证

使用JavaScript即时表单验证

Feb 16, 2025 am 10:40 AM

实时表单验证:提升用户体验的微妙改进

Instant Form Validation Using JavaScript

核心要点:

  • JavaScript 可用于实现实时表单验证,此功能可为用户提供输入有效性的即时反馈,从而提升用户体验并维护数据完整性,确保仅提交有效数据。
  • HTML5 属性 patternrequired 可用于定义表单元素的有效输入范围。如果浏览器不支持这些属性,则其值可用作 JavaScript 兼容性填充程序的基础。
  • aria-invalid 属性可用于指示字段是否无效。此属性提供辅助功能信息,并可用作 CSS 钩子以直观地指示无效字段。
  • JavaScript 函数 instantValidation() 测试字段并执行实际验证,控制 aria-invalid 属性以指示字段的状态。此函数可以绑定到 onchange 事件以提供实时表单验证。

HTML5 引入了几个用于实现基于浏览器的表单验证的新属性。pattern 属性是一个正则表达式,用于定义文本区域元素和大多数输入类型的有效输入范围。required 属性指定字段是否必填。对于不支持这些属性的旧版浏览器,我们可以使用它们的值作为兼容性填充程序的基础。我们还可以使用它们来提供更有趣的增强功能——实时表单验证。

需要注意的是,不要过度使用验证,以免破坏正常的浏览行为并妨碍用户操作。例如,我见过一些表单,无法使用 Tab 键离开无效字段——JavaScript 被用来(更确切地说,是被滥用)强制焦点停留在字段内,直到其有效为止。这非常不利于用户体验,并且直接违反了辅助功能指南。

本文将介绍一种侵入性较小的实现方法。它甚至不是完整的客户端验证——它只是一种细微的用户体验增强,以可访问的方式实现,在我测试脚本时发现它几乎与 Firefox 当前原生实现的功能相同!

基本概念

在最新版本的 Firefox 中,如果必填字段为空或其值与模式不匹配,则该字段将显示红色边框,如下图所示:

Instant Form Validation Using JavaScript

当然,这不会立即发生。如果发生这种情况,则每个必填字段默认都会显示该边框。相反,只有在您与字段交互后才会显示这些边框,这基本上(虽然不完全)类似于 onchange 事件。

因此,我们将使用 onchange 作为触发事件。或者,我们可以使用 oninput 事件,该事件只要在字段中键入或粘贴任何值就会触发。但这真的太“即时”了,因为它很容易在快速连续键入时反复触发,从而产生闪烁效果,这会让一些用户感到厌烦或分心。而且,无论如何,oninput 不会从编程输入中触发,而 onchange 会触发,我们可能需要它来处理来自第三方插件的自动完成等操作。

定义HTML和CSS

让我们看一下我们的实现,从它所基于的 HTML 开始:

<form action="#" method="post">
  <fieldset>
    <legend><strong>Add your comment</strong></legend>

    <p>
      <label for="author">Name <abbr title="Required">*</abbr></label>
      <input
        aria-required="true"
        id="author"
        name="author"
        pattern="^([- \w\d\u00c0-\u024f]+)$"
        required="required"
        size="20"
        spellcheck="false"
        title="Your name (no special characters, diacritics are okay)"
        type="text"
        value=""
      >
    </p>

    <p>
      <label for="email">Email <abbr title="Required">*</abbr></label>
      <input
        aria-required="true"
        id="email"
        name="email"
        pattern="^(([-\w\d]+)(\.[-\w\d]+)*@([-\w\d]+)(\.[-\w\d]+)*(\.([a-zA-Z]{2,5}|[\d]{1,3})){1,2})$"
        required="required"
        size="30"
        spellcheck="false"
        title="Your email address"
        type="email"
        value=""
      >
    </p>

    <p>
      <label for="website">Website</label>
      <input
        id="website"
        name="website"
        pattern="^(http[s]?:\/\/)?([-\w\d]+)(\.[-\w\d]+)*(\.([a-zA-Z]{2,5}|[\d]{1,3})){1,2}(\/([-~%\.\(\)\w\d]*\/*)*(#[-\w\d]+)?)?$"
        size="30"
        spellcheck="false"
        title="Your website address"
        type="url"
        value=""
      >
    </p>

    <p>
      <label for="text">Comment <abbr title="Required">*</abbr></label>
      <textarea
        aria-required="true"
        cols="40"
        id="text"
        name="text"
        required="required"
        rows="10"
        spellcheck="true"
        title="Your comment"
      ></textarea>
    </p>

  </fieldset>
  <fieldset>
    <input name="preview" type="submit" value="Preview">
    <input name="save" type="submit" value="Submit Comment">
  </fieldset>
</form>
登录后复制
登录后复制

此示例是一个简单的评论表单,其中一些字段是必填的,一些字段经过验证,一些字段同时满足这两个条件。具有 required 属性的字段也具有 aria-required 属性,以便为不支持新输入类型的辅助技术提供后备语义。

ARIA 规范还定义了 aria-invalid 属性,我们将使用它来指示字段是否无效(HTML5 中没有等效属性)。aria-invalid 属性显然提供了辅助功能信息,但它也可以用作 CSS 钩子来应用红色边框:

input[aria-invalid="true"], textarea[aria-invalid="true"] {
  border: 1px solid #f00;
  box-shadow: 0 0 4px 0 #f00;
}
登录后复制
登录后复制

我们可以只使用 box-shadow 而不用管边框,坦白说这样看起来会更好,但这样一来,在不支持 box-shadow 的浏览器(例如 IE8)中就没有指示了。

添加JavaScript

现在我们有了静态代码,我们可以添加脚本了。首先,我们需要一个基本的 addEvent() 函数:

function addEvent(node, type, callback) {
  if (node.addEventListener) {
    node.addEventListener(type, function(e) {
      callback(e, e.target);
    }, false);
  } else if (node.attachEvent) {
    node.attachEvent('on' + type, function(e) {
      callback(e, e.srcElement);
    });
  }
}
登录后复制

接下来,我们需要一个函数来确定是否应该验证给定字段,该函数只需测试它既未禁用也未只读,并且它具有 patternrequired 属性:

function shouldBeValidated(field) {
  return (
    !(field.getAttribute("readonly") || field.readonly) &&
    !(field.getAttribute("disabled") || field.disabled) &&
    (field.getAttribute("pattern") || field.getAttribute("required"))
  );
}
登录后复制

前两个条件可能看起来很冗长,但它们是必要的,因为元素的 disabledreadonly 属性不一定反映其属性状态。例如,在 Opera 中,具有硬编码属性 readonly="readonly" 的字段仍然会为其 readonly 属性返回 undefined(点属性只匹配通过脚本设置的状态)。

一旦我们获得了这些实用程序,我们就可以定义主验证函数,该函数测试字段,然后根据需要执行实际验证:

function instantValidation(field) {
  if (shouldBeValidated(field)) {
    var invalid =
      (field.getAttribute("required") && !field.value) ||
      (field.getAttribute("pattern") &&
        field.value &&
        !new RegExp(field.getAttribute("pattern")).test(field.value));
    if (!invalid && field.getAttribute("aria-invalid")) {
      field.removeAttribute("aria-invalid");
    } else if (invalid && !field.getAttribute("aria-invalid")) {
      field.setAttribute("aria-invalid", "true");
    }
  }
}
登录后复制

因此,如果字段是必填的但没有值,或者它具有模式和值,但值与模式不匹配,则该字段无效。

由于模式已经定义了正则表达式的字符串形式,所以我们只需要将该字符串传递给 RegExp 构造函数,它就会创建一个我们可以针对该值进行测试的正则表达式对象。但是,我们必须预先测试该值以确保它不为空,这样正则表达式本身就不必考虑空字符串。

一旦我们确定了字段是否无效,我们就可以控制它的 aria-invalid 属性来指示该状态——将其添加到尚未具有该属性的无效字段中,或将其从具有该属性的有效字段中删除。很简单!最后,为了使这一切都能运行,我们需要将验证函数绑定到 onchange 事件。它应该像这样简单:

<form action="#" method="post">
  <fieldset>
    <legend><strong>Add your comment</strong></legend>

    <p>
      <label for="author">Name <abbr title="Required">*</abbr></label>
      <input
        aria-required="true"
        id="author"
        name="author"
        pattern="^([- \w\d\u00c0-\u024f]+)$"
        required="required"
        size="20"
        spellcheck="false"
        title="Your name (no special characters, diacritics are okay)"
        type="text"
        value=""
      >
    </p>

    <p>
      <label for="email">Email <abbr title="Required">*</abbr></label>
      <input
        aria-required="true"
        id="email"
        name="email"
        pattern="^(([-\w\d]+)(\.[-\w\d]+)*@([-\w\d]+)(\.[-\w\d]+)*(\.([a-zA-Z]{2,5}|[\d]{1,3})){1,2})$"
        required="required"
        size="30"
        spellcheck="false"
        title="Your email address"
        type="email"
        value=""
      >
    </p>

    <p>
      <label for="website">Website</label>
      <input
        id="website"
        name="website"
        pattern="^(http[s]?:\/\/)?([-\w\d]+)(\.[-\w\d]+)*(\.([a-zA-Z]{2,5}|[\d]{1,3})){1,2}(\/([-~%\.\(\)\w\d]*\/*)*(#[-\w\d]+)?)?$"
        size="30"
        spellcheck="false"
        title="Your website address"
        type="url"
        value=""
      >
    </p>

    <p>
      <label for="text">Comment <abbr title="Required">*</abbr></label>
      <textarea
        aria-required="true"
        cols="40"
        id="text"
        name="text"
        required="required"
        rows="10"
        spellcheck="true"
        title="Your comment"
      ></textarea>
    </p>

  </fieldset>
  <fieldset>
    <input name="preview" type="submit" value="Preview">
    <input name="save" type="submit" value="Submit Comment">
  </fieldset>
</form>
登录后复制
登录后复制

但是,为了使这能够工作,onchange 事件必须冒泡(使用通常称为事件委托的技术),但在 Internet Explorer 8 及更早版本中,onchange 事件不会冒泡。我们可以选择忽略这些浏览器,但我认为这将是一种遗憾,尤其是在问题如此容易解决的情况下。它只是意味着代码更复杂一些——我们必须获取输入和文本区域元素的集合,遍历它们并将 onchange 事件分别绑定到每个字段:

input[aria-invalid="true"], textarea[aria-invalid="true"] {
  border: 1px solid #f00;
  box-shadow: 0 0 4px 0 #f00;
}
登录后复制
登录后复制

结论和展望

就是这样——一个简单且非侵入性的实时表单验证增强功能,提供可访问和直观的提示,以帮助用户完成表单。

这个脚本实现后,我们实际上只需要几步就能完成一个完整的兼容性填充程序。这样的脚本超出了本文的范围,但是如果您想进一步开发它,所有基本模块都在这里——测试是否应该验证字段,根据模式和/或 required 验证字段,以及绑定触发事件。

我必须承认,我不确定它是否真的值得!如果您已经有了此增强功能(在 IE7 及所有现代浏览器中都能工作),并且考虑到您别无选择,也必须实现服务器端验证,并且考虑到支持 patternrequired 的浏览器已经使用它们进行预提交验证——考虑到所有这些,真的还有必要添加另一个兼容性填充程序吗?

(此处可以添加关于实时验证的常见问题解答部分,内容与原文档中的FAQs部分相同)

以上是使用JavaScript即时表单验证的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

前端热敏纸小票打印遇到乱码问题怎么办? 前端热敏纸小票打印遇到乱码问题怎么办? Apr 04, 2025 pm 02:42 PM

前端热敏纸小票打印的常见问题与解决方案在前端开发中,小票打印是一个常见的需求。然而,很多开发者在实...

神秘的JavaScript:它的作用以及为什么重要 神秘的JavaScript:它的作用以及为什么重要 Apr 09, 2025 am 12:07 AM

JavaScript是现代Web开发的基石,它的主要功能包括事件驱动编程、动态内容生成和异步编程。1)事件驱动编程允许网页根据用户操作动态变化。2)动态内容生成使得页面内容可以根据条件调整。3)异步编程确保用户界面不被阻塞。JavaScript广泛应用于网页交互、单页面应用和服务器端开发,极大地提升了用户体验和跨平台开发的灵活性。

谁得到更多的Python或JavaScript? 谁得到更多的Python或JavaScript? Apr 04, 2025 am 12:09 AM

Python和JavaScript开发者的薪资没有绝对的高低,具体取决于技能和行业需求。1.Python在数据科学和机器学习领域可能薪资更高。2.JavaScript在前端和全栈开发中需求大,薪资也可观。3.影响因素包括经验、地理位置、公司规模和特定技能。

JavaScript难以学习吗? JavaScript难以学习吗? Apr 03, 2025 am 12:20 AM

学习JavaScript不难,但有挑战。1)理解基础概念如变量、数据类型、函数等。2)掌握异步编程,通过事件循环实现。3)使用DOM操作和Promise处理异步请求。4)避免常见错误,使用调试技巧。5)优化性能,遵循最佳实践。

如何实现视差滚动和元素动画效果,像资生堂官网那样?
或者:
怎样才能像资生堂官网一样,实现页面滚动伴随的动画效果? 如何实现视差滚动和元素动画效果,像资生堂官网那样? 或者: 怎样才能像资生堂官网一样,实现页面滚动伴随的动画效果? Apr 04, 2025 pm 05:36 PM

实现视差滚动和元素动画效果的探讨本文将探讨如何实现类似资生堂官网(https://www.shiseido.co.jp/sb/wonderland/)中�...

JavaScript的演变:当前的趋势和未来前景 JavaScript的演变:当前的趋势和未来前景 Apr 10, 2025 am 09:33 AM

JavaScript的最新趋势包括TypeScript的崛起、现代框架和库的流行以及WebAssembly的应用。未来前景涵盖更强大的类型系统、服务器端JavaScript的发展、人工智能和机器学习的扩展以及物联网和边缘计算的潜力。

如何使用JavaScript将具有相同ID的数组元素合并到一个对象中? 如何使用JavaScript将具有相同ID的数组元素合并到一个对象中? Apr 04, 2025 pm 05:09 PM

如何在JavaScript中将具有相同ID的数组元素合并到一个对象中?在处理数据时,我们常常会遇到需要将具有相同ID�...

Zustand异步操作:如何确保useStore获取的最新状态? Zustand异步操作:如何确保useStore获取的最新状态? Apr 04, 2025 pm 02:09 PM

zustand异步操作中的数据更新问题在使用zustand状态管理库时,经常会遇到异步操作导致数据更新不及时的问题。�...

See all articles