近期因为在筹划阐述前端开发工作中的各种复杂场景,并将其中可能用得上的思想讲明白,比如:模块化开发、自动化构建、工程化等,在每一个方向上,都是用于解决我们在项目开发过程中,所遇到的问题,以及提升工作效率的考虑,以此提升开发工作的趣味性。
Not just do it, but enjoy it.
以此为砖,用以引玉。
正好近期也接受到了一个项目——《大富翁》小游戏,对于该项目的初步分析,并结合到我的想法,可能适合作为“复杂场景”的一个引子,我希望可以以该项目的实施及思考过程,来实例化的描述一下整体的一个解决思路。暂且叫其为:思(什)考(么)模(鬼)型。
1 项目效果演示
先上个图,大致看一下最后的效果,没有将所有出现的情况全部展示。
2 为什么可以说复杂
2.1 整体的游戏执行流程
这张图中可以看出游戏在执行过程中的逻辑流程,其中大部分都会涉及到前端交互的响应变化,因此其中前端交互流程复杂。
2.2 界面中元素众多
其中涉及到场景的元素非常多,各元素之间的排列,以及形状尺寸各不相同。这种场景下,给界面的兼容适配带来了难度。
2.3 界面元素涉及状态切换&动画执行
其中小狐狸的状态涉及到3种:静态、向左走动、向右走动。
掷出骰子后,界面其他元素的交互触发需要锁定,并且,各元素的执行有明确的先后顺序,需要类似时间轴的概念来统一协调管理。
3 需要如何考虑
3.1 样式部分
界面非常的个性化,导致界面的样式布局上,我们很多场景需要使用背景图片来进行处理,另外,加上在不同尺寸终端上展示适配需求,更加使得整体问题变得复杂难解。
需要解决的点:
- 各终端不同尺寸适配
- 大部分为不规则的背景元素,CSS的编写过程,元素尺寸的快速管理
- 页面动画过程中,元素位置的定位问题
- 页面的样式有相近部分,如:弹窗,如何达到封装共用
各终端不同尺寸适配
目前市面上,可以统计到的不同终端尺寸,没有上百,也有几十,因此,在H5开发过程中,样式开发如何适配不同尺寸的显示屏,成为了我们这块所必须面对的首要问题。
1. 媒体查询(media query)
所涉及到的情况实在是太多,这导致,不同尺寸区间的细分会非常的复杂,而且,每一个尺寸区间下的都需要或多或少的人工干预调整,这在工作量上已经是无法实现的,还没考虑其中所涉及到的测试检验等等一系列的问题,所以,该方法基本可以排除。
2. 百分比
在CSS开发过程中,我们可以尝试使用百分比的方式来定位各不同元素在场景中的位置,以期在不同尺寸下达到同等比例的缩放。
这种思路很好,但技术选择方向上,百分比带来了很多的不可测量性,简单的来说,你拿到一个设计稿,其中一个元素相对于整体场景,或是另一个元素,具体较为精确的距离是百分之多少,这个没办法很直接的测量,因此,这种情况下,很多是由前端人员,依“手感”来细微的调整元素的位置,一个百分点,甚至零点几个百分点的来调整,而且调整完成后,由于各元素之间细微的误差积累,等放入另一个尺寸下时,你可能会发现,各要素的偏差很大,已经出现了我们常遇到的不兼容。
总结来说,就是工作量巨大,而且不兼容。
3. REM
REM是我实践过程中,认为的终极解决方案。当然,这其中我们要感谢很多在这方面提供解决方案的开源付出,如:lib-flexible,这就是其中的一个,具体的设计思路,可以详细去查阅本方向上的资料,这里不再展开。
附加的,会产生出另一个问题,REM,这个单位毕竟不是PX,仍需要换算。这里也同样有相应的解决方案,我们可以借用自动化的构建工具,实现rem和px之间的自动转换,px2rem,可以与gulp或grunt等构建工具集成,实现自动转换。
自动解析后:
元素尺寸的快速管理
在场景中,出现了很多个性化的元素,其中的实现,很多是以背景图片来实现,之所以选择这种方式,是借助了 cssgrace 中的一个特性:可以通过 image-width、image-height 两个动态属性,来自动的获取到图片的宽高尺寸。
编译解析后
这样不但可以将图片尺寸的管理交托给自动化的构建脚本,提升CSS开发中的效率,并且可以明显降低设计稿发生修改所带来的代码改动成本。
如若过程中,设计稿发生修改,某一个元素的尺寸发生了稍微的改动,这种方案下,我们只需要重新更新切图,再执行一次自动构建任务,中间的代码不需要任何的改动,高效而准确!
元素定位
得益于 REM 方案带来的方便,我们只需要解决一种尺寸稿件下的准确定位,再附加上自动构建任务中,将 PX 自动转换为 REM 单位,其中的源码是 PX 单位,而构建出的成品代码是 REM 单位,这样实现了代码对于开发人员的可理解,以及代码的各尺寸终端的可兼容,两者兼顾。定位问题,在本次的开发过程中,直接采用的是针对于 750px 尺寸下的精准定位。
如图中所示,小狐狸的路径节点相对于 750px 下的定位,全可以一次性的在稿件中标注定位,并写好相应的class,自动构建类的脚本,会自动将相关的单位进行解析转换。
样式封装共用
相信大家,在前面的几组对比图中,就可以发现,开发中有用到 LESS 来结构化的开发样式布局。类似于 LESS 的CSS预处理插件还有很多,我们可以自己查询相关的资料,这里希望能过这种预处理的插件,给我们带来了 CSS 模块、函数式的编辑体验,这样可以大增强样式表的结构可读性,同时也可以很好的提升样式表产出的规范,以及逻辑准确性。重要的是,其中可以很大程度的减少我们相似规则,或是嵌套规则之间的代码量。
在本段示例规则中,弹窗的整体内容进行了一次性编写,其中各不同弹窗中的 .bts 和 .bt 可以共用,并且结合共用规则的封装,每一个不同弹窗,都与规则 .pop_cont 组合,其中具有相同表现的弹窗(.p_c_free & .p_c_props)直接共用规则。其中各规则之间的嵌套层级非常明确清晰,对于规则的阅读以及整体统一管理非常方便,从而屏蔽了普通 CSS 在编写过程中的,可能比较分散,规则识别路径原则不一致,给编写和维护带来困惑的弊端。
总之(总而言之,言而总之)
对于样式的处理,我们借助了几个不同的方案,进行了一种组合搭配,实现了对于移动端尺寸适配,以及样式结构化、模块化的开发体验。
3.2 HTML部分
HTML部分的提出,对于本项目中的场景,可能不是十分的贴切,这里最为主要的点是需要解析 HTML 模块化的问题,引出这个需求的考虑有以下几点:
- 页面结构更为清晰
- 模块之间可以达成共用
- IDE 等相关软件的响应速度影响
- 减少重复代码在不同文件中的重复出现
这是本次项目中的主要 HTML 页面代码结构,其中有出现 include 的语法,而这种就是对于分模块化开发的一种实践方式,集成的是 nunjucks ,它的引入给 HTML 带来了很多模块化方向的能力提升,具体的特性,可以详细阅读其手册。
回到项目中, head_wap.html 这是文件所需要引入的相关样式及JS库的部分,这是我们项目中经常在各个页面重复出现的部分,因此,这里对该部分进行了一次提取,在不同页面,只需要一名 include 就可以解决这种重复问题,更好的达到统一管理的需求。
而对于另一个实操过程的痛点,即,我们在开发过程中,一般会选用相关的代码编辑器,这里是 webstorm IDE,而正是因为这种类型工具的使用过程中,工具本身对于代码文件需要内建很多的索引,用以提供相关功能,而这个内建索引及维护过程中,需要消耗很大的系统性能,这种情况在大文件编辑时尤为明显,因此,为了在这个方向提升我们的开发效率和体验,我们通过模块化的分割,将一个大文件,拆分为各相对较小的文件,这样也就可以避免在编辑器上的体验下降的问题。
3.3 JS部分
JS部分中,我们需要整理和注意的点其实非常的多,其中所涉及到的模块,功能、性能、安全、规范……,等等,各个词,甚至都可以拓展开为一个专门的课程,可见在这个大方向上,问题的复杂程度。
在本次的项目中,也只是一个很小的引子,希望可以引申出对于这些方向问题的考虑,而实际的使用,可能并没有涉及。
模块化
有点牵强,但可能如前面所述,可以是一个引子。这里的模块化,也就只是停留在了函数的简单封装,能有规范、明确的相关参数说明,以及相关的调用解析。
这些也仅仅只是JS模块化的冰山一角,问题(砖)的抛出,只是为了引出项目实施过程中,对于模块化开发的思考(玉)。
其过程中,可能有好几个词可以来提及,commonjs、AMD,这些思想,都是为了解决一种(一系列)具体的问题而产生,因此,要读懂这其中的内容,也必须要能理解这种问题是什么,痛到底在哪里,这里也仅仅只能讲到这个层次,更多的内容,后面有机会,我再会详细的来展开。
3.4 什么能交给工具
前面无论是示例,又或是说明,都有多次的提到模块化,而这种模块化,更多的层面是面向我们开发者,是为了:让开发者有更好的编辑体验,而对于机器来说,最终是需要运行,因此,这中间的一个衔接,都是可以交给工具来完成的。
LESS不能直接在浏览器直接识别解析
因此有了类似于 gulp-less 的解析编译工具,可以方便快捷高效的将你的 less 代码转换为对应的 CSS。
include是什么鬼,浏览器怎么认识
这个梗主要是用来给你人看的,而浏览器看不到它,中间就是因为有 nunjucks 的存在,解析了人机之间的区别。
我只能理解PX,但机器需要REM
px2rem 的引入,正好解决了这种人与机器之间的不同需要点,人能很好理解,机器又能很好适配。
……
工程化的过程,其实就是模块化、自动化之间的一种更业务层次的组合,每一个复杂业务场景出现时,最为直接的问题解决方向就是如何便于人的理解,又能便于机器的执行,这些不同层次问题的思考解决过程,其实就是我们所需要的思考模型。