当前位置: 首页 > 科技观察

顺势而为,HTML开发与UI组件设计演进

时间:2023-03-21 12:28:56 科技观察

阅读本文前,推荐阅读之前的一篇文章:《面向设计的半封装Web组件开发》,轻松理解文章的一些困惑.一、现状1、前端发展现状前端这几年的发展是有目共睹的。但是,如果你梳理一下已经付诸实践的标准,你会发现,基本都是后期的JS开发水平,比如Node.js。.js下的前后端分离,MV*库,React.js,各种包管理工具和前端集成方案等。往前看,虽然ShadowDOM,WebComponents规范和标准也出现了,为大家指明了方向和未来,但由于兼容性问题(见下表),或者缺乏优秀团队的强有力领导,我们在实际项目中很少见到。即使使用webcomponents.js等polyfill,也只有IE11+完全支持。是不是等到WebComponents一统天下,才开始做HTML端的工作?这么多年的HTML5开发就这么白费了吗?我们是否因为一些过时的浏览器而停留在PC端?2、UI组件现状成熟的团队都有自己的一套组件库,这样当各种项目来的时候,能够从容应对。为了能够从容应对,我们必须有思想,有企业级的,能够应对大型项目,各种复杂的场景,充分发挥组件的复用性。往往到最后,组件会越来越重,逻辑会越来越复杂,API的数量也会越来越多。我们不妨看看kissy5.0的DatePicker组件的使用图:如果单看功能,确实很强大。禁用日期可任意自定义,轻松定义各操作栏是否显示。它确实是一个企业级的web组件。看起来它可以适应各种复杂的场景。但是,在我看来,问题很多。静下心来想一想,我们经历过的大部分项目都是不复杂的吗?我们有必要使用企业级的大而重的产品吗?这就像你有一个面向显示的网站,但是使用AngularJSMVVM让它变得更大。截趾宜,顿云愚。看似能够适应各种场景,但是目前现代web技术发展迅速,UI层日新月异。您确定您的组件可以跟上这些变化吗?恐怕最终会演变成组件支持跟不上,设计师的一些想法被否决了。本末倒置!代码中有GregorianCalendar、GregorianCalendarFormat等方法或对象。你知道这到底是什么吗?你知道他用来做什么吗?学习成本~~render,showWeekNumber,showClear,showToday,disabledDate等API名称你是不是见过?“我好像在哪里见过?”“好像是鬼,我没见过!”现在大家闭上眼睛,还记得这些API名称是什么吗?假设一周后,你还记得吗?您要查看API文档吗?使用成本~想象这样一个场景,项目启动,负责组件的前端和负责业务的前端开始一起工作,但是突然,负责组件前端的老婆要给突然出生,必须陪产。这个时候负责业务的前端应该怎么办呢?马景涛的脑子里会不会是这样:“时间选择组件还没做完,这里的日期交互就靠组件了,这不是甩锅让我挑吗!?”可见两人的发展受到了阻碍!结果有两种,一种是自己动手,一种是暂停工作。于是大家发现,组件和业务是耦合在一起的,不利于协作。例如,picker.on('select',function(e){});上面截图代码中,如果组件没有做好,根本无法使用!或者先自己做,以后再改,很烦人。2.探索正是因为目前的现状不如人意,所以我一直在思考有没有什么办法可以做出改变。不一定意味着一步大跃进,但至少可以指明另一条路。我们还是以时间选择器为例。想一想,HTML5是不是给我们带来了原生的UI组件?对对对,大家应该都知道:日期类型的输入框,自然可以选择时间。我们可以使用min/max属性来限制可以选择的时间范围,使用值来确定当前选择的日期。也就是说,从原有的功能来看,原生的日期时间选择可以满足绝大部分的业务需求。如果这些符合标准、符合行业标准的HTML特性可以直接应用到实际项目中就好了!然而,问题在于浏览器的原生界面往往与我们网站的设计风格有些不一致。说白了就是设计者觉得丑,不能自由定义某些功能,比如清除。另一个非常现实的问题是兼容性。包括IE11在内的IE浏览器都没有type="date"组件行为,所以这个patch直接伤了我的心。怎么做?这个时候我们不妨梳理一下:type/min/max/看重这些native标准的HTML属性是没有问题的,唯一的问题是点击后出现的那个看起来很简单的选择浮层。所谓对症下药,就是对症下药。我们只需要想办法把丑陋的浮层变漂亮。考虑到兼容性,我们其实可以像传统的时间选择器组件一样自定义浮层的内容。注意我们只自定义了浮层,html还是原来的样子。我们构建一个名为DateTime的实例方法。理想情况下,我们只需要绑定和初始化它,就像这样:newDateTime($("[type=date]");然后duang,时间选择器的浮层直接美化成设计师想要的样子,多完美啊!梦想总是有的,万一实现了呢?既然用了自定义浮层,就需要去掉浏览器自带的浮层,怎么办呢?我们可以让输入框readonly只读,所以原来的输入框不会出现。输入框内置的三角形(需要隐藏)和斜线(需要用短横线)怎么办?这部分支持自定义,类似::-webkit-clear-button,::-webkit-inner-spin-button,::-webkit-calendar-picker-indicator{display:none;}[type="date"]::-webkit-datetime-edit-text{color:transparent;}[type="date"]::-webkit-datetime-edit-text::before{content:'-';position:absolute;}::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute-field,::-webkit-datetime-edit-ampm-field{background:none;}你可以下载webkit的的时间输入框。所以,通过CSS和JS的配合,我们可以实现一个基于原生HTML5标准的时间选择器。“等一下,怎么实现的?”可能有人会有这样的疑问。下面这段是我小时候用的一组组件库的初始化:newDatePicker($("#date"),{type:"date",initDate:..,beginDate:..,endDate:..,onSelected:$.noop});对比:我们能找到它的关系吗?没错,这位同学眼力不错。HTML中的type属性对应JS中的typeAPI,value属性值对应initDate值,min/max分别对应beginDate/endDate。其实内部实现和传统组件没什么区别。onSelected呢?onSelected是一个回调方法。解释是选择日期后要做什么。其实我们原生的输入框也有类似的事件,什么?改变事件。由于我们在这里使用的是原生HTML输入框,因此我们可以使用其原生的change事件。所以,什么onSelected回调是完全没有必要的。我们只需要在组件内部赋值的时候触发原来的change事件即可。于是乎,我们得到了一个HTML是原生的,API也是原生的,事件也是原生的,UI是自定义的时间选择控件。真正把HTML5应用到实际项目中,同时,连10年前的IE6都兼容。完美的!但是,肯定有朋友会质疑,你的功能太局限了。如果遇到特殊需求,比如不能选择所有周末,怎么解决?OK,这个时候需要这篇《面向设计的半封装Web组件开发》?之所以有人提出以上质疑,是因为他们还是按照传统组件的思维方式来思考。是的,确实有些项目的时间成分要求不能选择周末。但是,你现在做的项目有这个需求吗?你考虑一下。现在CSS3越来越成熟,UI层的变化也越来越快,变幻莫测。这种趋势要求我们的UI组件要轻巧、灵活,能够根据上层的变化随时调整。而那种试图考虑各种场景、代码量大冗余的组件化开发方式,越来越不适合未来的趋势。如果你真的遇到“周末选不出来”的需求,我告诉你怎么办?自定义一个名为“date-no-weekend”的类型。当然,内部的JS代码要复用。模块化:还是觉得不能接受,仔细品味下面这句话:组件要面向设计,实施项目,追求品质。那么,我们现在已经实现了基于HTML5的时间选择组件的实用化制作,它们的推广,必将有助于HTML5标准在国内的学习和普及。然而,仅仅一个部件就很脆弱,即使掉进海里也不会溅起水花。这种面向HTML的想法是否也可以开发其他组件?有!跟大家说说,QQ公众平台的UI组件体系贯穿始终,是基于HTML规范化开发的思想。同时,借助面向设计的开发思路,让组件拥有极致体验。同时,它们又轻又快,一有风就可以飞上天。3、实践QQ公众平台UI组件实现,与传统实现完全不同的设计思路。基于本机HTML实现,从JS层沉积了另一层。多说无用,眼见为实(下打)。demo-点这里-demo点击上面的demo,进入一个普通的静态页面,看到的是一个普通的表单。里面的UI是系统默认的,HTML功能也是原生的。比如:标题提示,选择日期,点击提交表单验证,UI很原始,但是功能很完善。例如:男女款式、城市、运费保险对价格的影响表单提交事件下面,见证奇迹的时刻到了。点击demo页面的按钮(如下图),加载并初始化QQ公众平台的UI组件资源:结果,一瞬间,上面原本粗糙的界面一下子变成了这个样子:妥妥的丑小鸭变成了白天鹅,包括以前的原生HTML功能。例如:标题提示选择日期,点击提交表单进行验证。最重要也是最神奇的是:我们只介绍了QQ公众平台的UI组件,没错,就是介绍和一点初始化,之前什么都没有。一点业务JS。不过之前的各种交互功能丝毫不受影响,反而体验更好!请看下面的gif截图演示:这是一次意想不到的旅程,你有没有发现,面向HTML的开发其实并不仅仅是简单地推动了HTML5等现代Web技术的实施,还为我们的开发过程带来了极大的帮助——UI组件可以与业务JavaScript完全分离,实现无缝连接。是因为整个组件系统都是基于原生HTML开发的设计理念,让UI组件回归到它们的本质或者说是它们自身的功能——UI。4.优点下面总结了面向HTML的UI组件开发的优点。1.现代产品在HTML/CSS端的实现,我们的UI组件是基于HTML标准开发的,通过技术克服各种兼容性问题,让我们的前端技术也能搭上现代Web技术的快车HTML层,以及标准的HTML5规范,我觉得提前很多年呈现广大受众传统PC页面上的属性和属性,是非常有意义的。2、避免了传统组件的诸多问题;更强的语义、可访问性、搜索引擎优化等;学习和使用成本低;关注HTML控件本身,而不是组件;一次可以全局处理;①.语义化,可访问性毕竟是基于原生HTML开发的,这一点是必须要撬动的。比如时间选择:显然语义比下面的文本类型要好:再比如基于checkbox/radio类型输入框模拟的单选框自然比传统的p元素模拟的语义和设备可访问性要高得多。②.更低的学习和使用成本一眼看去不会有类似GregorianCalendar和GregorianCalendarFormat的对象和方法。showWeekNumber、showClear、showToday和disabledDate等JSAPI名称无需记住,但您只需记住标准的HTML5属性即可。只需记住一次,终生使用。别担心,它不会改变的。HTML5文案已定稿。而且学习成本低,对跨团队合作很有帮助。你说kissy学起来很快,或者你只需??要写标准的HTML就可以快速上手!其他组员愿意用你的东西,他们插手很快,效果也不错,大家都很高兴。反之API千差万别,每次使用都要翻看文档,肯定会影响合作。但是在实践中,有一个学习成本我没有考虑过,就是改变思维方式的学习成本。其实只要是面向元素的HTML元素开发就够了,但是如果遇到小伙伴,还是要按照老思路,在生成的UI组件元素上做文章。③.关注HTML控件本身,而不是组件。比如日期选择器,当日期被修改了,我们怎么办,直接:$("input").change(function(){});想要修改日期范围,直接:$("input").attr({"min":"2015-12-27","max":"2016-12-27"});UI组件将自动同步。没有任何组件相关的JS代码,也没有任何取巧。没有所谓的高楼大厦,都是非常简单和基本的HTML操作。这样的开发是不是省心到新手也能上手?因此,当多个团队协同开发时,前端开发的进度不会因为UI组件的开发而受到影响。它面向HTML,可以专注于自己的业务发展。负责组件开发的前端正在休陪产假。负责业务的前端直接根据标准的HTML控件元素实现自己的业务逻辑,直接使用原生的事件和方法进行任何回调。等负责组件开发的前端回来,哪怕耽误一周,只要组件完成,公共JS初始化,业务JS不做任何修改,无缝对接.于是乎,实现了一件听起来很棒的事情:前端分离。这也为整个开发流程和效率带来了巨大的提升。不仅如此,厂里有很多开发人员,负责内部项目,会写JS,擅长实现业务功能,但UI是软肋。OK,至此,我们面向HTML的UI组件系统就是它的救星了吧?直接引入CSS和JS,简单初始化全局(可能是一些简单的微调)。结果,页面立马变高了,是不是很有用!④.传统实现可以一次全局处理,每个具体业务的脚本都需要参与UI组件具体的API参数设置。对于面向HTML的实现,API落地和具体的业务页面,所以,只要在common中全局初始化即可。无需出现UI组件相关的JS代码。将UI层的JS代码与业务层的JS代码分离,实现进一步的“前端分离”和解耦。与传统组件相比,更易于日后维护和升级。五、结果面向HTML的UI组件开发贯穿于整个QQ公众平台UI组件体系。包括上面没有出现的范围选择、自定义滚动效果等。从实践的结果来看,前端同事都对它赞不绝口(功能层),我们设计中心的领导希望这套可以推到其他团队(体验层)。感兴趣的话,不妨尽快加入QQ公众平台,也来体验一下吧。欢迎反馈和宝贵意见。6.结束语一个type="date"的输入框其实就是一个终极的WebComponents,一个简短的是一个可以导入的模块,然后就可以出现一个复杂的界面组件效果(shadowDOM),API就可以了是HTML的本机属性。QQ公众平台UI组件离WebComponents还有多远?如果说传统web组件的距离是长安街1条,那么QQ公众平台UI组件的距离只有0.5长安街。HTML和API使用原生的WebComponents模式,非WebComponents模式只是自定义浮层,但设计思路和思路都在向WebComponents模式靠拢。也就是说,虽然不可能直接一步到WebComponents,但是我们可以借助HTML的发展,通过一些策略和设计,对UI组件进行一些改动,从而可以向WebComponents迈出一大步。本文重点介绍设计思路。至于具体的技术细节,有机会我会慢慢分享。可以说的点很多很多。成品越简单,越需要积累。以上,希望本文的内容能给大家一些启发。