现在的位置: 首页 > 综合 > 正文

用Javascript制作一个可自动填写的文本框(一) 选择自 yjgx007 的 Blog

2012年08月31日 ⁄ 综合 ⁄ 共 6881字 ⁄ 字号 评论关闭
CSDN - 文档中心 - Javascript 阅读:8074   评论: 1    参与评论
标题   用Javascript制作一个可自动填写的文本框(一)     选择自 yjgx007 的 Blog
关键字   IE Opera Mozilla TextRange 浏览器检测
出处   http://www.sitepoint.com/article/1220/

版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处http://xinyistudio.vicp.net/和作者信息及本声明

 

本文适合中高级读者

译者序:

为了获取用户更多的信息,你不惜网站页面中产生了大量的文本框,选单,列表框,当用户看到如此繁多的需要输入或选择项,很有可能为此产生厌倦并最终离开你的网站。

采用Javascript对输入文本框更好的设计,能够尽可能的避免上述问题,希望本篇译文能够对你在web页面的开发设计当中有所帮助,译文翻译错误难免,望大家批评指正。

 

 

    今天人们最不愿意面对的就是填写大量的表单(form),特别是那些需要敲入字符的文本框(就是我们经常用的<input type=text> html标记, 以后为方便就称为文本框)。

微软在outlook中结合了可自动完成输入的文本框--文本框检查由用户输入的少量的字符,然后从给定的下拉列表中给出一个建议的词。同样的,当你开始在web地址栏中填入一个url地址,你的Web浏览器会给你推荐一个url的下拉列表单。

 

在这篇教程中用了一点点Javascript的控制,我们将创建具有与IE(版本5.5或更高)

Mozilla(版本1.0或更高)浏览器相类似行为的输入文本框。

 

 

Ø 简单的浏览器检测

-----------

首先,我们需要做一个浏览器的检测,下面是一些简单的代码(这个过程可以用你自已写的代码替代它)

var isOpera = navigator.userAgent.indexOf(“Opera”) > -1;

var isIE = navigator.userAgent.indexOf(“MSIE”) > 1 && !isOpera;

var isMoz = navigator.userAgent.indexOf(“Mozilla/5.”) == 0 && !isOpera;

 

这代码很明显不是非常完善,但它看来对于我们要达到的目的已足矣。让我们开始这个项目吧。

 

Ø 选择文本框

---------――

在这过程的第一步是创建一个方法,这个方法可以在一个文本框中选择确定的文本数。我将

调用这个方法 textboxSelect() , 它有三个参数,第一个参数是让这个方法作用于的对象:oTextbox;第二个参数是非必选项,它指示了选择的起始位置(如果这个参数被忽略,那么全部的文本都被选择);第三个参数,同样是非必选项,指示了选择的结束位置。如果提供了第二个参数,但第三个参数未提供,在文本框中被选的文本将从起始位置到结束位置。

 

我们写一个非常容易理解的格式:如果仅有一个参数提供,那么我们就使用文本框的原型方法select() 在这个文本框中以选择所有的文本:

 

function textboxSelect(oTextbox, iStart, iEnd) {

 

   switch(arguments.length) {

       case 1:

           oTextbox.select();

           break;

       ...

   }

}

 

在这里我们使用了switch语句测试有多少个参数输入。如果仅有一个,即只有oTextbox

输入。下一步, 我们跳到有三个参数都被选择的case语句的开始处(iStartiEnd都被选择)。

这里,我们需要用一个浏览器检测一下这个方法所做的一切,对于IE浏览器,我们将使用一个文本范围对象。

 

function textboxSelect (oTextbox, iStart, iEnd) {

 

   switch(arguments.length) {

       case 1:

           oTextbox.select();

           break;

 

      case 3:

           

           if (isIE) {

               var oRange = oTextbox.createTextRange();

               oRange.moveStart("character", iStart);

               oRange.moveEnd("character", -oTextbox.value.length + iEnd);     

               oRange.select();                                             

           } else if (isMoz) {

               ...

           }                    

   }

}

 

在粗体代码中,我们从一个text range对象(由文本框对象创建的文本范围对象TextRange)开始,TextRange设置了文本选择范围的起始和结束坐标,要调整这开始坐标我们用moveStart() 方法;这个方法给出了两个参数:参数一是移动间隔类型,代码中使用了”character”(字符)类型 ;参数二是移动多少个间隔,比如移动了5个间隔那么就由参数一”character”得知移动了5个字符, 如果参数一是”word”(词),那么就移动了5个词。(译者注:关于TextRange对象的方法详细说明详见MSDN)。moveEnd()有同样的参数,稍有不同的是其第二个参数必须是负数(译者注:在MSDN2001中查得这个参数可以是正数,可能原作者考虑到IE版本较低的问题),你可以想象为移动到被选择文本结束处,然后后退一个间隔,后退两个间隔。为了获得moveEnd()的第二个参数,我们将赋给 iEnd文本框中文本长度的负值, 因此,如果iEnd 8且文本框中有10个字符,第二个参数变为-2,选择范围会将结束点会后退2个字符。最终,我们调用select() 方法在文本框中加亮选择的范围。

 

Mozilla浏览器完成上面这些事情居然更容易办到。

文本框对象有一个setSelectionRange() 方法,它有两个参数:选择的开始和结束位置,可以直接通过iStart iEnd 设定:

 

function textboxSelect (oTextbox, iStart, iEnd) {

   switch(arguments.length) {
       case 1:
           oTextbox.select();
           break;

       case 3:
           
           if (isIE) {
               var oRange = oTextbox.createTextRange();
               oRange.moveStart("character", iStart);
               oRange.moveEnd("character", -oTextbox.value.length + iEnd);      
               oRange.select();                                              
           } else if (isMoz) {
               oTextbox.setSelectionRange(iStart, iEnd);
           }                    
   }
}

 

现在我们返回到上一个case语句处,即只赋给了两个参数(iEnd 未赋值)的case语句处。

实际上,与赋三个参数不同的是iEnd 必须等于在文本框中字符串的长度就可以了。像下面这样实现:

function textboxSelect (oTextbox, iStart, iEnd) {

   switch(arguments.length) {
       case 1:
           oTextbox.select();
           break;

       case 2:
           iEnd = oTextbox.value.length;
           /* falls through case3继续处理
*/
           
       case 3:          
           if (isIE) {
               var oRange = oTextbox.createTextRange();
               oRange.moveStart("character", iStart);
               oRange.moveEnd("character", -oTextbox.value.length + iEnd);      
               oRange.select();                                              
           } else if (isMoz){
               oTextbox.setSelectionRange(iStart, iEnd);
           }                    
   }
}

 

在上面的case 2 中我们没有使用break 语句,只是在执行完case 2后的语句后再进入下一个case语句。

 

在函数的最后结尾处设置文本框聚焦,以便用户敲入的字符可以代替选择的文本。

function textboxSelect (oTextbox, iStart, iEnd) {

   switch(arguments.length) {
       case 1:
           oTextbox.select();
           break;

       case 2:
           iEnd = oTextbox.value.length;
           /* falls through */
           
       case 3:          
           if (isIE) {
               var oRange = oTextbox.createTextRange();
               oRange.moveStart("character", iStart);
               oRange.moveEnd("character", -oTextbox.value.length + iEnd);      
               oRange.select();                                              
           } else if (isMoz){
               oTextbox.setSelectionRange(iStart, iEnd);
           }                    
   }

   oTextbox.focus();
}

 

Ø 替换文本框中选择的文本(译者注:该功能似乎用处不大,读者直接跳过)

-----------

另一项任务是我们需要用一些其它的文本来替换当前选择的文本,为此,创建了textboxReplaceSelect() 方法,它有两个参数:作用于的文本框对象和要插入的文本。在这里我们要用到TextRange对象,我们需要为IEMozilla建立不同的代码,让我们先给出IE的代码:

function textboxReplaceSelect (oTextbox, sText) {

   if (isIE) {
       var oRange = document.selection.createRange();
       oRange.text = sText;
       oRange.collapse(true);
       oRange.select();                                
   } else if (isMoz) {
       ...
   }

   oTextbox.focus();
}

 

在上面的第4行,从文档当前选择区创建了TextRange对象(可以设想一下在文本框中,由onkeypress事件触发调用),随后的一行我们用给定的字符串替换在选择范围中的文本,在第6行中,调用了TextRange对象的collapse方法,设置选择范围的宽度为0;其中的布尔型参数如果是true,光标会偏向选择范围的结束处,反之。最后,我们用select() 方法将光标确定在选择范围的结束处。

Mozilla浏览器中利用string对象的一些简单操作来完成相同的效果。我们可以用文本框对象的selectionStartselectionEnd属性来确定选择的起始和结束点:

 

function textboxReplaceSelect (oTextbox, sText) {

   if (isIE) {
       var oRange = document.selection.createRange();
       oRange.text = sText;
       oRange.collapse(true);
       oRange.select();                                
   } else if (isMoz) {
      var iStart = oTextbox.selectionStart;
       oTextbox.value = oTextbox.value.substring(0, iStart) + sText + oTextbox.value.substring(oTextbox.selectionEnd, oTextbox.value.length);
       oTextbox.setSelectionRange(iStart + sText.length, iStart + sText.length);
   }

   oTextbox.focus();
}

 

在上面的第9行,保存了选择的起始点,第10行看起来挺费解的,事实上这行代码只是用于得到所选择文本前、后的字符串,并在它们之间添加要替换的字符串文本。

接下来的一句代码是需要纠正一下光标在文本后的位置――开始点位置加上所替换文本的长度。

 

Ø 匹配

―――――――――

下步需要处理的是写一个方法:给定的一个字符串A,在一个string数组中搜索并返回起始处使用了这个字符串A的第一个字符串值B(例如:通过’a’string数组中查找起始位置使用”a”的字符串值”abcd”)。这个方法的名称是autocompleteMatch(), 它有两个参数:需要匹配的文本和被匹配的所有文本值的数组。

 

直接搜索――反复地检查数组中的每个值。方法返回以true的形式返回一个值,否则如果没有匹配的值找到,将返回null。全部代码如下:

function autocompleteMatch (sText, arrValues) {

   for (var i=0; i < arrValues.length; i++) {
       if (arrValues[i].indexOf(sText) == 0) {
           return arrValues[i];
       }
   }

   return null;

}

 

需要注意的是:为保证这函数能够正确工作,你应该将数组中的字符串按字母排序。

Ø autocomplete()的补充

autocomplete() 方法补充一下,我们先到可自动完成的文本框标记中看一下(译者注<input type=text>),autocomplete()方法将给出三个参数:作用于的文本框的对象oTextbox对象,event(事件)对象。调用方法如下:

<input type=”text” onkeyup=”return autocomplete(this, event, arrValues)” />

 

考虑到在文本框中触发onkeypress事件(译者更正:应该使用onkeyup事件,以保证字符已被输入)的第一个键的键码:

function autocomplete(oTextbox, oEvent, arrValues) {

   switch (oEvent.keyCode) {

       ...
   }
}

 

有许多按键需要被屏蔽,如光标键,只需要在下面指定的case语句中返回true

function autocomplete(oTextbox, oEvent, arrValues) {

   switch (oEvent.keyCode) {
       case 38: // á

       case 40: //
â
       case 37: //
ß
       case 39: //
à
       case 33: // Page Up

       case 34: // Page down

       case 36: // Home

       case 35: // End
               
       case 13: // Enter

       case 9: // Tab

       case 27: // Esc

       case 16: // Shift

       case 17: // Ctrl

       case 18: // Alt

       case 20: // Caps Lock

       case 8: //
退格键 
       case 46: // Delete

           return true;
           break;
       ...

   }
}

抱歉!评论已关闭.