码出未来,极客你来!

新蛋NESC微信招聘页面技术详解

1. 技术选择及简介

1.1 HTML5

2014年10月29日,W3C泪流满面地宣布,经过几乎8年的艰辛努力,HTML5标准规范终于最终制定完成了,并已公开发布。

HTML5的正式发布,可谓大快人心,是否今后各浏览器就能统一标准呢?还得拭目以待。

说到HTML5,首先会想到canvas,但在我们项目中,考虑到兼容性和上线时间,并没有使用HTML5的canvas。关于HTML5,我们用了其中的viewport技术。

手机浏览器是把页面放在一个虚拟的“窗口”(viewport)中,通常这个虚拟的“窗口”(viewport)比屏幕宽,这样就不用把每个网页挤到很小的窗口中(这样会破坏没有针对手机浏览器优化的网页的布局),用户可以通过平移和缩放来看网页的不同部分,如下图:

viewport.png

在我们项目中,为了使得页面自适应各种分辨率的手机尺寸,我们将viewport的大小等于手机屏幕大小,初始比例设为1,并且禁止用户手动缩放。

<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1, user-scalable=no">

1.2 JS

  • zepto.js,我们仅需要它进行DOM的操作,相较于jQuery Mobile,它体积更小,完全满足我们的需要,这就够了。而它的用法,和jQuery几乎一样,使用起来感觉不到差别。
  • touch.js,zepto的一个组件,用于支持触屏操作,仅6K。

1.3 CSS3

CSS3是我们这个页面的核心,所有的动画效果都是由它完成。而CSS3动画的精髓,无外乎这三个属性:变形(transform)、转换(transition)和动画(animation)。

更多关于CSS3的基础知识,可以前往CSS3 Introduction

2. 动画效果详解

2.1 通用的基础动画

在本项目中,有一些动画效果比较通用,主要是一些基本的平移、旋转、缩放等我们将这些通用的动画提取成了一个css库,叫做NEC,我们一起来看一下:

Fade渐变

.nec-ani-fadeIn

.nec-ani-fadeOut

Move平移

.nec-ani-moveFromLeft

.nec-ani-moveFromRight

.nec-ani-moveFromTop

.nec-ani-moveFromBottom

.nec-ani-moveToLeft

.nec-ani-moveToRight

.nec-ani-moveToTop

.nec-ani-moveToBottom

MoveFade渐变平移

.nec-ani-moveFromLeftFade

.nec-ani-moveFromRightFade

.nec-ani-moveFromTopFade

.nec-ani-moveFromBottomFade

.nec-ani-moveToLeftFade

.nec-ani-moveToRightFade

.nec-ani-moveToTopFade

.nec-ani-moveToBottomFade

MoveSpring弹簧平移

.nec-ani-moveUpDownSpring

.nec-ani-moveLeftRightSpring

Rotate旋转

.nec-ani-rotateLeft

.nec-ani-rotateRight

Scale缩放

.nec-ani-scaleUpCenter

.nec-ani-scaleDownCenter

.nec-ani-scaleDown

.nec-ani-scaleUp

2.2 黑客帝国的眼镜动画

很酷,对不对?其实实现起来很简单,只需要在眼镜的玻璃上放一个圆形的divdiv的背景图片选择一张包含很长的数字流的图片,然后通过css3控制background-position-y进行变化。

@keyframes matrixGlass {
     0% { background-position-y: 0%;}
   100% { background-position-y: -500%;}
}

2.3 飘落的彩带

这个动画也被加入NEC中了,只需要为你的需要飘落的元素上加上.nec-ani-flagWave这个类就可以了。

具体实现原理如下:

@keyframes flagWave {
     0% { opacity: 0; transform: translate(-250%, -500%) rotate(30deg);}
     5% { opacity: 1; transform: translate(-225%, -450%) rotate(28deg);}
    50% { opacity: 1; transform: translate(0%, 0%) rotate(0);}
    95% { opacity: 1; transform: translate(225%, 450%) rotate(-115deg);}
   100% { opacity: 0; transform: translate(250%, 500%) rotate(-120deg);}
}

2.4 浮动的标签云

Floating Tag浮动标签

CSS3

.nec-ani-tagFloatingLeft

CSS3

.nec-ani-tagFloatingRight

2.5 金鱼吐泡泡

Bubble冒泡

.nec-ani-bubble

2.6 摩托车

有一个摩托车从天而降,然后嗖的一下开走的小动画,很炫,那么它是怎么实现的呢?其实很简单,我们先来看一下分解动作:

首先在旋转-30度透明度为零的情况下,从天而降,下降到地面,并且下降的同时将透明度渐变到1,然后后轮着地时,开始做旋转的动作,将角度转到0,紧接着再做向右平移的动作,代码如下:

@keyframes autobike {
     0% { opacity: 0; transform: translateY(-400%) rotate(-30deg);}
    30% { opacity: 1; transform: translateY(-30%)  rotate(-30deg);}
    60% { opacity: 1; transform: translateY(0%)    rotate(0deg);}
   100% { opacity: 1; transform: translateY(500%)  rotate(0deg);}
}

3. 自适应屏幕尺寸

在自适应屏幕尺寸方面,我们花了不少努力。我们主要通过下面4个方面来控制在各种屏幕上显示效果的一致性:

  • 所有单位都基于百分比
  • 所有元素都是绝对布局
  • 以屏幕中心为基准,调整位置
  • 通过js控制整体缩放

我们以图片的宽度百分比来控制图片的大小,这样可以保证图片在不同尺寸的屏幕下,其图片宽度总是不会超过屏幕,并且他们之前的相对大小一致。

绝对布局是为了后面以屏幕中心为基准,进行位置的调整。通常的绝对布局是通过lefttop来进行定位,但是这样定位有一个问题:由于我们所有单位都是基于百分比的,而且left的百分比是基于屏幕宽度,而top的百分比是基于屏幕高度度,如果单纯使用lefttop来定位,当屏幕尺寸不成等比变化时,各元素的lefttop位移的比例不一样,导致各个元素之间的相对位置发生了改变,对于我们这个项目来说,这是不能允许的,例如第二幅动画里的地球自转,他和周围的建筑物之间的相对位置必须保持一致,否则显示效果就会很差。于是我们采用设置lefttop都为50%,然后通过margin-leftmargin-top来进行位置调整,根据W3C的规范,当margin的单位为百分比时,他们都是基于宽度来进行计算的,也就是说当屏幕尺寸变化时,我们margin-leftmargin-top的量只取决于宽度的变化,这样各元素的相对位置就保持一致了。

这样还有一个问题,当屏幕宽度不变,高度变得很低,甚至低于宽度的时候,也就是说用户横屏了,这时候整个页面虽然宽度没问题,高度也是居中的,但是人物头和脚会看不见,因为根据之前的理论,我们并没有对其进行高度的限制,仅根据宽度进行缩放。这时候,我们需要借助js,将整个wrap进行scale缩放。

我们发现,我们显示效果最优的屏幕比例是0.63,而当屏幕比例大于0.65时,会开始出现顶部和底部留的空白太少的问题,影响美观,当这个比例再大的时候,就会出现顶部或底部显示不全的问题,因此当宽高比大于0.65时,我们进行处理,将整个wrap缩小,缩小的比例为0.63/屏幕宽高比,为什么是这个值?大家可以自行画图理解。大家可以看下面三个图:

第一张,是正常的显示情况,第二张是没有进行缩放的显示情况,第三张是经过我们整体缩放之后的显示效果。可以看到,经过这样处理后,任何屏幕比例,我们都能较完美的显示出来。

4. 浏览器版本兼容性

说到浏览器的兼容性,其实经过测试,几乎目前所有智能手机的系统自带浏览器的显示效果都很不错,然而,在他们的微信上,显示效果却常常会有问题,主要是位置上的问题,元素之间的相对位置发生了变化,这不符合我们之前所做的努力。这一点,我们做了一些研究,结果发现和Webkit的内核版本号有关。先给出一些测试数据,见下表(均为Android机器,微信版本都是6.0版):

浏览器 显示效果 Webkit版本
A手机-微信 Good AppleWebkit/537.36
A手机-Chrome Good AppleWebkit/537.36
A手机-自带 Good AppleWebkit/537.36
A手机-百度6.0 Good AppleWebkit/537.36
A手机-搜狗 Bad AppleWebkit/534.30
B手机-微信 Bad AppleWebkit/534.30
B手机-UC Bad AppleWebkit/533.1
B手机-自带 Good AppleWebkit/537.36

从上面的表中,可以得出两个结论:

  1. Webkit内核版本号为537.36的均正常,而534.39、533.1不正常。
  2. 微信里的内置浏览器并不是用的自己的内核,因为同样版本的微信,里面浏览器却显示不同的内核版本。

好,我们先来解决第一个问题。

首先经过分析,我们发现,在534.39等不正常的webkit版本上,问题出在margin-top上,根据W3C的规范,margin-top值为百分比时,应当按照容器宽度作为基础,而在这些webkit版本中,却是以高度作为基础的。经过仔细搜寻,终于找到了这个bug,Webkit在2012年12月13日变更集137695中已经修复了这个bug。

下面问题来了,到底是低于哪个版本的webkit有这个bug呢?我们并没有能够找到webkit发布的history,只找到了safari的发布历史。通过safari的发布历史,我们基本可以确定,当webkit版本号小于536.28时,均存在这个bug。

下面我们来看第二个问题。

既然微信里的内置浏览器并没有自带内核,那他就应该是使用了系统中安装的某个浏览器的内核。

基于这个猜想,我们在A机器上又安装了各种浏览器,当我们安装了QQ浏览器之后,问题来了!QQ浏览器和A手机上的微信都挂了!显示效果都出了问题!

下面是A手机中安装了QQ浏览器之后的数据:

浏览器 显示效果 Webkit版本
A手机-微信 Bad AppleWebkit/533.1
A手机-QQ浏览器 Bad AppleWebkit/537.36

这里有一个坑

大家注意看上面的表格,QQ浏览器里的webkit内核版本号显示的是537.36,而他却并没有修复旧版的bug,而且在安装了它之后,微信就不行了,而微信里面显示的webkit内核却是533.1。这是咋回事?

其实,QQ浏览器是使用的自家基于webkit修改过的内核,号称X5内核,而他们的UA版本号却是伪造的537.36,其真实的webkit内核版本其实是533.1,关于这一点,强烈谴责一下腾讯,你说你基于两年前的533.1也就罢了,干嘛还要伪装成最新的呢?坑!是在太坑!

5. 微信分享的封面图片

一开始,我们一直以为我们可以通过微信企业号来进行发布,因为微信企业号发布的消息,是可以手动添加封面的。后来直到上线那天才发现,我们NESC的微信账号是服务号,不是企业号。我们只能直接通过链接自己分享到朋友圈、发给好友。那么问题又来了,如何控制微信链接前面的缩略图呢?

微信链接的缩略图的选择,官方并没有进行说明,通过研究,我们发现,微信会选择页面中第一张display不为none,并且分辨率大于400px*400px的图片作为缩略图,那就简单了,将制作好的一张分辨率为450px*450px的缩略图放在页面比较靠前的位置,并且加上style="width:0; height:0; position:absolute;"即可。

6. 写在最后

好了,分享完了,看完分享是不是很感兴趣?快来NESC,加入我们,一起成长吧!

各地HR的邮箱:

上海NESC

成都NESC

西安NESC