基于原生HTML的UI组件开发

这篇文章发布于 2016年01月22日,星期五,17:35,归类于 Web综合。 阅读 49990 次, 今日 16 次 32 条评论

 

本文属于波澜不惊,平铺直叙版本。如果想看有有激情有思想的版本,可以点击这里:“顺势而为,HTML发展与UI组件设计进化”

一、基于HTML开发组件的设计思想

要想知道基于原生的HTML进行UI组件开发是什么鬼,您可以狠狠地点击这里:基于原生的HTML UI组件体验demo

点击上面的demo, 进入一个平凡的静态页面,引入眼帘的是一个普通的表单,里面的UI都是系统默认的,HTML功能也是原生的。

例如:
  • title提示
    title提示
  • 选择日期
    选择日期
  • 点击提交的表单验证
    表单验证
UI虽然原始,但是功能却是很健全的。
例如:
  • 男女款式、城市以及运费险对价格的影响
    交互与最终价格
  • 表单提交事件
    表单提交
下面,见证奇迹的时刻到了,点击demo页面(下图所示)的按钮进行某项目UI组件资源的加载和初始化:

点击测试按钮示意

结果,一瞬间,上面原始粗糙的界面一下子变成了这样子:
加载CSS资源后的模样

妥妥的丑小鸭变成了白天鹅,包括之前原生的HTML功能。

例如:
  • title提示
    引入UI组件后的提示
  • 选择日期
    日期选择示意
  • 点击提交的表单验证
    表单验证

而,最最重要,和最最神奇的事情是:我们仅仅是引入了UI组件的一些CSS和JS,对,仅仅是引入和一点初始化,没有动之前一点点一丝丝的业务JS. 但是,之前的各种交互功能,却完全不受影响,反而体验更上两层楼!

请看下面的gif截图演示:
业务功能不受影响示意

之所以这里的UI组件可以和业务相关JavaScript完全分离,同时可以无缝对接。就是因为设计理念上是基于原生的HTML实现的,让UI组件回归了其本质或者说本职作用——UI.

二、基于原生HTML的UI组件开发

解决2个疑问:
  1. 为何可以基于原生HTML进行UI组件开发?
  2. 如何基于原生HTML进行UI组件开发?

1. 为何可以基于原生HTML进行UI组件开发?
HTML中自带的很多原生的UI表现和UI组件的UI表现本质上是类似的,差别仅仅在于长相的粗糙和精致。

举个例子,title提示。浏览器默认使用title属性,长这样:
title提示

而设计师设计的tips组件是小黑风格,如下:
引入UI组件后的提示

这两者其实是一个东西,作用是一样的,差别仅仅在于——UI. 因此,我们完全可以基于原生的title属性实现我们的tips提示效果。利用相同的本质,改变的仅仅是呈现的样子。

再举个更有意思的例子,表单验证。在HTML5中,表单默认内置验证,基于type, required, pattern, max, min等HTML原生属性,且自带UI(下图是win下Chrome效果,其他系统其他浏览器长相不一样):
原生表单验证示意

下图则是team决定采用的UI形式:
表单验证

同样的,验证的本质都是类似的,交互的形式也是类似的,不一样的仅仅是UI. 因此,我们完全可以基于原生的HTML验证规则实现我们的表单验证效果。利用相同的本质,改变的仅仅是呈现的样子。

其他很多UI组件都是类似的。

当我们希望改变的仅仅是相貌的时候,重复利用之前的灵魂难道不是最合理的策略吗?

2. 如何基于原生HTML进行UI组件开发?
有2个要点:① API参数直接取自HTML; ② 回调直接trigger原生事件;

我们拿上面提过的日期时间选择器举例说明下。

日期选择器,主流实现基本上是这样的:

<input id="date" type="text">
new DatePicker($("#date"), {
  type: "date",
  initDate: ..,
  beginDate: ..,
  endDate: ..,
  onSelected: $.noop
});

API参数,事件的回调全部源自JS参数。

而面向HTML的设计思想下的实现则是:

<input type="date" min="2015-11-11" max="2015-12-31">
new DateTime($("[type=date]");

API参数全部取自HTML,JS代码仅仅就是全局初始化(一次覆盖所有时间类控件)。其中HTML中的type属性对应JS中的type API, value属性值对应initDate值, min/max分别对应beginDate/endDate. 至于onSelected回调,则是通过trigger input框原生的change时间实现。

于是,其他前端小伙伴在开发的时候,就可以按照原生的HTML属性和事件来开发就可以了,从而实现业务JS和UI组件基于0成本的无缝对接。

三、面向HTML的UI组件开发的好处

  1. 语义化,可访问性,SEO等;
  2. 学习成本低;
  3. 专注HTML控件本身,而不是组件;
  4. 可以一次性全局处理;

1. 语义化,可访问性
毕竟是基于原生HTML来开发的,这一块必定杠杠的。

2. 更低的学习成本
不需要记住千差万别的JS API名称,记住标准的HTML5属性即可,反过来对一些前端开发同学的HTML学习还起到了帮助作用。

而学习成本低对于跨团队合作非常有帮助。其他团队同学乐于使用你的东西,介入快,实现效果好,大家都开心。反之,API千差万别,每次使用都要去翻文档,肯定影响合作。

不过,实践下来,有一点学习成本我没考虑到,就是转换思维方式的学习成本。实际上只要面向元素的HTML元素开发就可以了,但是有遇到小伙伴,还是按照老的思维方式,在生成的UI组件元素上做文章。

3. 专注HTML控件本身,而不是组件
举个例子,日期选择器,当日期修改了,我们要干嘛干嘛,直接:

$("input").change(function() {});

想要修改日期范围,直接:

$("input").attr({
  "min": "2015-12-27",
  "max": "2016-12-27"
});

UI组件会自动同步。没有任何组件相关的JS代码,也没有什么故弄玄虚,没有所谓的高屋建瓴,全是很简单基础的HTML操作。是不是这样的开发反而很省心,连小白用户也能上手?

于是乎,在多团队联合协作开发的时候,前端开发的进度并不会受UI组件开发影响,面向HTML,专心自身业务开发就可以了。

于是乎,实现了一个听上去很了不得的东西:前端分离

不仅如此,厂子里有很多开发,负责内部项目,会写JS擅长业务功能实现,但是,UI这块是个软肋。OK,此时,我们这里面向HTML开发的UI组件体系就是其救星,对吧,直接引入CSS和JS,简单全局初始化一下(可能还有一些简单的微调),结果,页面立马高大上了,是不是很有用!

4. 可以一次性全局处理
传统实现,每个具体业务的脚本里面要参与UI组件的具体API参数设置。而面向HTML的实现,API落地与具体的业务页面,于是乎,只要在项目的common.js中全局初始化一下,如下拉Select.init(), 具体的业务JS文件(绝大多数情况下)中就无需再出现UI组件相关的JS代码。

UI层的JS代码和业务层JS代码分离,实现进一步的「前端分离」,去耦合。对于日后的维护、升级等必定大有裨益。

四、总结

本文主讲设计思想,至于具体的技术细节,以后有机会会慢慢分享。越是简单的成品越是需要足够的积累。

然而,现在的我再重新评估UI组件的实现,还是有一些遗憾的,主要遗憾在于,HTML层→数据层→展现层这三层概念实现的时候并没有理得很清楚。目前,HTML层和展现层没有任何问题,但是,数据层,并没有完整贯穿整个UI组件体系,导致,本UI组件体系不能很好地吸引对JSON数据有着偏执爱好的开发,以及应付潜在的极端需求。

不过,不要担心,明年,也就是16年,我会对组件设计进一步增强,首先,不考虑IE7浏览器,于是可以做的事情就更多了;其次,清晰的数据层作为中间层的代码重构等。

以上,希望本文的内容能够对大家有一点启示。

(本篇完)

分享到:1
×


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

  1. molaga.z说道:

    关于组件化,除了原生html,还有shadow dom不知道可行性高不高

    关注博主挺久,前端的东西收获不少,感谢
    PS:一只做画面比后端还多的java小码农

  2. 看看说道:

    空军建军节

  3. wenrun说道:

    checkbox在ie7下面使用[defaultChecked]进行处理时候,input的状态改变了,label的显示效果却没有变化,是要怎么进行重绘还是要如何处理?

  4. luckyqiao说道:

    样式乱了,求修复

  5. indra说道:

    样式乱了。。。求修复

  6. sddfsf说道:

    。。开源了没?

  7. xyzxyz说道:

    大神,有个问题请教,原生datepicker快速点击下一月按钮,那个动画怎么实现的呢,或者按住不放的动画效果,是用canvas吗还是svg还是requestanimationFrame

  8. xxxx说道:

    示例有问题啊,好像是样式不对

  9. 阿文说道:

    啥时开源呢 我自己网站后台想用个

  10. ManfredHu说道:

    类似polyfill的UI fix.我没理解错吧。
    应该是一种趋势,统一浏览器原生丑丑的UI

  11. qqxufo说道:

    看起来不错呀,可以偷学代码么= =

  12. steven说道:

    请问目前开源了么,还有就是input date 在微信端会先弹出原生的,其次又弹出第三方的组件选择器。

  13. newbee说道:

    这个东西和pintucss是不是差不多呢,不过事件都是用的原生的。如果用这个的话,虽然不用背GregorianCalendar这种,但是是不是还要大量的背他的class,比如:ui_button,ui_button_blue,这种???
    求解答~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  14. 刘东奇说道:

    基于原生html开发页面,这个思路真是太好了。不知道现在有没有博主说的这种只需要少量引用和初始化就能让原生html美化的产品可用

  15. Daisy说道:

    如果能推动HTML原生控件往全部支持个性化定制的方向发展,自然是极好的!

  16. 赵某人说道:

    以后腾讯浏览器弄个网页渲染按钮得了.太黑科技了.

  17. 小李说道:

    颇受启发

  18. hhgnsc说道:

    手机号没盖严实呀!好像还是能看清

  19. lianpen说道:

    哥哥,脚本干毛加个密呀 如何阅读呀啊啊啊

  20. sandman说道:

    demo页面的代码可以下载用吗?

  21. sandman说道:

    这个思路很赞!学习大牛!

  22. 陈小轩说道:

    赞赞赞,以前写代码会先把业务逻辑写好,在UI,这个思路更明显,彻底,赞赞赞

  23. 北京soho说道:

    您引入的ui里面的js和css是你自己写的吗?

  24. reyhappen说道:

    鑫哥,搞个表格操作的插件玩玩哪(实现单元格合并,拆分,在合并的基础上的插入新行、新列)

  25. liuqingchi说道:

    dojo 早就做到了,是不是多此一举呢?

  26. dr说道:

    学习了

  27. 松鼠闹IT说道:

    越是简单的成品越是需要足够的积累。

    说的相当不错。我一直都在寻找如何能简化美化UI的方式

  28. 懒人说道:

    适合jq,不适用mvvm