剑客
关注科技互联网

基于active,checked等状态类名的web前端交互开发

这篇文章发布于 2016年10月30日,星期日,00:00,归类于web综合。 阅读 109 次, 今日 108 次

byzhangxinxu from http://www.zhangxinxu.com/wordpress/?p=5716

本文全文转载需购买版权(500¥),摘要引流则免费,具体参见这里

一、热身开始

在我们进行web前端开发的时候,恩,换种接地气的说法,在我们进行网页制作的时候,一定会存在各种交互效果,比方说,选中高亮,点击显示更多,选项卡切换等等。

我可以拍着胸脯说,绝对多数前端人员在实现这些交互效果的时候,是没有什么规范或者准则的。比方说点击显示更多,有些人可能直接jQuery $().show() 方法,有些人可能会写个类似 .more-show 的类型控制显示,具体使用什么方式,用什么样的命名,完全要看网上搜到的代码是如何实现的,以及看当时的心情。

代码如产品,要想做出好产品一定要细心打磨,同样的,如果要想写的好代码也需要细心打磨。所谓打磨,就是让一些“糙”的地方变得流畅。

好产品的意义在于用户和企业受益,好代码的意义在于自己的寿命以及同事关系。

交互效果的实现方式随性,就是代码“糙”的地方,我们其实可以约定一套通用的规范或者准则,这这一块变得流畅。虽然说从产品的角度讲,意义不是很大,但是对于我们开发人员自己或者一起合作的同事而言,却是很有裨益的。因为,可以降低我们日后维护的成本,同时有其他一些非常受用的益处。需求总是要变更了,迭代总是要进行的。好的代码准则可以让你不怕需求变更,不要加班修“霸哥”。和产品成为好盆友,每天可以早早回去陪女朋友看电视,岂不很好!

我经过这些年的实践和提炼,对于交互效果的实现提炼了一套实践准则,至少在我目前这个阶段,觉得是很有裨益的,这里跟大家分享下。

如果用一句话概括下这个交互实现准则就是: 完全基于active,checked等状态类名的web交互开发

二、进入正题:基于active,checked等状态类名的web交互开发

那什么是“基于active,checked等状态类名的web交互开发”呢?

我们拿最最简单的“点击显示更多”效果举例,比方说下面这种现在见的比较多的查看更新信息的效果:

基于active,checked等状态类名的web前端交互开发

默认状况下,容器会设定一个高度,例如 80px ,然后 overflow:hidden ,类似下面的CSS:

.box {
    height: 80px;
    overflow: hidden;
}

此时要实现点击展开效果,其实很简单,比较偷懒的做法就是JS一步搞定:

more.onclick = function () {
    box.style.height = 'auto';
};

也有喜欢用CSS类名控制的小伙伴,此时会发挥自己在CSS命名上的天赋,来一个 .height-auto 的类名:

.height-auto {
    height: auto;
}

于是,JS代码变成:

more.onclick = function () {
    box.className = box.className + ' height-auto';
};

其实从产品角度讲,上面两种实现都无伤大雅,都是不错的实现,但是从代码层面讲,则均有不足之处。

1. JS直接控制样式的不足

由于我们网页大部分的样式都是CSS控制的,一旦JS也直接参与样式控制,CSS和JS就存在交叉关系,用一个软件术语描述就是“耦合了”,一旦两个事物发生耦合,势必会增加日后的维护成本。举个例子,产品上线后,设计师突然希望这里的展开不要这么的硬,希望可以有点CSS3动画效果。请问,此时,你当如何维护,是不是CSS既要修改(增加动画控制),JS也要修改(设置 heightauto 不会触发CSS3动画),看,要修改两个地方。如果我们一开始所有的样式都值交给CSS控制,只需要改一个CSS文件就可以了。同时,考虑到,很多公司写CSS的和写JS的不是同一个人,如果CSS和JS同时修改,岂不是要动用两个人力参与,这用人的成本和周期就上去了。虽然,计算下来,都是小成本,但是,但我们埋头某项目或者某问题的时候,被这种小需求插入,其实是很损耗精力的。如果这类小打小闹(尤其不是自己本职的)总能避免,工作岂不会轻松很多。

2. 命名语义或随意的问题

类名样式语义本无可厚非,但是,对于JS交互效果实现而言,语义化就是问题所在。语义化的类名往往代表了自身是有CSS样式的,例如,上面的 .height-auto ,但是,由于我们这种添加类名的行为是在JS代码中完成的,因此,本质上,

more.onclick = function () {
    box.className = box.className + ' height-auto';
};

more.onclick = function () {
    box.style.height = 'auto';
};

几乎没有任何区别。这个点很重要,大家再仔细想想,这两者是不是没有本质的区别。还是举例说明,同样的,设计师突然希望这里的展开不要这么的硬,希望可以有点CSS3动画效果。虽然说,从技术的角度讲,我们只需要修改CSS代码就可以了,但是,这个 .height-auto 命名…如果我们把里面的样式改成了CSS3动画相关内容,是不是就牛头不对马嘴了?是不是要去JS中把这个类名改成 .height-animate 之类的。看,最后还是改了两处。

另外还有一个看上去不是问题的问题,那就是,一个页面往往会有很多很多的交互效果,如果没有交互效果都有一个对应的类名控制,那岂不是JS文件中有很多样式控制的类名。很显然的,这东西一旦多了之后啊,自然也就不好维护了。

—————-低调的分隔线———–

但是,如果我们采用“基于active,checked等状态类名的web交互开发”,就不会有上面JS和样式耦合的问题。如何做呢?很简单,就是,我们控制样式的类名使用 .active.checked 等这种状态类名,例如:

more.onclick = function () {
    box.className = box.className + ' active';
};

并且,网页所有的页面交互都使用这种状态类名,根据我自己的实践,就算所有交互都使用 .active 这同一个类名都是可以的,而且事实上是推荐这么做的。

注意,下面这条准则很重要,很重要,是本文的精髓–

.active等JS交互类名自身绝对…绝对不能有CSS样式

再说一遍, 自身无样式 ,就是一个状态标识符,用来和其他类名发生关系,然后让其他类名的样式发生变化。这种关系可以是父子,兄弟或者自身。

不急,我们先看一个例子,您可以狠狠地点击这里: 基于.active类名的显示更多交互demo

默认是这样的:

基于active,checked等状态类名的web前端交互开发

当我们点击更多按钮后,会以CSS3动画的方式展开剩余所有文字信息,如下动图:

基于active,checked等状态类名的web前端交互开发

下面我们看下关键的CSS代码,这个 .active 是如何自身无样式的:

.box {
    max-height: 80px;
    transition: max-height .25s;
    overflow: hidden;
}
.box.active {
    max-height: 200px;
}
.active > .more {
    display: none;
}

可以看到,当我们点击按钮后,盒子变高,以及更多元素隐藏,全部都是通过和 .active 发生关系后发生的,而不是 .active 自己的样式。例如,我们盒子实现的 200px 以内任意高度的动画效果,是通过 .box.active 组合类名触发的,用中文解释就是 .box 元素同时有 .active 状态的时候,样式如何如何…

同样, .active > .more 表示,当我的爸爸状态为 .active 的时候,我隐藏。

.active本质上扮演的角色不是类名样式,而是一个标识符!

—————-低调的分隔线———–

有人可能会疑问,为什么要这样处理呢?

还记不记得 .height-auto 命名问题所在,由于这个类名本身牵扯样式,因此,本质上,还是把CSS样式牵扯到了JS文件中。但是,如果是一个完全没有独立样式的状态标识符,则 .active 在JS中扮演的角色也就成了一个完完全全真真切切的状态占位符了!也即是说,虽然我们的JS文件中出现了类名,但是,就如同 .JS_xxx 类名作为DOM选择器一样,本身适合样式分离的, 实现了真正意义上的样式和行为分离

比方说,技术总监突然觉得这里展开更多有动画效果太啰嗦,要直接展开,要更硬朗,需要进行改动怎么办?你会发现,我们根本无需劳烦JS开发工程师,直接页面仔改一下CSS文件就可以了,例如,回到一开始的 height:auto

.box {
    height: 80px;
    overflow: hidden;
}
.box.active {
    height: auto;
}

三、高潮开始:基于active状态类名的web交互开发更炸裂的优点

采用“基于active状态类名的web交互开发”除了上面提到的“CSS样式和JS行为分离”有利于日后维护的优点外,还有很多其他炸裂的优点:

  1. 省了很多想命名的脑细胞

    妈妈再也不要担心有些单词不知道怎么翻译啦~~

  2. CSS和JS代码可读性更强了

    一旦在CSS或JS中看到 '.active' ,大家都知道,页面这块内容要变形了;

  3. JS代码量更少了

    例如,我们在全局,或者顶层局部定义这么一个变量:

    var ACTIVE = 'active';

    则,由于我们所有的交互都只要这一个类名,因此,当我们JS压缩的时候,其压缩率要高很多,也更好维护。加入说页面中有10个UI交互效果,原先是10个不能压缩的字符串,现在变成了1个,代码量自然要少。

  4. 类名压缩成为了可能

    我几乎从未见到国内的网页产品HTML中的类名是有压缩的,如果 .aaa-bbb-ccc 这种类名可以压缩成1~2个字符,那岂不是CSS和HTML压缩率会更喜人,同时,我的 CSS命名最佳实践(无ID,无层级,无标签) 唯一的HTML中className会比较多的问题也解决了。

    类名压缩最大的阻碍,在我看来,就是我们小伙伴在实现JS交互效果的时候不注意,常常把带有CSS样式的类名混在JS文件中,并且命名随意,并且,会把类名字符串进行分隔处理,尤其一些网上的UI组件,类似:

    var classNameRoot = 'swipe-slide-';

    然后,通过这个类名前缀,拼接其他类名,你说,这该如何准确压缩。

    但是,如果大家遵循“基于active状态类名的web交互开发”,JS文件中只有不参与CSS样式的类名选择器,以及不参与CSS样式的交互效果占位符,则我们就可以通过简单的设置不过滤的类名,实现我们的类名压缩效果了。例如在 config.js 中:

    {
        "compressClassName": true,
        "ignoreClassName": ["active", "disabled", "checked", "selected"]
    }

    让我们的类名压缩工具不压缩这些类名,则我们完全不要关心JS,也就是无需去截自页面使用的JS资源,只要安安心心压缩CSS文件中的类名,同时对我们页面中使用的类名进行压缩就可以了,一个想实现很多年的东西就通过这么个实现准则约束给实现了。

    实现了?对,实现了。

    由实习生完成的我们阅文集团新的招聘官网已经可以外网访问了,不过还有些细节需要打磨,所有老站还没做301跳转,现在我是悄悄的告诉大家地址的,大家这几天低调传播,什么时候高调传播可以关注我的微博: http://join.yuewen.com/

    整个招聘站的HTML类名(如果CSS有使用)全部进行了2字符的压缩(2字符显得更规整,我心里舒服),如下截图:

    基于active,checked等状态类名的web前端交互开发

    经测试,CSS大小可以降低10%,HTML则受标签多还是内容多影响,也是有明显的体积减小的。

四、缓缓收尾:为何以前没有这样的实践准则

“基于active状态类名的web交互开发”在多年之前实际上是很难实践下去的,因为,该准则依赖于的CSS关系符选择器,而几乎所有的CSS关系符选择器都是从IE7浏览器开始才支持完全的。

例如: .active.xxx 之前在IE6下是有bug的,顺序没放好,可能会发生 .active 冲突的情况;相邻父子关系 .active > .xxx IE7浏览器才开始支持,由于我们网站几乎所有普通交互都使用这同一个 .active 类名,因此,不能简单使用父子选择器 .active .xxx 有一定概率会发生冲突,使用相邻父子关系 .active > .xxx 约束则无此问题;相邻兄弟选择器 .active + .xxx 以及普通兄弟选择器 .active ~ .xxx 全部都是IE7浏览器才开始支持。也就是,浏览器的发展催着这这种更好实践的成型和普及。不好意思,说错了,应该还没普及,我是希望可以从本文开始慢慢普及。

我想,现在基本上很少有公司还要兼容IE6的了,如果你的产品还要做这样的事情,我只能扼腕而叹了。

五、缓缓收尾:我常用的一些状态类名

我简单回顾了下,我使用的状态类名最多的就是 .active 以及 .disabled ,在单复选框UI组件使用过 checked ,自定义下拉使用过 selected 等,其他几乎鲜有使用。

另外,还有其他一些状态类名,当然,是我见别人用过的,有 .on ,以及 .in.out 。前面的 .on 等同于我习惯使用的 .active ,因为 .on 的状态含义更广,例如单选框选中用 .on 表示就挺好,但是如果是 .active 则似乎则是另外的意思了,所以,如果大家希望偷懒,建议可以试试 .on 这个状态标识符,真正的可以贯穿所有交互的状态类名;后面的 .in.out 是用来标示CSS3 animation 动画状态的,也属于状态类名。

等等。

六、最终收尾

中国有句成语,就做“立竿见影”,比喻效果很明显。

如果从降低维护成本的角度讲,折腾那些node前端工具流所节约的开发和维护成本确实是立竿见影,相比之下,本文的这点东西(如果不是后面的类名压缩撑腰)节约的开发和维护成本简直就是不值一提。

这其实是一件很悖论的东西。从企业的角度讲,自然是希望员工能够把好钢用在刀刃上,以最小的力带来最大的收益,优先解决最为瓶颈的东西上,所以,如果大家比较看重职级,抬头,薪资这样的东西,建议更多精力花在这些“立竿见影”的事情上,本文的这些内容呢,大可不必较真。但是,从工程师的角度讲,指有责任心的工程师,会对技术和代码品质很有追求,会化很多精力去磨代码,这其实是很棒的一件事情,就好比本文所说的这些代码准则。然而,问题在于,工程师花了很多精力做这样的事情,其带来的价值往往并不是立竿见影的那种,需要时间来证明。从企业的角度讲,这样的工程师并不一定是最想要的工程师,尤其中小企业。企业属于商业机构,不是学术交流场所,看重利益,所以,很多做技术的同学一定要认清这一点,如果你在意公司对你的认可,做出立竿见影的成绩来说话;如果你觉得自己技术很不错,但升职加薪的不是我,想想看是不是自己的认知层出现了偏差,是不是认为代码最棒的就应该工资最高。当然,如果你就是希望技术纯青,对世俗这些不care,则建议你要一直坚定的走下去,每天成长每天提高,通过技术给企业给同事给同行带来更加沉稳更加厚重的收益,假以时日,你一定可以走出和别人不一样的康庄大道,要知道,决定一个人最终成功的不是智商,而是毅力。这些话既是鼓励也是自勉。

对了,对于前文提到的我自己写的类名压缩工具,目前暂不开放,除了精力有限的原因外,最主要原因是……想了想,归根结底还是精力有限,嫌麻烦。你看我10月份就2篇文章,忙的连鱼缸的鱼都没时间喂。

恩,就这些,欢迎交流!

基于active,checked等状态类名的web前端交互开发

本文为原创文章,尊重辛勤劳动,可以免费摘要、推荐或聚合,但完整转载需付费购买版权,详见转载协议声明

本文地址: http://www.zhangxinxu.com/wordpress/?p=5716

(本篇完)

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址