HTML5 datalist在实际项目中应用的可行性研究

这篇文章发布于 2013年03月27日,星期三,13:51,归类于 Web综合。 阅读 131387 次, 今日 6 次 21 条评论

 

一、需求以及资源脉

有些人积累了丰富的人脉,因此,有需求的时候,其会想到相关的人寻求帮助或合作。对于他们而言,人就是资源。

性格使然,我并不擅长人脉(虽然在不断提高这方面的不足),因此,我自知做不好销售或公关之类。但是,做技术却时不时能得到一些所谓的自我满足,原因呢?从本质上讲,无论你是与代码打交道还是与人打交道,你所打交道的对象都是资源,可以概括称为“资源脉”。因此,上面问题的答案可能在于自己有一定的技术相关资源的积累,因此,在有需求的时候,能够将这些积累的资源为自己所用。

人脉越丰富,与人打交道越得心应手;技术脉越丰富,与技术打交道越得心应手。因此,对于做技术的我们而言,学习必须是不断的,积累必须是持续的,否则资源脉匮乏,行事多阻碍。

下图为我最近接触的一个需求。先不管这种交互的必要性,也不要管UI的合理性,更不用管“请选择邮箱类型”是多么的废话,就单单需求而言,我们该如何实现?
交互需求图

早些年的时候(大概3年前-擦,这么久啦),自己写了个实现该功能jQuery插件mailAutoComplete, 不过,现在看来,此插件写得比较的,因此,除了个人网站、内网项目等,并不推荐使用。
文本框邮箱地址自动提示jQuery插件 张鑫旭-鑫空间-鑫生活

好比火车站里的厕所,八百年用一次的东西,自己并不想弄得过于复杂。因此,一向不循规蹈矩的我就想玩点不一样的花样实现。于是,我大脑迅速遍历自己这些年学习累积的一些“技术资源脉”,其中有个东西一下子进入了头版头条——HTML5 datalist.

两年前1月份(X,这么久啦)的“HTML5表单新特征简介与举例”中首次提到了HTML5 datalist, 可以实现自定义的列表效果。那个时候,只有Opera浏览器支持;如今,时过境迁,人是物非。

大家都听过“灵感”,灵感是如何产生的呢?实际上,灵感不是天上掉下来的,也不是人脑所固有的,而是经过艰巨劳动的长期酝酿促成的。它是一朵长期积累后偶尔得之的思想火花

道理都是想通的,有没有发现,灵感的说法与技术需求实现有异曲同工之妙,都是需要长期积累。这里,我并不是要得瑟什么,比我有想法的人多了去了,自己要积累的太多了,只是告诫自己、顺便提醒正在读此文的你:“虽说天下之学者,孰不欲一蹴而造圣人之域;但着眼现实,若想大成,须戒骄戒躁,静心积累,路漫漫其修远兮啊!”

貌似扯远了,有感而发而已,抱歉,下面回到正题。稍等,再插一句,我在写本文的时候,datalist实际应用的可行性自己并不确定,属于边写边尝试,因此,本文最后的结论可能是“可以”、也可能是“不推荐”,一起来探索吧~~

二、先大致了解datalist何物

demo先行,您可以狠狠地点击这里:HTML5 datalist简单使用demo

HTML如下(高亮为基本用法,一目了然):

列表:<input type="text" list="mydata" placeholder="热门电影排行" />
<datalist id="mydata">
    <option label="Top1" value="让子弹飞">
    <option label="Top2" value="非诚勿扰2">
    <option label="Top3" value="大笑江湖">
    <option label="Top4" value="赵氏孤儿">
    <option label="Top5" value="初恋这件小事">
</datalist>

在Chrome浏览器下,双击文本框,结果下面这样,效果还是蛮拉风的:
Chrome下datalist的效果截图 张鑫旭-鑫空间-鑫生活

FireFox的差异
在FireFox浏览器下,optionlabel值与value值只能显示一个,诡异的是label值优先显示——label值为空或缺省时才显示value值。也就是在FireFox浏览器下,上代码双击后的显示是:
firefox浏览器下label值优先显示示意

demo页面中看到的不是这样,是因为使用了JS清空了了所有optionlabel值。
FireFox浏览器label值为空后的显示 张鑫旭-鑫空间-鑫生活

浏览器支持
经测试,Opera,Chrome,IE10, FireFox浏览器都是支持HTML5 datalist自定义列表的。

三、datalist与动态邮件地址提示

demo先行,您可以狠狠地点击这里:HTML5 datalist与动态邮箱地址demo

一些浏览器下的效果截图,图儿们,注意队形,展示开始了(截自window 7):
FireFox下datalist下动态邮箱地址效果图 张鑫旭-鑫空间-鑫生活Chrome下datalist下动态邮箱地址效果图 张鑫旭-鑫空间-鑫生活Opera下datalist下动态邮箱地址效果图 张鑫旭-鑫空间-鑫生活IE10下datalist下动态邮箱地址效果图 张鑫旭-鑫空间-鑫生活

哟,还真那么回事,不由得啧啧称赞下。然而,上图只是新闻联播的展示画面,实际背后并没有这么简单光彩。

几乎完美的Chrome
Chrome浏览器在交互上,几乎无懈可击,就是我们要的效果:内容输入,列表显示,键盘/鼠标选择,赋值,列表隐藏,用一句洋文称赞下就是 – perfect!

但是,一番尝试,还是找到了瑕疵,如下截图:
Chrome浏览器下的瑕疵截图示意

出现在输入一些字符,删除,列表宽度与文本框宽度要一致的时候。

小问题不断的FireFox
1. 闪瞎眼睛
输入框输入内容的时候,浮动的下拉框更新的时候尼玛闪个不停,体验很不好,其他浏览器都很自然显示与匹配,相信这个问题再后续版本肯定会改进的。

闪动会级联另外一个问题,当文本框设置了autofocus的时候,页面载入的时候,会瞬间呈现丑陋的原始列表内容(*@qq.com...),阻碍的技术实现的灵活性(不能使用autofocus或原始列表只能是(@qq.com...))。

2. 不肯消失的列表
在Chrome下,我们点击列表项,文本框会复制,列表会隐藏。但是,在FireFox浏览器下,列表不会隐藏,这是糟糕的细节。原因何在?demo上的解释很拗口,打个通俗点的比方:FireFox好比个性感的狐狸精 ,摸一下她的屁股(datalist HTML变化),她屁股会翘一下(datalist出现)。我们想踹她的屁股让她不要翘(选择一个datalist项),结果她以为我们又摸她屁股,屁股又抬起来了(datalist又出现)……于是,屁股永远翘着!除非我们踹她的床啊被子什么的(点击页面空白是失去焦点),屁股才会下去(datalist隐藏)。

然而,demo上却没有问题,是因为demo做个相关的优化,会匹配输入内容以决定是否要踹火狐的“屁股”。

走得很近的IE10和Opera
IE10和Opera的呈现与交互走得很近。其datalist在动态呈现上有个致命的不足:滞后性!具体描述就是:动态列表地址比输入框中内容慢1拍。于是,一直到输入字符@时列表才会呈现;删除的时候永远会呈现,但永远少一个字符。
IE10以及Opera滞后一个字符 张鑫旭-鑫空间-鑫生活

我并未想到什么好的解决方法,求指点。不过,个人觉得,影响可以接受,毕竟,用户邮箱输入的多。

实现原理
实现的思路很简单,默认如下格式HTML:

邮箱:<input type="email" id="email" list="emailList" name="off_autocomplete" autofocus />
<datalist id="emailList">
    <option value="*@qq.com">
    <option value="*@163.com">
    <option value="*@gmail.com">
    <option value="*@yahoo.com.cn">
    <option value="*@126.com">
</datalist>

其中*为占位符,当文本框输入内容的时候,*替换成邮箱地址的前半部分,于是,动态邮件地址提示的效果就实现了。例如,当文本框输入了iam的时候,datalist相关HTML变成了:

<datalist id="emailList">
    <option value="iam@qq.com">
    <option value="iam@163.com">
    <option value="iam@gmail.com">
    <option value="iam@yahoo.com.cn">
    <option value="iam@126.com">
</datalist>

并匹配呈现出来了。

四、IE6~9怎么办?

对于IE6~9浏览器,如何以最小的成本实现类似的效果呢?datalist中的option选项元素让我想起了select控件,是不是可以尝试在select上找到出路呢——即IE6~9使用select代替datalist实现类似效果?

OK,稍等,我做个demo看看可行性和最后的效果如何……

(第二天白天~)一个晚上的折腾,搞了个凑合的demo,您可以狠狠地点击这里:HTML5 datalist与动态邮箱地址(兼容IE)demo

先看看一些效果截图吧(window 7):
ietester ie6下select下拉模拟截图 ietester ie8select模拟动态下拉截图IE10向下IE7模式下的效果图

IE9浏览器自以为是忽略不认识的datalist中的option选项们,因此,在本demo,通过datalist获取数据的方法在IE9浏览器下木有效果。但是,从可行性上讲,我们可以通过其他更好的方式支持。

低版本IE浏览器上的列表为传统的select下拉列表,通过设置size值赋予不同平时的下拉框UI。本质上将,select下拉以及datalist下拉都属于浏览器自带的下拉列表,因此,其有相通之处,例如,选中背景色、边框等是无法修改的;宽度都自适应于列表内容的(地址长,宽度自动变长);选中的值可以使用value表示等。不同之处也有,select下拉需要额外绑定键盘事件(上下键、回车)、点击选择以及稍微棘手的动态匹配,不过因为是select下拉框,处理的细节比ul > li的模拟要简单多了(例如,元素选中,直接设置当前optionselected就可以了,不要管什么选中元素切换以及背景色修改什么的)。

技术细节什么的估计大家都没兴趣,只字不提,您有兴趣,可以去demo瞅瞅。

IE6~IE9动态下拉的折腾让我确定了,IE6~9可以实现“神似”IE10以及其他现代浏览器datalist效果前者select > option, 后者datalist > option. 下面要做的事情就很清楚了,将上面的研究折腾做一番总结,写个简单的公用方法,完美收工!

四、datalist下的动态邮箱地址公共方法

啪啪啪,数个小时(带测试),当当当当,新鲜的方法出炉了——datalist-mail.js

方法名为:fnDatalistMail.
使用方法:fnDatalistMail(eleEmail, options); eleEmail表示邮件输入框DOM啦~ options参数可选,目前仅一个可选属性”email“, 表示哪些邮箱,默认值为:["qq.com", "163.com", "gmail.com", "yahoo.com.cn", "126.com"]. 实际使用不一定就是这些,您可以自己设置。

例如demo页面直接下面一段就实现效果了,没有任何额外CSS支持:

fnDatalistMail(document.getElementById("email"));

fnDatalistMail方法不依赖任何JavaScript框架,你可以自由使用。

忘记demo页面了,您可以狠狠地点击这里:公共方法下的动态邮件地址demo

这回IE9浏览器就乖了~
IE9浏览器下的效果 张鑫旭-鑫空间-鑫生活

五、实际应用的硬伤

功能都实现了,兼容性也没问题,性能也不错。但是,datalist/selectlist有个致命的硬伤——UI!显然,在面向广大普通用户的网站,一般网站是没有这个气量把datalist/selectlist生成的默认的略显简陋的列表(尤其IE)呈现给用户的,至少,挑剔的设计师是不能忍受的。从而导致一个幽默的妹子因为长得很幽默而没能被高富帅青睐。

据我所知,目前来看,datalist是不能随便定义样式的,因此,长相阻碍了datalist的实际应用。

不过,对于一些更强调功能或特定用户群体的网站/项目而言,这个东西到是可以试试哦!比方说公司的内网,我就有可能会在登录页面加上这个。

边学边写,错误难免;欢迎留言,欢迎指点。

六、更新与2013-04-02

回到现实,为了实际项目,还是使用传统的方法,今天下午抽了点时间写了个邮件列表下拉提示的jQuery插件。

您可以狠狠地点击这里:jquery.mailAutoComplete-4.0.js

demo页面狠狠地点击这里:邮箱自动下拉匹配插件demo

使用方法

$().mailAutoComplete(options);

options可选参数,支持参数有:

className
列表外部ul容器的类名,用来控制样式,默认是”emailist“.
email
下拉数组。默认值是:[“qq.com“,”gmail.com“,...,”sohu.com“,”sina.com“]
zIndex
下拉列表的层级

支持多个input框。

(本篇完)

分享到:


发表评论(目前21 条评论)

  1. Apparition2018说道:

    感觉可以不用占位符*,改如下两句:

    return option.value.replace(“@”, “”);

    eleList.innerHTML = htmlListInit.replace(/\@/g, arrValue[0] + “@”);

    因为没有占位符*,载入即匹配eleMail.fnListReplace.call(eleMail).focus();也可以去掉了

  2. 木乃伊说道:

    有一个问题希望大神能给点帮助:
    datalist下数据条数过多的时候,在火狐浏览器中会自动生成滚动条,但在谷歌浏览器中不会,现在希望在谷歌浏览器中能实现滚动条的生成,不知道是否有什么办法能做到?

  3. robin说道:

    有一个硬伤,在同时有value 和label的情况下,我要显示的是value,怎么才能获取到label的值呢。

  4. eddiexxxx说道:

    挺好的,但是input前面加文本或者label,下拉列表会错位啊,这个也解决一下会不会更好

  5. 找方法找到吐血说道:

    有人研究出datalist在chrome下能产生滚动条的方法吗?

  6. jelly说道:

    邮箱:

    var mail=document.getElementById(‘mail’);
    mail.oninput=function () { //不兼容IE
    var list=document.getElementById(‘list’);
    var opt=list.getElementsByTagName(‘option’);
    var arr=[‘@qq.com’,’@163.com’,’@126.com’,’@gmail.com’,’@outlook.com’];
    if(mail.value.indexOf(‘@’)==-1){
    for(var i=0;i<opt.length;i++){
    opt[i].innerText=mail.value+arr[i];
    }
    }
    }

  7. xiaoxiao说道:

    插件下载不了呀

  8. xiao刘说道:

    好东西先收藏了,可惜自己永远都写不出来

  9. 绑定怎么也绑定了这个列表???说道:

    当你选择了的绑定值时,此时去双击也会出现这个下拉列表

    而双击就不会,为什么会绑定列表

  10. Almeida说道:

    是个好东东,可惜用不起来,每次到这return $(this).each(function() {…就不往下走了,咋回事,能看下不?

    页面:

    New Document

    $(“.inputMailList”).mailAutoComplete();

    .demo p {width:1000px; margin-left:auto; margin-right:auto;}
    .input{padding:12px; width:300px; border:1px solid #c2c2c2; border-radius:4px; box-shadow:0 0 1px #fff, inset 0 0 2px rgba(0,0,0,.15); background-color:#F2F2F2; font-size:14px;}
    .emailist{border:1px solid #bdbdbd; border-radius: 4px; background-color:#fff; color:#666; font-size:14px; list-style-type:0; padding:0; margin:0; overflow:hidden;}
    .emailist li{padding:2px 11px; cursor:pointer;}
    .emailist li:hover{background-color:#eee;}

  11. suqingbin说道:

    美中不足的是,利用jquery的部分

    在鼠标选中下拉邮箱后不能将光标定位到 input email 里面。。。。

  12. wuxiaolan91说道:

    我测试了之后发现你这个在ie10下有bug.
    http://www.zhangxinxu.com/study/201303/html5-datalist-dynamic-email-compatible-ie-demo.html
    在ie10下一打开页面默认就会把@qq.com等其他邮箱的后缀的这个列表给展示出来
    可是我输入字母,比如”a”or”aa”的时候,这个可供选择不同邮箱后缀名的列表却没有出现了.

  13. 二次元说道:

    其实我觉得最好的方法就是另起一个登录页面,然后用你以前写的那个插件。。。。。

  14. s说道:

    IE 10 的 datalist 很漂亮了好吧。。。我真心没有开愚人节玩笑。。。

  15. 胡尐睿丶说道:

    HTML5的东西,如果不能做到大统一(功能&展示),即使有再多好用的API,也无法大面积使用。