HTML 5 DataList入门教程

译文
开发 开发工具 后端
在Web设计中,经常会用到如输入框的自动下拉提示,这将大大方便用户的输入。本文将以实例的方式讲解HTML 5中DataList的使用和要注意的事项。

Web设计中,经常会用到如输入框的自动下拉提示,这将大大方便用户的输入。比如在Google中进行搜索的时候,就会出现下拉的智能提示列表选择框。这样的下拉列表框称为AutoComplete。在以前,如果要实现这样的功能,必须要求开发者使用一些Javascript的技巧或相关的框架进行ajax调用,需要一定的编程工作量。但随着HTML 5 的慢慢普及,开发者可以使用其中的新的DataList标记就能快速开发出十分漂亮的 AutoComplete组件的效果。本文将以实例的方式讲解HTML 5DataList的使用和要注意的事项。

创建DataList

    首先,我们看下传统的简单文本输入框是什么样子的,如下代码所示:

  1. <label for="favorite_team">Favorite Team:</label> 
  2.  
  3. <input type="text" name="team" id="favorite_team"> 

这个输入框中,用户必须手动在其中输入文字内容,并没有提示,而如果使用了HTML5 中的DataList,则可以允许用户从下拉列表中选择。一个最简单的DataList使用如下方式声明:

  1.  <datalist> 
  2.   <option>Detroit Lions</option> 
  3.   <option>Detroit Pistons</option> 
  4.   <option>Detroit Red Wings</option> 
  5.   <option>Detroit Tigers</option> 
  6.   <!-- etc... --> 
  7. </datalist> 

 

<datalist>标签中所包裹的就是可供用户选择的项了。
   那么,如何将datalist和文本框进行绑定呢?使用如下的代码:

  1. <label for="favorite_team">Favorite Team:</label> 
  2. <input type="text" name="team" id="favorite_team" list="team_list"> 
  3. <datalist id="team_list"> 
  4.   <option>Detroit Lions</option> 
  5.   <option>Detroit Pistons</option> 
  6.   <option>Detroit Red Wings</option> 
  7.   <option>Detroit Tigers</option> 
  8.  </datalist> 

在上面的代码中,为文本输入框inputbox指定list属性,其值一定要和<datalist>中的id值相匹配。
在各浏览器中运行上面的代码,马上可以看到效果了,如下图:

在上图中,左上角的图为IE 10中的效果,右上角图为Firefox 18中的效果,左下角图为Chrome 24中的效果,右下角图为Opera 12的效果。
要注意的是IE 10Opera 中,不需要用户必须输入一个字符才看到下拉的建议列表,而其他浏览器需要用户至少输入一个字符才能看到效果。
Datlist中,同样可以为每一个下拉列表选项指定一个value值,如下代码:

  1. label for="state">State:</label> 
  2. <input type="text" name="state" id="state" list="state_list"> 
  3. <datalist id="state_list"> 
  4.   <option value="AL">Alabama</option> 
  5.   <option value="AK">Alaska</option> 
  6.   <option value="AZ">Arizona</option> 
  7.   <option value="AR">Arkansas</option> 
  8. </datalist> 

如果在option中一旦指定了value的值,则用户通过下拉列表选择后,文本框中显示的将会是value的值,如下图:

 

Autocomplete属性

下面讲解autocomplete属性。该属性可以设置为onoff,表示输入字段是否应该启用自动完成功能,如下代码所示:

 
  1. <form> 
  2.   <!-- 
  3.   如果设置了autocomplete属性,则将会继承父元表单元素中autocomplete的值得,
  4. 如果也没设置,则默认autocomplete为on,这里没进行任何设置,所以firstName的autocomplete属性为on 
  5.   --> 
  6.   <input type="text" name="firstName"> 
  7.   <!-- 
  8. autocomplete设置为on,浏览器将记忆下用户每次输入的值 
  9.   --> 
  10.   <input type="text" name="address" autocomplete="on"> 
  11.   <!-- 
  12. 设置为off,代表浏览器将不记忆用户在该文本框本次的输入,也不进行建议提醒 
  13.   --> 
  14.   <input type="text" name="secret" autocomplete="off"> 
  15. </form> 

要注意的是,在opera浏览器中,如果设置autocompleteoff,则根本不显示datalist,而在其他浏览器中,是会显示datalist的,只不过失去自动建议提醒功能。

其他输入的属性

接下来,我们学习下datalist中其他的输入属性。在datalist的下拉列表提示框中,还可以支持其他类型的HTML 5标签,比如下面的代码,展示的是一个HTML 5的滑动数字条,在运行后,当鼠标每向右滑动时,会有对应的文字提示:

  1. label for="donation">Donation Amount (USD):</label> 
  2. <input type="range" name="donation" id="donation" list="donation_list" 
  3.   step="5" min="5" max="200"> 
  4. <datalist id="donation_list"> 
  5.   <option>25</option> 
  6.   <option>50</option> 
  7.   <option>100</option> 
  8.   <option>200</option> 
  9. </datalist> 

#p#

下图是分别在Chrome 24IE 10的效果图:


  
  

 

可惜的是,目前只有ChromeIE 10支持datalist中使用range范围控件的做法。下面的这个表,很清晰说明了在各个浏览器中datalist和其他HTML 5控件搭配的情况:


什么时候该使用DataList?

   要注意的是,使用这种下拉的智能提示框也要注意场合。比如在一些要选择不是太多的场景下,使用一般的下拉框其实就可以了。而如果在需要用户在很多数据中去选择,则可以建议使用Datalist下拉建议提示框,因为可以方便用户快速检索去选择。一个典型的场景就是对世界各个国家的选择,如下代码:

  1. <label for="country">Country:</label>  
  2. <input type="text" id="country" list="country_list">  
  3. <datalist id="country_list">  
  4.   <option value="AF">Afghanistan</option>  
  5.   <option value="AX">Åland Islands</option>  
  6.   <option value="AL">Albania</option>  
  7.   <option value="DZ">Algeria</option>  
  8.   <!-- more -->  
  9. </datalist>  

限制datalist选择的值

有的场景下,我们要限制用户在下拉自动提示列表中所选择的值,而在IE 10,有一系列专门为此新加入的API,具体可以参考:

http://msdn.microsoft.com/en-us/library/ie/hh673544(v=vs.85).aspx#dom_methods_input_val,下面的代码是一个使用的例子:

  1. / 找出所有绑定了datalist的input文本框 
  2. var inputs = document.querySelectorAll('input[list]'); 
  3. for (var i = 0; i < inputs.length; i++) { 
  4.   //当输入文本框的值发生改变 
  5.   inputs[i].addEventListener('change'function() { 
  6.     var optionFound = false
  7.       datalist = this.list; 
  8. //判断用户的输入是否存在于datalist的下拉列表框的数据项中 
  9.     for (var j = 0; j < datalist.options.length; j++) { 
  10.         if (this.value == datalist.options[j].value) { 
  11.             optionFound = true
  12.             break
  13.         } 
  14.     } 
  15.    
  16. 使用IE 10的Validation API中的setCustomValidity方法对是否存在合法的输入值进行前端的响应展示 
  17.     if (optionFound) { 
  18.       this.setCustomValidity(''); 
  19. else { 
  20. //如果用户的输入不在datalist列表中,前端显示相关错误信息 
  21.       this.setCustomValidity('Please select a valid value.'); 
  22.     } 
  23.   }); 

 下图是在IE 10下,当用户输入的值不在下拉列表后,浏览器显示的错误提示信息如下:

要注意的是,客户端的这种验证不能取代服务端的验证,***的做法是依然在服务端进行合法性的校验。而且要注意的是在旧的浏览器中,是缺乏这种对于datalist的校验支持的,除非开发者另外进行编码进行校验。

如何应对不支持的浏览器

在写本文的时候,依然只有IE 10,Firefox 4+,Chrome 20+Opera是支持datalist的,这意味着不少旧版本的浏览器的用户不能使用datalist的功能,但办法总是有的,下面分别介绍一些折衷的办法

1datalist中嵌套使用传统的select下拉选择框

    一个不错的解决方法,是在提供传统的select下拉文本框的同时,提供给用户能输入普通文本的文本框,如下代码:

  1. <label for="country">Country:</label>  
  2. <datalist id="country_list">  
  3.   <select name="country">  
  4.     <option value="AF">Afghanistan</option>  
  5.     <option value="AX">Åland Islands</option>  
  6.     <option value="AL">Albania</option>  
  7.     <option value="DZ">Algeria</option>  
  8.     <option value="AS">American Samoa</option>  
  9.     <!-- more -->  
  10.   </select>  
  11.   If other, please specify:  
  12. </datalist>  
  13. <input type="text" name="country" id="country" list="country_list">  

 

#p#

运行的效果为如下图所示:  

在写本文的时候,依然只有IE 10,Firefox 4+,Chrome 20+Opera是支持datalist的,这意味着不少旧版本的浏览器的用户不能使用datalist的功能,但办法总是有的,下面分别介绍一些折衷的办法:

1datalist中嵌套使用传统的select下拉选择框

    一个不错的解决方法,是在提供传统的select下拉文本框的同时,提供给用户能输入普通文本的文本框,如下代码:

  1. <label for="country">Country:</label> 
  2. <datalist id="country_list"> 
  3.   <select name="country"> 
  4.     <option value="AF">Afghanistan</option> 
  5.     <option value="AX">Åland Islands</option> 
  6.     <option value="AL">Albania</option> 
  7.     <option value="DZ">Algeria</option> 
  8.     <option value="AS">American Samoa</option> 
  9.     <!-- more --> 
  10.   </select> 
  11.   If other, please specify: 
  12. </datalist> 
  13. <input type="text" name="country" id="country" list="country_list"> 
 

 运行的效果为如下图所示:

 

意在上面的代码中,在datalist中嵌套了传统的select下拉文本框,而input文本框中依然绑定了datalist,这样的好处是,当在不支持datalist的浏览器中运行的时候会有上图的效果:一边是下拉选择,另外的是可以允许用户输入下拉列表中不存在的记录。而上面的代码如果在支持datalist的浏览器中运行,则是原来的只显示一个datalist的效果。

2使用jquery ui中的autocomplete插件

    还有一种方法就是判断当用户的浏览器是不支持datalist的话,则使用jquery ui中的autocomplete插件,代码如下:

  1. if (Modernizr.input.list) {  
  2. //如果返回值为true,则证明浏览器支持datalist  
  3.   } else {  
  4.     //浏览器不支持datalist  
  5.   }  
  6. }  

使用jquery ui中的autocomplete插件的原因之一是因为其功能强大和简单易用,当然读者可以从下面的这个地址获得更多的候选方案:https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-Browser-Polyfills,里面提供了很多在其他浏览器中用其他方法实现同样的HTML 5功能的方法。下面是具体的代码:

  1. var datalist, 
  2.   listAttribute, 
  3.   options = []; 
  4. if (!Modernizr.input.list) { 
  5.   // 对每一个绑定datalist的输入文本框循环遍历 
  6.   $('input[type="text"][list]').each(function() { 
  7.     //找出对应的datalist 
  8.     listAttribute = $(this).attr('list'); 
  9.     datalist = $('#' + listAttribute); 
  10.    
  11.     if (datalist.length > 0) { 
  12.       options = []; 
  13.   //将datalist中的option值复制到jquery autocomplete控件中去     
  14.       datalist.find('option').each(function() { 
  15.         options.push({ label: this.innerHTML, value: this.value }); 
  16.       }); 
  17.     //将options和autocomplete控件重新绑定 
  18.       $(this).autocomplete({ source: options }); 
  19.     } 
  20.   }); 
  21.   // 移除所有的datalist不予以显示 
  22.   $('datalist').remove(); 

 

上面代码的核心,就是找出所有的datalist中的值,然后循环逐一复制到传统的options数组中,然后将optionsautocomplete控件重新绑定,,并不显示datalist,这样上面的代码就既可以在支持datalist的浏览器中运行,也可以在不支持datalist的浏览器中运行。

   下图是在Safari浏览器中运行的效果图:

在上面的图中,可以看到,jquery autocomplete默认是下拉列出和用户输入字符匹配的所有单词,而原生的datalist只是列出首字母相同的单词。因此如果需要改动的话,可以按如下代码的方式,则可以让jquery autocomplete达到相同的效果。

  1. <input type="text" id="autocomplete"
  2. <script> 
  3. var options = ['Badger''Bat''Cat''Cheetah''Crocodile''Deer''Donkey'
  4.   'Elephant''Fish''Frog''Giraffe''Gorilla']; 
  5. $('#autocomplete').autocomplete({ 
  6. //req是用户输入的字符,responseFn是返回给用户的列表. 
  7.   source: function (req, responseFn) { 
  8.     var term = $.ui.autocomplete.escapeRegex(req.term), 
  9.   
  10. //使用正则表达式去匹配谁首字幕,'i'表示使用大小写敏感匹配 
  11.       matcher = new RegExp('^' + term, 'i'), 
  12.       //循环options并只选择满足的 
  13.       matches = $.grep(options, function (item) { 
  14.         return matcher.test(item); 
  15.       }); 
  16.        responseFn(matches); 
  17.   } 
  18. }); 
  19. </script> 

要注意的是,针对旧版本的IE 浏览器(IE 9及之前的)必须要求options标签是一定要位于select标签的子标签中,这个可以通过使用如下代码的

条件注释去解决这个问题(参考:http://msdn.microsoft.com/library/ms537512.aspx

  1. <datalist> 
  2.   <!--[if IE]><select><!--<![endif]--> 
  3.   <option>Apple</option> 
  4.   <option>Banana</option> 
  5.   <option>Cherry</option> 
  6.   <!- etc --> 
  7.   <!--[if IE]><select><!--<![endif]--> 
  8. </datalist> 

这样,IE 9及以前的IE 浏览器则不会对以上的语法报错了。

Datalist的限制

当然,Datalist也有限制和不足之处,体现在:

1)不能使用CSS去随意控制或改变其下拉建议列表中的项

 2)不能控制datalist的位置

 3) 不能控制每次当用户输入多少个字符后,就出现下拉建议列表

 4)不能控制大小写敏感,或当匹配什么样的字符就出现下拉建议列表

 5)不能将其与服务端的数据源绑定

   因此,目前来说,除非HTM L5关于datalist的相关标准有继续修订,或者各大浏览器厂商继续去改进,否则建议在实际的应用中,依然使用如jQuery Autocomplete等类似的插件去实现该功能。

 

 

责任编辑:陈四芳 来源: 51CTO
相关推荐

2011-07-11 09:58:52

2009-07-08 15:12:48

Java Servle

2014-05-26 15:35:55

Web组件Web Compone

2009-08-25 16:01:43

DataList控件入

2013-08-29 14:12:52

Storm分布式实时计算

2010-08-03 13:06:15

Flex Builde

2018-03-22 14:59:13

Docker入门容器

2011-09-02 10:59:10

jQuery Mobi

2010-07-20 16:19:54

Perl

2010-06-18 16:56:50

UML建模语言

2010-08-03 14:37:30

Flex入门教程

2010-05-21 12:50:45

Subversion快

2011-07-21 10:29:18

iPhone 开发

2010-07-27 15:53:15

2010-06-13 09:45:35

Widget开发

2012-05-10 08:29:46

XcodeiOSPhoneGap

2013-08-29 14:28:09

StormHadoop

2010-05-27 17:27:45

Subversion快

2010-03-12 14:04:32

Python入门教程

2011-06-16 09:40:53

QML 教程
点赞
收藏

51CTO技术栈公众号