QQ天气H5-前端完整解析_html/css_WEB-ITnose
前言: 什么是手Q天气
手Q天气是在手Q 6.0版本以上新增的功能,页面会展现当天的气温情况,已经五天温度折线图以及24小时温度图表等。 并且为了更好的交互效果,天气页面会根据8种不同的天气信息,展现相应的天气动画。如下雨下雪,飘云,日光闪烁等动画效果。
在开发手Q天气的时候,学习到许多,发现有许多地方值得写一下。以下是我的总结。
一、REM整体布局
我们知道对于移动端来说,分辨率适配是个常见的问题,设计师往往给与我们的是iphone6(750px)的视觉稿。而对于天气页面来说 采用REM来整体布局 是个十分不错的选择。
rem 是什么
rem(font size of the root element)是指相对于根元素的字体大小的单位。简单的说它就是一个相对单位。rem计算的规则是依赖根元素。
基本写法
如下面定义html的节点
/*定义html根元素字体大小*/html{ font-size:10px;}/*定义子元素,采用rem作为单位*/.sonDom { width: 6rem; /*相当于 6*10=60px*/ height: 3rem; /*相当于 3*10=30px*/ line-height: 3rem; /*相当于 3*10=30px*/ font-size: 1.2rem; /*相当于 1.2*10=12px*/ border-radius: .5rem; /*相当于0.5*10=5px*/}
从上面可以看出,rem其实相当于一个划算单位
举个例子,我们平时理解的 1米=10分米=100厘米
同理可得: 1rem = 根元素font-size的值
这里一开始设置了 html根元素font-size为10px,即 1rem = 10px
通过上面的,我们可以得出
可以通过改变html的font-size的值而等比改变所有用了rem单位的元素。
而这个正是rem实现完美的分辨率适配的原理。
如何动态更改根元素font-size值
为了实现分辨率适配,我们需要用根据屏幕的大小动态去计算根元素的font-size的值 目前普遍的是两种方法:
1、通过媒体查询方式
通过媒体查询的方式,能够满足大部分场景,只需要把常用的屏幕宽度考虑进去即可
/*默认为20px*/html { font-size : 20px;}/*判断宽度设置不同的html font-size值去覆盖默认值*/@media only screen and (min-width: 320px){ html { font-size: 10px; }}@media only screen and (min-width: 375){ html { font-size: 16; }}@media only screen and (min-width: 414px){ html { font-size: 20px; }}
2、通过js设置
如果希望把所有屏幕大小给考虑进去,可以考虑使用js来计算(天气H5也是使用js来换算),如下面的代码
//设置fontsize var doc = document, win = window; function initFontSize () { var docEl = doc.documentElement, resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize', recalc = function() { var clientWidth = docEl.clientWidth; //window.innerWidth; if (!clientWidth) return; fontSizeRate = (clientWidth / 375); var baseFontSize = 15 * fontSizeRate; docEl.style.fontSize = baseFontSize + 'px'; }; recalc(); if (!doc.addEventListener) return; win.addEventListener(resizeEvt, recalc, false); doc.addEventListener('DOMContentLoaded', recalc, false); };
rem换算
我们在开发的时候,往往不希望涉及到rem的换算,如一个设计稿按钮是120px,如果我们根节点font-size是14px, 计算 120/14=8.571rem。感觉还是挺麻烦得 而这些工作是可以通过 sass等预处理器 或者 构建 去完成
如下面 翔神写的fis插件
https://github.com/imweb/fis-parser-rem
效果图
如下面, rem的适配效果还是挺不错的
rem需注意点
在移动端使用rem的话,兼容性没问题的。但还是存在着一些需要注意的地方:
1、小数数值处理
不同浏览器计算rem转换为px数值时,对于小数点后的数值的处理是有所偏差, rem计算偏差的根源是浏览器内核数字类型的区别 ,如果浏览器的内核数字类型是float类型,能够较好地支持有小数点的数值。当浏览器内核数字类型是int类型,不支持小数点,会对数字进行四舍五入,这样就会有偏差。如果元素越大偏差得就越明显!
2、雪碧图rem
使用rem的同时又涉及到雪碧图时,由上面我们可以得知,rem的换算成px的尺寸非严格精确尺寸,如果雪碧图如果图标之间的距离过小,就可能导致图标过界,因此图与图之间的间隙需要留相应大一点。
3、单纯的rem没解决高度适配的问题。
单纯的rem没解决高度适配的问题,当然目前也没有特别多高度适配的场景,因此建议如果需要在使用rem基础上还做相应的高度适配,就要通过相应的js去辅助啦。
2、弹性盒子局部布局
我们发现,过去对于页面均分的布局时,我们比较常用下面的方式:
- 使用float浮动子元素的方法,但需要注意清除浮动
- 或者是设置子元素为inline-block,但需要注意设置子元素margin值
或许我们可以考虑下css3弹性盒子模型。
兼容性
让人惊喜的是目前的主流智能移动设备操作系统Android和ios的内嵌浏览器对其也有不错的支持。对移动开发来说这真是太美好了,至少对于不太喜欢使用float,padding的我来说是这样的。
手Q天气的使用
如下面这样的布局整个div分成5个部分,每个部分占据同样的宽度。
上面的html结构如下
通过弹性盒子模型,设置其css代码如下:
/*设置容器为盒子*/.info-day-list { display: -webkit-box; padding: 1rem 0;}/*设置item*/.info-day-item { -webkit-box-flex: 1; /*设置item占据的比例*/ width: 1%; font-size: 1.4rem; line-height: 3rem; text-align: center;}
通过上面,可以发现,弹性盒子将模块的所拥有的空间进行我们自定义比例去分配。上面每个item设置的 box-flex 都为1,故其都有父容器 剩余空间 1比重的宽度。
需注意点
1、弹性盒子模型div块因为文字内容不同而不均分
在开发的时候,我发现在使用弹性盒子模型时,如果涉及到文字的时候需要注意
由于天气的描述文字长度不同,如西南风和微风,分别是三个字和两个字。会有不同的宽度而导致不均分
如上面css所示,我设置了子元素width为1%(只有设置了item是统一的width就行,不一定需要是1%)就可以解决这个问题
HTML5 canvas
我们可以看到在页面中带有温度折线图以及下雪下雨的动画,这个时候我们发现使用dom去绘制这样稍微复杂的动画时,性能并不好也不好操作。这时候我们可以考虑使用到HTML5的canvas画布去实现了。这样 可规避渲染树的计算,使渲染更快
由于代码比较篇幅较长,这里只给最终生成效果哈。
折线图表
下雨下雪动画
效果如下, 发现使用canvas在绘制这些动画的时候,还是十分方便的。
具体实现可以看下面这个文章 -前端如何呼风唤雨
canvas需注意点
1、canvas高清屏模糊
在绘制折线图的时候,我们发现,折线图在高清屏下十分模糊,这是为什么呢?
熟悉retina屏的同学应该都知道,在浏览器的window变量中有一个devicePixelRatio的属性,该属性决定了浏览器会用几个(通常是2个)像素点来渲染1个像素,举例来说,假设devicePixelRatio的值为2,一张100x100像素大小的图片,在retina屏幕下,会用2个像素点的宽度去渲染图片的1个像素点,因此该图片在retina屏幕上实际会占据200x200像素的空间,相当于图片被放大了一倍,因此图片会变得模糊。
因此我们的解决方案时: 更加屏幕像素比devicePixelRatio的小同比方法canvas
如下面代码
//兼容高清屏幕,canvas画布像素也要相应改变 var c = document.getElementById("canvas"); //获取devicePixelRatio var DPR = window.devicePixelRatio;画布宽高 //同比设置画板宽高 c.width = = canvasWidth * DPR; c.height = canvasHeight * DPR;
2、内存占用
canvas对内存的消耗是挺大的,如非必要还是不要使用多个canvas
css3 transition animation
我们可以使用CSS3的transition和animation来实现许多交互效果。
使用transition实现滑动Slider
在天气内页有个星座slider,如下面
通过设置每个卡片的类名,使其切换不同的位置
.star-icon-outside-l { z-index: 20; -webkit-transform: translateX(-18.8rem) scale(.673); transform: translateX(-18.8rem) scale(.673);}.star-icon-outside-r { z-index: 20; -webkit-transform: translateX(8.5rem) scale(.673); transform: translateX(8.5rem) scale(.673);}.star-icon-beside-l { z-index: 40; -webkit-transform: translateX(-12.5rem) scale(.851); -webkit-transform: translateX(-12.5rem) scale(.851);}.star-icon-beside-r { z-index: 40; -webkit-transform: translateX(2.35rem) scale(.851); transform: translateX(2.35rem) scale(.851);}.star-icon-hide-l { z-index: 10; -webkit-transform: translateX(-25rem) scale(.673); transform: translateX(-25rem) scale(.673);}.star-icon-hide-r { z-index: 10; -webkit-transform: translateX(17rem) scale(.673); transform: translateX(17rem) scale(.673);}.star-icon-cur { z-index: 90; -webkit-transform: translateX(-5.05rem) scale(1); transform: translateX(-5.05rem) scale(1);}
animation循环动画
1、渐隐渐现
@-webkit-keyframes toggleShow{ 0% { opacity: 0; } 11% { opacity: 0; } 12.5% { opacity: 1; } 20%{ opacity: 0; } 100%{ opacity: 0; }}
2、放大收缩
@-webkit-keyframes shine{ 0% { -webkit-transform: scale(1,1); } 50% { -webkit-transform: scale(1.2,1.2); } 100% { -webkit-transform: scale(1,1); }}
3、飘动
@-webkit-keyframes moveToLeft /* Safari 和 Chrome */{ from {-webkit-transform: translate(0);} to {-webkit-transform: translate(-33.33333333%);}}
优化
我们知道,在移动端开发,性能和加载速度是十分重要的,这里我们就需要考虑所有前端能优化的点,做好了优化, 才能时你这个页面更好的展示。以下是相关的优化内容
基本动画优化
基本的动画优化,如使用transform的translate来代替left等位移操作 3D加速等,
合理使用RAF(requestAnimationFrame)
使用raf能解决脚本问题引起的丢帧,卡顿问题,并且支持中间状态监听
//首页判断是否可以使用requestAnimFrame来替换setTimeoutwindow.requestAnimFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || function(callback) { return window.setTimeout(callback, 1000 / 30); };
canvas优化
使用canvas实现下雨下雪效果,是通过一帧一帧地去重绘下落的雨滴或者雪花。这里雪花雨滴越多,对手机的性能要求就越高。
因此我们需要对不同的手机进行处理,对于一些稍微低端的手机进行一些 降级处理和优化 。 根据渲染情况,相应的减少雨滴和雪花的个数,减少渲染计算时间
//判断每次update的时间差,如果发现时间长过长,则相应地减少动画的最大雪花个数 if (new Date - lastTime > 30 && drops.length < OPTS.maxNum && OPTS.maxNum > 21) { OPTS.maxNum -= 10; }
内存优化
由于我们打开天气广告时,是新开一个webview的 因此我们需要暂停被遮住的天气webview的天气动画,减少内存消耗
if(mqq&&mqq.iOS&&mqq.addEventListener){ mqq.addEventListener("qbrowserVisibilityChange", function(e){ cancelAnimationFrame(drp_ticker); if(!e.hidden){ update(); } }); }
合理使用缓存
为了加快二次加载页面的速度,我们就需要使用好缓存。
天气的数据,都会用localstorage缓存起来
第二次短时间加载则会使用localstorage的数据,加快二次加载速度。
//判断是否有可用的缓存if (checkCache('weather-local_weather_info')) { //有则使用缓存 Page.processData(local_weather_info); weather_info = local_weather_info;} else { //没有缓存则去请求 Vinda.getData('data-weatherInfo', function(data) { if (data && data.retcode == 0) { Page.processData(data); //将天气信息存储进来,新增时间戳,用于缓存新鲜度的判断 $.extend(data.result, { searchTime: +Date.now(), city: city }); //每次获取都会更新缓存 $S.save({ key: 'local_weather_info', value: data }); });}
预加载
DNS预解析
我们可以通过dns 预解析prefetch,提前解析,减少dns请求时间
<link rel="dns-prefetch" href="//pub.idqqimg.com" />
CGI预加载
由于天气页面是强数据页面,对于cgi数据是强依赖的。因为提前预先加载cgi能够使我们更快地去渲染页面而不是等先拉取页面js再去执行页面js去请求cgi的这样的顺序。
代码优化
dom对象池复用
在天气内页有个星座slider,如下面
我们知道总共有12个星座,但我这里却只使用了7个dom(5个可见,2个分别是隐藏的),通过复用来实现循环的12个月。虽然这里并没有减少很多dom的数量,但我觉得dom对象池复用的思想能给多dom节点的的场景带来质的飞跃。
异步加载权重较低的模块
由于整个天气又有折线图,又有动画,又有下雨下雪等东西。因此我们需要对页面进行模块划分。每个部分都是一个模块 我i将天气页面大致分成下面几个模块
//页面总模块var Page = {/**/};//头部模块var headerMod = {/**/};//时间维度的温度变化图var timeDegreeMod = {/**/};//广告模块var adsMod = {/**/};//一周天气情况图var detailMod = {/**/};//天气动画模块var AnimationMod ={/**/}
然后通过总模块去管理子模块,由于模块的划分,我们可以很轻松的根据页面展示权重和先后顺序,分别去渲染和异步加载相应的模块
var Page = { render: function(){ //渲染基本页面 headerMod.render(); timeDegreeMod.render(); detailMod.render(); //加载完天气信息才去加载广告; adsMod.getAds(); //由于权重较低,因此异步加载下雨下雪的动画部分组件 require.async('./setAnimation', function(AMod) { AnimationMod = AMod; AnimationMod.init(); }); }}
其余基本优化
雪碧图,文件合并等减少请求数
资源压缩,代码压缩减少请求体积。
内联css, js置后等渲染无阻塞
兼容点
在开发手Q天气时,还遇到下面一些需要兼容和注意的点:
ios 广点通app广告处理逻辑兼容
由于手Q天气涉及到广告,大部分广点通广告是只需要点击链接跳转就可以了
但有些广告由于是app广告,需要引导用户去下载,故在ios上则需要做些兼容。在ios手机需要通过以下判断,改为呼起app store下载页面
//判断是否为手Q打开且为ios且为app下载广告var isIosAppAds = mqq.iOS && mqq.device.isMobileQQ() && producttype == 19;//如果是app ios 广告,//则jsonp请求广点通给的跳转链接,获取跳转appstore的tencent串if (self.isIosAppAds) { $.ajax({ url: adsMod.jump_url, data: { acttype: 1, }, dataType: 'jsonp', success: function(o) { if (o && o.ret >= 0) { var data = o.data || {}; if (data.dstlink) { //通过手Q接口呼起app mqq.app.launchApp({ name: data.dstlink //self.dstlink }); } } } });} else { //默认打开新webview即可 mqq.ui.openUrl({ url: adsMod.jump_url, target: 1, style: 0 });}
X5内核兼容点
由于我们的场景是在手Q上打开,故需要兼容X5内核上的规范。
在 X5 tbs.1x版本时 ,伪元素是不能做动画的。
在 X5 tbs.1x版本时 ,不支持transition-timing-function 的ease-out曲线
目前了解,貌似到了X5 tbs.2x版本正在开始灰度支持。
更多x5上的问题,可以通过以下链接去查看QQ浏览器官网的 X5技术指南
非a标签跳转 bug
因为天气页面有许多跳转上报,需要先上报再跳转,然后我之前是这样写的
<div id="js-jump-xxx" onclick="reportAndJump();"></div>
但这样写发现在低版本的android机上,只能发起上报请求而不能进行链接跳转
后来经排查,发现低端android机只能使用a标签进行跳转操作
<a id="js-jump-xxx" onclick="reportAndJump();"></a>
不足
- 由于页面涉及到比较多的动画和canvas,故对 内存的消耗比较高 ,这方面一直没有很好去解决低内存手机的内存消耗问题
- 页面动画渲染和代码仍需雕琢。当时刚入职,许多方面还是一知半解。故自我觉得仍然有许多可以优化的地方。。。
总结
QQ天气H5是我毕业来到腾讯的第一个独立开发的项目。虽然现在已经交接了。但我时不时都会去看下这个项目的动态和代码提交记录。QQ天气H5这个项目,让我在刚入职时学会了许多。虽然写得并不是很好啦。

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

Video Face Swap
Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen



HTML ist für Anfänger geeignet, da es einfach und leicht zu lernen ist und schnell Ergebnisse sehen kann. 1) Die Lernkurve von HTML ist glatt und leicht zu beginnen. 2) Beherrschen Sie einfach die grundlegenden Tags, um Webseiten zu erstellen. 3) hohe Flexibilität und kann in Kombination mit CSS und JavaScript verwendet werden. 4) Reiche Lernressourcen und moderne Tools unterstützen den Lernprozess.

HTML definiert die Webstruktur, CSS ist für Stil und Layout verantwortlich, und JavaScript ergibt eine dynamische Interaktion. Die drei erfüllen ihre Aufgaben in der Webentwicklung und erstellen gemeinsam eine farbenfrohe Website.

AnexampleofaTartingTaginHtmlis, die, die starttagsaresesinginhtmlastheyinitiateElements, definetheirtypes, andarecrucialForstructuringwebpages und -konstruktionsthedoms.

WebdevelopmentRelieSonHtml, CSS und JavaScript: 1) HtmlStructuresContent, 2) CSSstylesit und 3) JavaScriptaddssinteraktivität, Bildung von TheBasisofModerernwebexperiences.

GitePages statische Website -Bereitstellung fehlgeschlagen: 404 Fehlerbehebung und Auflösung bei der Verwendung von Gitee ...

Der ad-axis-Position adaptive Algorithmus für Webanmerkungen In diesem Artikel wird untersucht, wie Annotationsfunktionen ähnlich wie Word-Dokumente implementiert werden, insbesondere wie man mit dem Intervall zwischen Anmerkungen umgeht ...

Um den Effekt der Streuung und Vergrößerung der umgebenden Bilder nach dem Klicken auf das Bild zu erreichen, müssen viele Webdesigns einen interaktiven Effekt erzielen: Klicken Sie auf ein bestimmtes Bild, um die Umgebung zu machen ...

HTML, CSS und JavaScript sind die drei Säulen der Webentwicklung. 1. HTML definiert die Webseitenstruktur und verwendet Tags wie z.
