1. 現状
1. フロントエンド開発の現状
近年のフロントエンドの発展は誰の目にも明らかです。実用化されている標準に従えば整理してみると、Node.jsやMV*ライブラリでのフロントエンドとバックエンドの分離など、基本的にはバックエンドJS開発レベルであることがわかります。 、React.js、各種パッケージ管理ツール、フロントエンド統合ソリューションなど。
今後、Shadow DOM、Web コンポーネントの仕様と標準も登場し、誰もがその方向性と将来性を垣間見ることができますが、互換性の問題 (以下の表を参照) や、Web コンポーネントの強度の欠如により、優れたチーム リーダーシップは、実際のプロジェクトではほとんど見られないものです。
webcomponents.js などのポリフィルがあっても、完全にサポートされているのは IE11+ のみです。
HTML 側の作業を開始する前に、Web コンポーネントが世界を席巻するまで待ったほうがよいでしょうか?これまでの HTML5 開発はすべて無駄になったのでしょうか?古いブラウザのせいで PC 側で停止しているのでしょうか?
2. UI コンポーネントの現状
成熟したチームは、さまざまなプロジェクトが来たときに落ち着いて対応できるように、独自のコンポーネント ライブラリを持っています。
これに冷静に対処できるようにするには、企業レベルで思慮深く、大規模なプロジェクトやさまざまな複雑なシナリオに対処でき、コンポーネントの再利用性を最大限に活用できる必要があります。多くの場合、最終的にはコンポーネントが重くなり、ロジックがより複雑になり、API の数が増加します。 Kissy 5.0 の DatePicker コンポーネントの使用法を見てみるのもよいでしょう:
関数だけを見てみると、無効になっている日付は非常に強力です。カスタマイズも自由自在で、各操作バーも簡単に定義できるまさにエンタープライズレベルのWebコンポーネントで、さまざまな複雑なシナリオに対応できそうです。
しかし、私の意見では、多くの問題があります。
1. 落ち着いて考えてください。私たちが経験したプロジェクトのほとんどは、大規模で重いエンタープライズレベルの製品を使用する必要があるのでしょうか?これは、プレゼンテーション指向の Web サイトを持っているが、見栄えを良くするために AngularJS MVVM を使用しているようなものです。足の指を切断するのはあなたにとって適切であり、ドゥンユンはあなたを愚かにします。
2. さまざまなシナリオに適応できるように見えますが、最新の Web テクノロジーは急速に発展しており、UI レイヤーは日々変化しています。あなたのコンポーネントがこれらの変化に対応できるかどうか。最終的にはコンポーネントのサポートが追いつかず、デザイナーのアイデアの一部が却下されるのではないかと心配しています。本末転倒!
3. GregorianCalendar や GregorianCalendarFormat などのメソッドまたはオブジェクトがコード内に表示されます。これが何であるか知っている人はいますか?彼が何に使われるか知っていますか?学習コスト~~
4. render、showWeekNumber、showClear、showToday、disabledDate などの API 名をどこかで見たことがあると思いますか?
「どこかで見たような?」
「幽霊みたいだ、見たことない!」
5.彼らの目、これらの API 名が何であるかをまだ覚えていますか? 1週間経ったとしますが、まだ覚えていますか? API ドキュメントを読みますか?使用コスト~
6. プロジェクトが開始され、コンポーネントを担当するフロントエンドとビジネスを担当するフロントエンドが突然連携して作業を開始すると想像してください。コンポーネントのフロントエンドを担当するスタッフが突然陣痛を起こし、出産に伴い行かなければなりません。この時、ビジネスを担うフロントエンドは何をすべきでしょうか?馬京濤は心の中でこう思っているだろうか:「時間選択コンポーネントはまだ完成していない。ここでの日付のインタラクションはコンポーネントに依存している。これは私に責任を委ねているのではないか!」二人の邪魔になった!結果は 2 つあり、1 つは自分で行うか、もう 1 つはこの作業が中断されるというものです。 コンポーネントとビジネスが結びついており、それがコラボレーションを促進しないことに気づきましたか。たとえば、上記のスクリーンショット コードの picker.on('select', function(e) {}); コンポーネントが適切に実行されていない場合、まったく使用できません。最初に自分で行って、後で変更するのですが、これは非常に面倒です。
2. 探求
こうした満足のいかない現状だからこそ、少なくとも大きな前進ではなく、何か変化を起こす方法はないかと考えてきました。別の方法を指摘できます。
タイムピッカーを例に挙げてみましょう。HTML5 はネイティブ UI コンポーネントを提供するのでしょうか?
<input type="date">
日付タイプの入力ボックス。当然、時間を選択できます。
min/max 属性を使用して選択できる時間範囲を制限し、value を使用して現在の選択日付を決定できます。つまり、本来の機能という観点から見ると、ネイティブ日時選択でほとんどのビジネスニーズを満たすことができるのです。
標準や業界標準に準拠したこれらの HTML 機能が、実際のプロジェクトに直接適用できれば素晴らしいですね。
しかし、問題は、ブラウザのネイティブ インターフェイスがサイトのデザイン スタイルと互換性がないことが多く、はっきり言って、デザイナーがそれを醜いと感じており、クリアなどの特定の機能を自由に定義できないことです。
もう 1 つの非常に現実的な問題は、IE11 を含む IE ブラウザには type="date" コンポーネントの動作がありません。この最後のヒットは私の心に直接刺さります。
どうすればいいですか?
この時点でそれを整理した方がよいでしょう:
<input type="date" min="2016-01-01" max="2016-12-31" value="2016-02-14">
type/min/max/value这些原生标准的HTML属性并没有问题,有问题的只是点击出现的那个长相简陋的选择浮层。所谓对症下药,哪个有问题就搞哪个,我们只要想办法把丑陋的浮层搞漂亮就可以了。
考虑到兼容性,我们其实可以和传统的时间选择器组件一样,对浮层内容进行自定义,注意,我们仅自定义浮层,HTML还是原始的。
我们构建一个名叫DateTime的实例方法,理想状况下,我们只要绑定初始化一下,类似这样:
new DateTime($("[type=date]");
然后duang,时间选择器浮层直接美化成设计师需要的模样,那该多完美啊!
梦想总是有的,万一实现了呢?
既然使用自定义的浮层,那就需要干掉浏览器原生的浮层,怎么弄呢?我们可以让input框readonly只读,这样,就不会出现原始的输入框了。
那input框内置的三角(需要隐藏)和斜杠(需要使用短横)该怎么办呢? 这部分是支持自定义的,类似:
::-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下的时间输入框改造成我们想要的样子了,而IE等不支持date输入框的浏览器,保持原来的样子就可以。
于是乎,通过CSS和JS的配合,我们就可以实现基于原生HTML5标准的时间选择器了。
“稍等,怎么就实现了?”有人可能会有这样的疑问。
下面这段是我年轻时候使用过的一套组件库的初始化示意:
new DatePicker($("#date"), { type: "date", initDate: .., beginDate: .., endDate: .., onSelected: $.noop});
对比:
<input type="date" min="2016-01-01" max="2016-12-31" value="2016-02-14">
我们是不是可以找到之间的关系?没错,这位同学好生眼力,HTML中的type属性对应JS中的type API, value属性值对应initDate值, min/max分别对应beginDate/endDate。其实内部实现跟传统的组件没什么差别。
那onSelected呢?onSelected是个回调方法,解读下就是当选择日期之后,干嘛干嘛。其实我们原生的input框有类似的事件,什么呢?change事件。既然,我们这里使用的是原生的HTML输入框,那我们就可以使用其原生的change事件。所以,什么onSelected回调,完全不需要。我们只要在组件内部,当赋值的同时trigger下原生的change事件。
于是乎,我们就得到了一个HTML是原生,API也是原生,事件也是原生,UI自定义的时间选择控件。真真切切将HTML5应用到了实际项目中,同时,就算是是10年前的IE6也是可以兼容。
完美!
然而,一定会有小伙伴提出质疑,你这个功能也太局限了吧,如果遇到特殊需求,例如,所有的周末都不能选择,你怎么整?
OK,此时就需要“面向设计的半封装web组件开发”的这篇文章出马了?
之所以有人会提出上面的质疑,还是按照了传统组件的思维方式去思考。没错,确实有些项目的时间组件要求周末不能选择。但是,你现在做的这个项目,有这个需求吗?你好好想想。
CSS3现在发展越来越成熟,UI层的变化越来越迅速和不可预知,这种趋势,要求我们的UI组件要轻快,灵活,随时可以根据上层变化做调整。而那种妄图考虑各种场景,代码又大又冗余的组件开发方式已经越来越不适应未来的潮流了。
如果你真的遇到“周末都不能选择”的需求,我告诉你怎么办?自定义一个名为”date-no-weekend“的type类型,内部的JS代码当然该重用的重用,该模块化的模块化:
<input type="date-no-weekend">
还是觉得难以接受,仔细品味后面这句话:组件要面向设计,落地项目,追求品质。
好,我们现在实现了基于HTML5时间选择组件落地实践生产,加以推广,势必对HTML5标准在国内的学习与普及带来帮助。
然而,就单单一个组件,势单力薄,怕是针落大海,激不起一点水花,其他些组件是不是也可以找这种面向HTML的思路去开发呢?
有!
告诉大家,QQ公众平台的UI组件体系贯穿始终,就是基于面向HTML标准开发的思想实现,同时借助面向设计的开发思想,让组件极致体验,同时轻便快捷,风一吹就可以飞到天上去。
三、实践
QQ公众平台的UI组件实现,和传统实现是完全不同的设计思想。从JS层进一步往下沉淀了一个层次,基于原生的HTML实现。
多说无益,眼见为实(狠击下面)。
demo-点击这里-demo
点击上面的demo, 进入一个平凡的静态页面,引入眼帘的是一个普通的表单,里面的UI都是系统默认的,HTML功能也是原生的。
例如:
1.title提示<.li>
2.选择日期
3.点击提交的表单验证
UI虽然原始,但是功能却是很健全的。
例如:
1.男女款式、城市以及运费险对价格的影响
2.表单提交事件
下面,见证奇迹的时刻到了,点击demo页面(下图所示)的按钮进行QQ公众平台UI组件资源的加载和初始化:
结果,一瞬间,上面原始粗糙的界面一下子变成了这样子:
妥妥的丑小鸭变成了白天鹅,包括之前原生的HTML功能。
例如:
1.title提示
2.选择日期
3.点击提交的表单验证
而,最最重要,和 最最神奇的事情是 :我们仅仅是引入了QQ公众平台的UI组件,对,仅仅是引入和一点初始化,没有动之前一点点一丝丝的业务JS. 但是,之前的各种交互功能,却完全不受影响,反而体验更上两层楼!
请看下面的gif截图演示:
真是一场意外之旅,发现没,面向HTML开发,实际上不是简单推动了HTML5等现代web技术落地实践,对我们的开发流程等也带来了巨大帮助——UI组件可以和业务JavaScript完全分离,可以实现无缝对接。就是因为整个组件体系基于原生HTML开发的设计理念,让UI组件回归了其本质或者说本职作用——UI.
四、优势
下面总结下面向HTML的UI组件开发的优势。
1. HTML/CSS侧的现代产物落地实践
基于HTML标准来开发我们的UI组件,通过技术跨越各种兼容问题,使得我们前端技术在HTML层也乘上了现代web技术的快车,标准的HTML5规范和属性提前很多年在广受众的传统PC页面呈现,我觉得是非常有意义的一件事情。
2. 规避了传统组件的很多问题
1.更强的语义化,可访问性,SEO等;
2.学习和使用成本低;
3.专注HTML控件本身,而不是组件;
4.可以一次性全局处理;
①. 语义化,可访问性
毕竟是基于原生HTML来开发的,这一块必定杠杠的。
例如,时间选择:
<input type="date">
显然语义要比下面的text类型要好:
<input type="text">
又如基于checkbox/radio类型的input框模拟的单复选框自然要比传统div元素模拟的无论是语义、设备可访问性都要高很多。
②. 更低的学习和使用成本
不会出现类似GregorianCalendar, GregorianCalendarFormat一眼不知道干嘛的对象和方法。
不需要记住类似showWeekNumber, showClear, showToday, disabledDate这样千差万别的JS API名称,记住标准的HTML5属性即可,只要记住一次,终身受用,放心,不会变的,HTML5文案已经定稿了。
而学习成本低对于跨团队合作非常有帮助。你说kissy上手快,还是只需要写写标准HTML就OK上手快!
其他团队同学乐于使用你的东西,介入快,实现效果好,大家都开心。反之,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 実装は特定のビジネス ページに関連するため、Select.init() に示すようにプロジェクトの common.js でグローバルに初期化されている限り、特定のビジネス JS ファイル (ほとんどの場合) UI コンポーネントに関連する JS コードは必要ありません。
UI 層の JS コードとビジネス層の JS コードを分離し、さらなる「フロントエンド分離」とデカップリングを実現します。従来のコンポーネントよりも、将来のメンテナンスやアップグレードが簡単です。
5. 結果
HTML 指向の UI コンポーネント開発は、QQ パブリック プラットフォーム UI コンポーネント システム全体で実行されます。上記には登場していない範囲選択、カスタムスクロール効果などを含みます。
実際の結果から判断すると、フロントエンドの同僚はこのセット (機能層) を賞賛しており、デザインセンターのリーダーは、このセットを他のチーム (エクスペリエンス層) にプッシュできることを望んでいます。
ご興味がございましたら、QQ パブリック プラットフォームに参加して体験してみてはいかがでしょうか。フィードバックや貴重なご意見をお待ちしております。
6. 結論
type="date" の入力ボックスは、実際には、インポートできるモジュールです。複雑なインターフェイス コンポーネント効果 (シャドウ DOM) が表示され、API は HTML のネイティブ属性です。
QQ パブリック プラットフォームの UI コンポーネントは Web コンポーネントからどのくらい離れていますか?従来の Web コンポーネント間の距離が長安街 1 つである場合、QQ パブリック プラットフォーム UI コンポーネントは長安街 0.5 つだけ離れています。
HTML と API はネイティブ Web コンポーネント モードを利用します。非 Web コンポーネント モードは単なるカスタム フローティング レイヤーですが、設計上のアイデアやアイデアは Web コンポーネント モードに移行しています。
言い換えると、1 つのステップで Web コンポーネントに直接到達することはできませんが、HTML の開発を使用して、いくつかの戦略と設計を通じて UI コンポーネントに変更を加えることができます。 Web コンポーネントで大きな一歩を踏み出しましょう。