65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 JavaScript 提高表单的可用性

starIconstarIconemptyStarIconemptyStarIconemptyStarIcon

2.00/5 (2投票s)

2007 年 4 月 10 日

CPOL

4分钟阅读

viewsIcon

24808

downloadIcon

52

如何使用 JavaScript 提高表单的可用性。

在开始本教程之前,请下载所需资源。

引言

为了让您看到我们的目标,请查看这个功能齐全的示例

首先,打开文件 'form-usability-resources-example.html'。这是我们将使用 JavaScript 使之更具可用性和吸引力的表单示例的一部分。

即使阅读了出色的《为表单应用 CSS》一文,此表单仍然不如它本应有的那样令人兴奋。让我们通过在激活 <input><label> 时添加一些 onfocus() 事件来使表单更具吸引力。

JavaScript

打开您下载的 js.js 文件,让我们开始吧!

注册事件

第一项任务是创建一个页面加载时发生的事件。我们不尝试使用 <body onload="callfunction()">HTML页面中执行函数调用,而是将使用Simon Willison 的 addLoadEvent(func)。这将使我们能够在页面加载后添加函数调用。

将以下 JavaScript 输入到 .js 文件中

function addLoadEvent(func)
{
  var oldonload = window.onload;
  if (typeof window.onload != 'function') { window.onload = func; }
  else { window.onload = function() { oldonload(); func(); } }
}
addLoadEvent(presentForm);

收集表单元素

在您的 JavaScript 文件中创建一个名为 presentForm 的空函数

function presentForm()
{
}

第二项任务是创建将由 JavaScript 操作的表单元素的集合。<form> 嵌套在具有 id="form"<div> 中。我们可以使用 getElementById 命令检索 <div id="form"> 并将其分配给变量 eleDiv。接下来,我们使用 getElementsByTagName 命令将 <div> 中的所有表单分配给变量 eleForms,如下所示

function presentForm()
{
    var eleDiv; var eleForms;
    if (document.getElementById && document.getElementsByTagName)
    {
        eleDiv = document.getElementById("form");
        eleForms = eleDiv.getElementsByTagName("form");
    }
}

收集文本框和输入框

包含在 <div id="form"> 中的所有表单现在被分配给变量 eleForms,这是一个HTML对象集合。下一步是创建此 <form> 中所有 <input><textarea> 的集合。我们可以通过循环遍历 <div id="form"> 中包含的所有 <form> 来做到这一点,并创建更多的HTML对象集合。我们可以使用 getElementsByTagName 命令将 <input> 分配给变量 eleInputs,将 <textarea> 分配给变量 eleTextAreas

function presentForm()
{
  var eleDiv; var eleForms;
  if (document.getElementById && document.getElementsByTagName)
  {
      eleDiv = document.getElementById("form");
      eleForms = eleDiv.getElementsByTagName("form");
      for (var intCounter = 0; intCounter < eleForms.length; intCounter++)
      {
          eleInputs = eleForms[intCounter].getElementsByTagName("input");
          eleTextAreas = eleForms[intCounter].getElementsByTagName("textarea");
      }
  }
}

presentForm() 函数几乎完成了。我们的下一步是实际处理 <textarea><input> 集合。我们将通过将集合传递给一个新函数来实现,该函数将为每个项目应用 onfocus() 事件,如下所示

function presentForm()
{
   var eleDiv; var eleForms;
   if (document.getElementById && document.getElementsByTagName)
   {
       eleDiv = document.getElementById("form");
       eleForms = eleDiv.getElementsByTagName("form");
       for (var intCounter = 0; intCounter < eleForms.length; intCounter++)
       {
           eleInputs = eleForms[intCounter].getElementsByTagName("input");
           eleTextAreas = eleForms[intCounter].getElementsByTagName("textarea");
           applyFunctionToFormElements(eleInputs);
           applyFunctionToFormElements(eleTextAreas);
       }
   }
}

应用 onfocus() 事件

接下来,我们创建一个名为 applyFunctionToFormElements(htmlObjectCollection) 的新函数,并遍历对象集合,准备应用 onfocus() 事件

function applyFunctionToFormElements(htmlObjectCollection)
{
    for (var intCounter = 0; intCounter < htmlObjectCollection.length; intCounter++) { }
}

在应用 onfocus() 事件之前,我们需要确保它不会应用于提交按钮。示例中提供的提交按钮具有 class="button" 属性,可用于识别它。接下来,我们将 onfocus() 事件应用于剩余的 <input><textarea>

function applyFunctionToFormElements(htmlObjectCollection)
{
    for (var intCounter = 0; intCounter < htmlObjectCollection.length; intCounter++)
    {
        if(htmlObjectCollection[intCounter].className != "button")
        {
            htmlObjectCollection[intCounter].onfocus = function () { }
        }
    }
}

一切都在这里发生!

最后,我们到达了激动人心的部分!让我们使用 onfocus() 事件来改变页面的外观。我们可以设置表单元素本身、它们的同级、父级甚至祖父级的类。在此示例中,我们将把 <input><label> 更改为粗体,并将包含的 <fieldset> 的背景颜色更改为粗体。我们将把以下代码输入到 onfocus() 函数中

this.parentNode.parentNode.parentNode.className = "fieldsetHighlight";<
this.previousSibling.className = "labelHighlight"; 

完成的函数应该如下所示

function applyFunctionToFormElements(htmlObjectCollection)
{
    for (var intCounter = 0; intCounter < htmlObjectCollection.length; intCounter++)
    {
        if(htmlObjectCollection[intCounter].className != "button")
        {
            htmlObjectCollection[intCounter].onfocus = function () {
                this.parentNode.parentNode.parentNode.className = "fieldsetHighlight";
                this.previousSibling.className = "labelHighlight"; }
        }
    }
}

我们使用 className="fieldsetHighlight"<fieldset> 分配了粉色背景,并使用 className="labelHighlight"<label> 分配了粗体状态。这两者都是包含在CSS:

.fieldsetHighlight
{
border: 1px solid #d7b9c9; background: #f3e6ed; }
.labelHighlight
{
font-weight: bold; }

清除元素

如果您点击其中一个 <input><textarea>,那么 fieldset 的背景颜色将变为粉色,标签将变为粗体。

但是,当您点击不同 <fieldset> 中的第二个 <input><textarea> 时会发生什么?您点击的第一个 <input><textarea> 仍然被迷人的粉色包围,而您点击的第二个项目也被高亮显示并变为粗体。最后的任务是循环遍历 <label><fieldset> 并将它们的颜色和字体粗细恢复正常,className=""

因此,我们将调用一个新的函数 clearFieldsetsAndLabels() 放在 onfocus() 函数的开头,如下所示

function applyFunctionToFormElements(htmlObjectCollection)
{
    for (var intCounter = 0; intCounter < htmlObjectCollection.length; intCounter++)
    {
        if(htmlObjectCollection[intCounter].className != "button")
        {
            htmlObjectCollection[intCounter].onfocus = function () { clearFieldsetsAndLabels();
            this.parentNode.parentNode.parentNode.className = "fieldsetHighlight";
            this.previousSibling.className = "labelHighlight";
            }
        }
    }
}

我们将创建 clearFieldsetsAndLabels() 函数,并获取包含在 <div id="form"> 中的所有 <label><fieldset>

clearFieldsetsAndLabels()
{
    var eleDiv; var eleFieldsets; var eleLabels;
    eleDiv = document.getElementById("form");
    eleFieldsets = eleDiv.getElementsByTagName("fieldset");
    eleLabels = eleDiv.getElementsByTagName("label");
}

然后,我们需要将每个 <fieldset><label> HTML 对象集合传递给一个重置其类的函数。

clearFieldsetsAndLabels()
{
    var eleDiv; var eleFieldsets; var eleLabels;
    eleDiv = document.getElementById("form");
    eleFieldsets = eleDiv.getElementsByTagName("fieldset");
    eleLabels = eleDiv.getElementsByTagName("label");
    clearEle(eleFieldsets) clearEle(eleLabels);
}

最后一个函数遍历 HTML 对象集合中的每个元素并重置它们的类。

function clearEle(elements)
{
    for (var intCounter = 0; intCounter < elements.length; intCounter++)
    { elements[intCounter].className = ""; }
}

结论

就是这样!一个简单的 JavaScript 解决方案,使用非侵入性 JavaScript 增强了反馈表单的可用性。查看这个功能齐全的示例

© . All rights reserved.