--- layout: post title: "Web App 相关技术" date: 2015-06-17 14:06:05 categories: JavaScript tags: JavaScript HTML CSS Sass 移动端 XSS AMD requireJS CommonJS 性能优化 WebApp --- * content {:toc} > 往前推2到3年,前端工程师还在忧心忡忡地想,移动互联网时代下,前端是不是没有生存空间了。但今天一看,在我们团队,前端工程师超过一半的工作都是在做移动端的Web或者APP的开发。移动Web或者APP在技术本质上是和做桌面端Web没有本质区别,但是移动端的坑那是非常的多,通过学习这部分内容,让你成为一名桌面移动通吃的前端开发工程师。 ## 概念 * 参考: [移动 Web 开发入门](http://junmer.github.io/mobile-dev-get-started/) 上面这个 slide 资料讲的非常好,算是一个入门的介绍吧。带我们建立基本的移动 web 开发知识体系和常见问题的实践。包含以下几个方面: * 基本概念 * Native 本地应用 使用 Java \ Objective-C \ Swift 开发 * WebApp 网页应用 html5 开发 * Hybrid 混合应用 ooxx(native, web) * 对比 * 视觉 * 设备的像素 * 文字单位使用 rem * viewport 属性 * 横屏竖屏 * Flex 伸缩布局 * 响应式设计 * 软键盘 * 隐藏地址栏 * 苹果设备添加到主屏图标 * 交互 * Touch * click 延迟 * Scroll * Gestures(hammer --A javascript library for multi-touch gestures) * 手指友好设计 * HTML5 APIS(图像,摇动,声音等) * 实践 * 屏蔽点击元素时的阴影 * 图像(像素、矢量图标、base64 减少请求、lazyload) * CSS3(合理使用渐变/圆角/阴影、代替 js 动画、translate3d、解决动画闪烁) * localStorage * 避免(iframe、fixed + input) * SPA 或 Multi page * can I use * 压缩合并 * @G/3G 下建立连接时间 * 调试 * 浏览器自己的调试工具,模拟手机设备 * weinre 关于 weinre 我写了一篇博客介绍它。[Weinre --WebApp 调试工具](http://gaohaoyang.github.io/2015/06/18/weinre/) --- ## head 标签 参考: * [移动前端不得不了解的html5 head 头标签](http://www.css88.com/archives/5480) 上面的链接详细的讲解了: * DOCTYPE * charset * lang属性 * 优先使用 IE 最新版本和 Chrome * 360 使用Google Chrome Frame * SEO 优化部分:页面标题标签(head 头部必须),页面关键词 keywords,页面描述内容 description,定义网页作者 author,网页搜索引擎索引方式 * 为移动设备添加 viewport `viewport` 可以让布局在移动浏览器上显示的更好。 通常会写 ```html <meta name ="viewport" content ="initial-scale=1, maximum-scale=3, minimum-scale=1, user-scalable=no"> <!-- `width=device-width` 会导致 iPhone 5 添加到主屏后以 WebApp 全屏模式打开页面时出现黑边 http://bigc.at/ios-webapp-viewport-meta.orz --> ``` * content 参数: * width viewport 宽度(数值/device-width) * height viewport 高度(数值/device-height) * initial-scale 初始缩放比例 * maximum-scale 最大缩放比例 * minimum-scale 最小缩放比例 * user-scalable 是否允许用户缩放(yes/no) * ios 设备,iOS 图标,Android,Windows 8 **总结:** ```html <!DOCTYPE html> <!-- 使用 HTML5 doctype,不区分大小写 --> <html lang="zh-cmn-Hans"> <!-- 更加标准的 lang 属性写法 http://zhi.hu/XyIa --> <head> <!-- 声明文档使用的字符编码 --> <meta charset='utf-8'> <!-- 优先使用 IE 最新版本和 Chrome --> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/> <!-- 页面描述 --> <meta name="description" content="不超过150个字符"/> <!-- 页面关键词 --> <meta name="keywords" content=""/> <!-- 网页作者 --> <meta name="author" content="name, email@gmail.com"/> <!-- 搜索引擎抓取 --> <meta name="robots" content="index,follow"/> <!-- 为移动设备添加 viewport --> <meta name="viewport" content="initial-scale=1, maximum-scale=3, minimum-scale=1, user-scalable=no"> <!-- `width=device-width` 会导致 iPhone 5 添加到主屏后以 WebApp 全屏模式打开页面时出现黑边 http://bigc.at/ios-webapp-viewport-meta.orz --> <!-- iOS 设备 begin --> <meta name="apple-mobile-web-app-title" content="标题"> <!-- 添加到主屏后的标题(iOS 6 新增) --> <meta name="apple-mobile-web-app-capable" content="yes"/> <!-- 是否启用 WebApp 全屏模式,删除苹果默认的工具栏和菜单栏 --> <meta name="apple-itunes-app" content="app-id=myAppStoreID, affiliate-data=myAffiliateData, app-argument=myURL"> <!-- 添加智能 App 广告条 Smart App Banner(iOS 6+ Safari) --> <meta name="apple-mobile-web-app-status-bar-style" content="black"/> <!-- 设置苹果工具栏颜色 --> <meta name="format-detection" content="telphone=no, email=no"/> <!-- 忽略页面中的数字识别为电话,忽略email识别 --> <!-- 启用360浏览器的极速模式(webkit) --> <meta name="renderer" content="webkit"> <!-- 避免IE使用兼容模式 --> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <!-- 针对手持设备优化,主要是针对一些老的不识别viewport的浏览器,比如黑莓 --> <meta name="HandheldFriendly" content="true"> <!-- 微软的老式浏览器 --> <meta name="MobileOptimized" content="320"> <!-- uc强制竖屏 --> <meta name="screen-orientation" content="portrait"> <!-- QQ强制竖屏 --> <meta name="x5-orientation" content="portrait"> <!-- UC强制全屏 --> <meta name="full-screen" content="yes"> <!-- QQ强制全屏 --> <meta name="x5-fullscreen" content="true"> <!-- UC应用模式 --> <meta name="browsermode" content="application"> <!-- QQ应用模式 --> <meta name="x5-page-mode" content="app"> <!-- windows phone 点击无高光 --> <meta name="msapplication-tap-highlight" content="no"> <!-- iOS 图标 begin --> <link rel="apple-touch-icon-precomposed" href="/apple-touch-icon-57x57-precomposed.png"/> <!-- iPhone 和 iTouch,默认 57x57 像素,必须有 --> <link rel="apple-touch-icon-precomposed" sizes="114x114" href="/apple-touch-icon-114x114-precomposed.png"/> <!-- Retina iPhone 和 Retina iTouch,114x114 像素,可以没有,但推荐有 --> <link rel="apple-touch-icon-precomposed" sizes="144x144" href="/apple-touch-icon-144x144-precomposed.png"/> <!-- Retina iPad,144x144 像素,可以没有,但推荐有 --> <!-- iOS 图标 end --> <!-- iOS 启动画面 begin --> <link rel="apple-touch-startup-image" sizes="768x1004" href="/splash-screen-768x1004.png"/> <!-- iPad 竖屏 768 x 1004(标准分辨率) --> <link rel="apple-touch-startup-image" sizes="1536x2008" href="/splash-screen-1536x2008.png"/> <!-- iPad 竖屏 1536x2008(Retina) --> <link rel="apple-touch-startup-image" sizes="1024x748" href="/Default-Portrait-1024x748.png"/> <!-- iPad 横屏 1024x748(标准分辨率) --> <link rel="apple-touch-startup-image" sizes="2048x1496" href="/splash-screen-2048x1496.png"/> <!-- iPad 横屏 2048x1496(Retina) --> <link rel="apple-touch-startup-image" href="/splash-screen-320x480.png"/> <!-- iPhone/iPod Touch 竖屏 320x480 (标准分辨率) --> <link rel="apple-touch-startup-image" sizes="640x960" href="/splash-screen-640x960.png"/> <!-- iPhone/iPod Touch 竖屏 640x960 (Retina) --> <link rel="apple-touch-startup-image" sizes="640x1136" href="/splash-screen-640x1136.png"/> <!-- iPhone 5/iPod Touch 5 竖屏 640x1136 (Retina) --> <!-- iOS 启动画面 end --> <!-- iOS 设备 end --> <meta name="msapplication-TileColor" content="#000"/> <!-- Windows 8 磁贴颜色 --> <meta name="msapplication-TileImage" content="icon.png"/> <!-- Windows 8 磁贴图标 --> <link rel="alternate" type="application/rss+xml" title="RSS" href="/rss.xml"/> <!-- 添加 RSS 订阅 --> <link rel="shortcut icon" type="image/ico" href="/favicon.ico"/> <!-- 添加 favicon icon --> <title>标题 ``` ## 页面切换动画 * [移动端重构系列13——页面切换](http://www.w3cplus.com/mobile/mobile-terminal-refactoring-slider.html) * [CSS3 3D Transform](http://www.w3cplus.com/css3/css3-3d-transform.html) 关于 HammerJS 的一个中文文档 * [Hammer.js](http://www.cnblogs.com/iamlilinfeng/p/4239957.html) --- ## CSS Processing > CSS语言由于其自身语言设计的问题,加上一些浏览器兼容性问题,往往会使得我们在写它的时候,要写很多冗余代码,或者为了兼容性对同一个样式设定写好几遍。针对这些问题,诞生了CSS预处理和后处理的概念及相关方法、工具。 > > 这些工具和方法帮助我们能够更加高效地书写可维护性更强的CSS代码。 这里我尝试使用了 Sass,果然很好用。下面记录几个 sass 教程。 * [Sass入门-w3cplus](http://www.w3cplus.com/sassguide/) * [SASS用法指南-阮一峰](http://www.ruanyifeng.com/blog/2012/06/sass.html) ### 安装 首先要有 ruby 环境。 由于国内网络原因(你懂的),导致 rubygems.org 存放在 Amazon S3 上面的资源文件间歇性连接失败。这时候我们可以通过gem sources命令来配置源,先移除默认的 https://rubygems.org 源,然后添加淘宝的源 https://ruby.taobao.org/,然后查看下当前使用的源是哪个,如果是淘宝的,则表示可以输入 sass 安装命令 `gem install sass` 了。 $ gem sources --remove https://rubygems.org/ $ gem sources -a https://ruby.taobao.org/ $ gem sources -l *** CURRENT SOURCES *** https://ruby.taobao.org # 请确保只有 ruby.taobao.org $ gem install sass ### 编译 sass --watch style.scss:style.css --style expanded --- ### 补充 **`rem`** 字体单位使用 rem,用户在手机上设置了字体大小时,不会打破布局,造成混乱。 * [CSS3的REM设置字体大小-w3cplus](http://www.w3cplus.com/css3/define-font-size-with-css3-rem) * [响应式十日谈第一日:使用 rem 设置文字大小-一丝](http://www.iyunlu.com/view/css-xhtml/76.html) --- ## 安全 > 安全是大家经常容易忽视,但其实一旦出现影响会非常大的问题,尤其对于没有经历过企业开发,或者没有踩过坑的同学,如果等到公司工作,做实际项目后非常容易发生安全问题。 ### 分类 WEB基本攻击大致可以分为三大类:“资源枚举”、“参数操纵” 和 “其它攻击” * 资源枚举 * 参数操纵 * SQL注入 * XPath注入 * cgi命令执行 * XXS(cross-site scripting跨域脚本攻击)其重点是“跨域”和“客户端执行” * Reflected XSS ——基于反射的XSS攻击。主要依靠站点服务端返回脚本,在客户端触发执行从而发起WEB攻击。 * DOM-based or local XSS——基于DOM或本地的XSS攻击 * Stored XSS——基于存储的XSS攻击 * 会话劫持 * 其它攻击 * CSRF(cross-site request forgery)跨站请求伪造 * 钓鱼攻击指的是网站的伪造,比如ta0bao.com,然后在其中应用XSS等方式发起攻击。 * 拒绝服务(DoS)指的是向网站发起洪水一样的请求(Traffic Floor),导致服务器超负荷并关闭,处理方法常规是采用QoS(Quality of Service)的软硬件解决方案。 ### 关于 XSS > **跨网站脚本**(Cross-site scripting,通常简称为XSS或跨站脚本或跨站脚本攻击)是一种网站应用程序的安全漏洞攻击,是代码注入的一种。它允许恶意用户将代码注入到网页上,其他用户在观看网页时就会受到影响。这类攻击通常包含了HTML以及用户端脚本语言。 > > XSS攻击通常指的是通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。这些恶意网页程序通常是JavaScript,但实际上也可以包括Java, VBScript, ActiveX, Flash 或者甚至是普通的HTML。攻击成功后,攻击者可能得到更高的权限(如执行一些操作)、私密网页内容、会话和cookie等各种内容。 > > ——维基百科 ### XSS 防护 1. 浏览器解析顺序: HTML Parser >> CSS Parser >> JavaScript Parser 2. 浏览器解码顺序: HTML Decoding >> URL Decoding >> JavaScript Decoding 3. 具体的防护方式: * 验证输入并且基于语境和按照正确的顺序转义不可信数据 * HTML 中的字符串 * HTML 属性中的字符串 * 事件句柄属性和 JavaScript 中的字符串 * HTML 属性中的 URL 路径 * HTML 风格属性和 CSS 中的字符串 * JavaScript 中的 HTML * 始终遵循白名单优于黑名单的做法 * 使用 UTF-8 为默认的字符编码以及设置 content 为 text/html * 不要将用户可以控制的文本放在标签前。通过使用不同的字符集注射可以导致 XSS。 * 使用 * 使用推荐的 HTTP 响应头进行 XSS 防护 * 防止 CRLF 注入/HTTP 响应拆分 * 禁止 TRACE 和其他非必要方法 对于 innerHTML 的方式输出的,我们可以采用如下的方式转码 ```js /** * 转码 XSS 防护 * @param {String} str 用户输入的字符串 * @return {String} 转码后的字符串 */ function changeCode(str) { str = str.replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """) .replace(/'/g, "'") .replace(/\//g, "/"); return str; } ``` --- 参考: * [浅谈WEB安全性(前端向)](http://www.cnblogs.com/vajoy/p/4176908.html) * [XSS的原理分析与解剖](http://www.freebuf.com/articles/web/40520.html) * [原创翻译:给开发者的终极XSS防护备忘录](http://www.fooying.com/chinese-translationthe-ultimate-xss-protection-cheatsheet-for-developers/) --- ## 性能优化 > 在自己做一些小项目时,可能是学校的一些网站项目,流量可能日均都不超过500,而且大多是校园局域网内访问;或者是开发一些实验室的MIS系统,这辈子你都不会去使用你开发的这个系统。在这样一些项目中,性能优化往往会被你忽略。 > > 但是如果你是做一个日均PV数万、数十万、甚至更大的量级,开发的页面会被全国各地,不同网络条件的用户来进行访问。这个时候,性能问题就无法忽视了。在当今的网络条件下,如果你的页面3秒都无法完成首屏渲染,一定会让你的网站流失很多用户。 > > 整个网站的性能优化有很多的环节和工作,大多数时候,不是前端工程师单独就能完成的,尤其在职能划分明确的公司中,往往需要前后端、运维、DBA等多个职位协同完成。所以,在我们的课程中,主要让你了解整个性能优化都涉及哪些方面的工作,同时,我们会专注介绍一些在前端领域可以重点关注的技术点。 这里就是网页的打开速度,如果你的网页打开速度很慢,那么一定会有用户的流失。所以性能优化很重要。 * 网页内容 * 减少http请求次数 * 减少DNS查询次数 * 避免页面跳转 * 缓存Ajax * 延迟加载 * 提前加载 * 减少DOM元素数量 * 根据域名划分内容 * 减少iframe数量 * 避免404 * 服务器 * 使用CDN * 添加Expires 或Cache-Control报文头 * Gzip压缩传输文件 * 配置ETags * 尽早flush输出 * 使用GET Ajax请求 * 避免空的图片src * Cookie * 减少Cookie大小 * 页面内容使用无cookie域名 * CSS * 将样式表置顶 * 避免CSS表达式 * 用\代替@import * 避免使用Filters * Javascript * 将脚本置底 * 使用外部Javascirpt和CSS文件 * 精简Javascript和CSS * 去除重复脚本 * 减少DOM访问 * 使用智能事件处理 * 图片 * 优化图像 * 优化CSS Sprite * 不要在HTML中缩放图片 * 使用小且可缓存的favicon.ico * 移动客户端 * 保持单个内容小于25KB * 打包组建成符合文档 具体细节参考文章: * [毫秒必争,前端网页性能最佳实践](http://www.cnblogs.com/developersupport/p/webpage-performance-best-practices.html) 我在 ToDo 这个任务中主要使用了 CDN 来加载静态资源。比如我使用了 [百度静态资源公共库](http://cdn.code.baidu.com/)。引用了里面的 fontawesome,速度果然比在 GitHub 仓库里快很多。下一步是压缩我自己写的静态资源。 其他参考资料: * [给网页设计师和前端开发者看的前端性能优化](http://www.oschina.net/translate/front-end-performance-for-web-designers-and-front-end-developers#section:maximising-parallelisation) * [梳理:提高前端性能方面的处理以及不足](http://www.zhangxinxu.com/wordpress/?p=3152) * [css sprite原理优缺点及使用](http://www.cnblogs.com/mofish/archive/2010/10/12/1849062.html) * [CSS Sprites:鱼翅还是三鹿?](http://www.qianduan.net/css-sprites-useful-technique-or-potential-nuisance/) * [大型网站的灵魂——性能](http://www.cnblogs.com/leefreeman/p/3998757.html) * [编写高效的 CSS 选择器](http://web.jobbole.com/35339/) --- ## 模块化 > 对于一个复杂项目,特别是多人协作的复杂项目,如何合理划分模块,如何更加方便地进行模块加载,如何管理模块之间的依赖,是一个项目团队都会面临的问题,目前业界已经有了一些较为普遍的解决方案,如AMD。这个部分希望你能够通过学习JavaScript的模块化,学习如何合理地规划项目模块,合理使用模块化工具来优化你的项目代码结构。 一个模块就是实现特定功能的文件,有了模块,我们就可以更方便地使用别人的代码,想要什么功能,就加载什么模块。模块开发需要遵循一定的规范,否则就都乱套了。 根据AMD规范,我们可以使用 `define` 定义模块,使用 `require` 调用模块。 目前,通行的 js 模块规范主要有两种:`CommonJS` 和 `AMD`。 ### AMD规范 AMD 即 Asynchronous Module Definition,中文名是“异步模块定义”的意思。它是一个在浏览器端模块化开发的规范,服务器端的规范是 CommonJS 模块将被异步加载,模块加载不影响后面语句的运行。所有依赖某些模块的语句均放置在回调函数中。 AMD 是 RequireJS 在推广过程中对模块定义的规范化的产出。 详细 API 如下: * [AMD(中文版)](https://github.com/amdjs/amdjs-api/wiki/AMD-(%E4%B8%AD%E6%96%87%E7%89%88)) --- ### CommonJS规范 CommonJS 是服务器端模块的规范,Node.js 采用了这个规范。Node.JS 首先采用了 js 模块化的概念。 根据 CommonJS 规范,一个单独的文件就是一个模块。每一个模块都是一个单独的作用域,也就是说,在该模块内部定义的变量,无法被其他模块读取,除非定义为 global 对象的属性。 输出模块变量的最好方法是使用 module.exports 对象。 --- ### 为什么要用 requireJS 试想一下,如果一个网页有很多的js文件,那么浏览器在下载该页面的时候会先加载js文件,从而停止了网页的渲染,如果文件越多,浏览器可能失去响应。其次,要保证js文件的依赖性,依赖性最大的模块(文件)要放在最后加载,当依赖关系很复杂的时候,代码的编写和维护都会变得困难。 RequireJS就是为了解决这两个问题而诞生的: > (1)实现js文件的异步加载,避免网页失去响应; > (2)管理模块之间的依赖性,便于代码的编写和维护。 #### requireJS * [requireJS 官网](http://requirejs.org/) * [requireJS 中文网](http://www.requirejs.cn/) --- ### AMD和CMD CMD(Common Module Definition) 通用模块定义。该规范明确了模块的基本书写格式和基本交互规则。该规范是在国内发展出来的。AMD是依赖关系前置,CMD是按需加载。 > AMD 是 RequireJS 在推广过程中对模块定义的规范化产出。 > CMD 是 SeaJS 在推广过程中对模块定义的规范化产出。 * [CMD 模块定义规范](https://github.com/seajs/seajs/issues/242) 对于依赖的模块,AMD 是提前执行,CMD 是延迟执行。 > AMD:提前执行(异步加载:依赖先执行)+延迟执行 > CMD:延迟执行(运行到需加载,根据顺序执行) --- ### 参考 * [Javascript模块化编程(一):模块的写法--阮一峰](http://www.ruanyifeng.com/blog/2012/10/javascript_module.html) * [Javascript模块化编程(二):AMD规范](http://www.ruanyifeng.com/blog/2012/10/asynchronous_module_definition.html) * [Javascript模块化编程(三):require.js的用法](http://www.ruanyifeng.com/blog/2012/11/require_js.html) * [详解 JavaScript 模块开发](http://segmentfault.com/a/1190000000733959) * [浅谈模块化的JavaScript](http://www.cnblogs.com/jinguangguo/archive/2013/04/06/3002515.html?utm_source=tuicool) * [再谈 SeaJS 与 RequireJS 的差异](http://div.io/topic/430) * 玩转AMD系列 by erik@EFE * [玩转AMD - 写在前面](http://efe.baidu.com/blog/dissecting-amd-preface/) * [玩转AMD - 设计思路](http://efe.baidu.com/blog/dissecting-amd-what/) * [玩转AMD - 应用实践](http://efe.baidu.com/blog/dissecting-amd-how/) * [玩转AMD - Loader](http://efe.baidu.com/blog/dissecting-amd-loader/) --- ## 前端工程化 > 业界目前有非常多的前端开发工具,完成一些开发过程中可以自动化完成的工作,提高研发效率,并且可以提高多人协作时的开发过程一致性,提高整个项目的运维效率。 > > 在EFE日常工作中,我们是基于EDP,完成项目开发过程中的项目构建、包管理、调试、单测、静态检测、打包、压缩、优化、项目部署等一系列所有工作。 注: 如果网络不好,可以使用 [淘宝 NPM 镜像](http://npm.taobao.org/)。 ### 参考 * [前端工程与模块化框架](http://div.io/topic/439) * [手机百度前端工程化之路](http://mweb.baidu.com/p/baidusearch-front-end-road.html) * [对话百度前端工程师张云龙:F.I.S与前端工业化](http://www.infoq.com/cn/articles/yunlong-on-fis) * [EDP](https://github.com/ecomfe/edp) * [Grunt教程——初涉Grunt](http://www.w3cplus.com/tools/grunt-tutorial-start-grunt.html) * [gulp入门指南](http://www.open-open.com/lib/view/open1417068223049.html) * [Gulp开发教程(翻译)](http://www.w3ctech.com/topic/134) * [Gulp 中文网](http://www.gulpjs.com.cn/) * [npm的package.json中文文档](https://github.com/ericdum/mujiang.info/issues/6) --- ## 最终作品 在任务三中,做了一个 PC 端的 ToDo 应用。任务四是将它优化,以适应移动端设备。 ### ToDo WebApp Version * [任务四要求](https://github.com/baidu-ife/ife/tree/master/task/task0004) * [源代码](https://github.com/Gaohaoyang/ToDo-WebApp) * [在线 demo](http://gaohaoyang.github.io/ToDo-WebApp/) * 手机查看 ↓ 二维码 ↓ ![todoWebApp](http://7q5cdt.com1.z0.glb.clouddn.com/task4-code-todoWebApp.png) * [我的博客 HyG](http://gaohaoyang.github.io) ### Details * **数据存储** 以 JSON 模拟数据表的形式存储于 LocalStorage 中 使用数据库的思想,构建3张表。 cateJson 分类 childCateJson 子分类 taskJson 任务 分类表 cate ---------------------- id* | name | child(FK) ---------------------- 子分类表 childCate -------------------------------- id* | pid(FK) | name | child(FK) -------------------------------- 任务表 task ---------------------------------------------- id* | pid(FK) | finish | name | date | content ---------------------------------------------- * **使用 `Sass` 重构了 CSS 代码** 使用分块、继承等方式,使得代码更加清晰明了。 * **响应式布局** 针对手机端细节做了很多调整,更符合手机上的视觉交互习惯。 * **加入页面切换效果** 使用 `translate3d()`,纯 CSS3 切换动画效果。 * **处理了 XSS 防护** 对可能造成破坏的字符进行转码。 * **性能优化** 使用 CDN 处理静态资源 fontAwesome,压缩静态资源等 * **模块化** 使用 requireJS 模块化 JavaScript 代码。重构 JavaScript 代码。优化之前写的耦合性高的绑定事件,重新绑定事件,降低耦合性。期间根据具体需求重写了事件代理的代码。 * **前端工程化** 使用 gulp,自动编译 Sass,压缩 CSS 和 JavaScript 代码。并且配置了自动流程。 --- ## 其他 ### `-webkit-tap-highlight-color` 属性 感谢 [fiona](https://github.com/fiona23) 指出。 safari移动端点击的时候会闪一下加上 `-webkit-tap-highlight-color: transparent;` 就不会闪了。 参考: * [`-webkit-tap-highlight-color` css88](http://www.css88.com/webkit/-webkit-tap-highlight-color/) * [`-webkit-tap-highlight-color` 属性](http://ued.ctrip.com/webkitcss/prop/tap-highlight-color.html) --- ### textarea 标签 disabled 颜色 * 为什么用 disabled 属性? 因为我发现仅仅使用 readonly 属性,在 IE 下是显示光标的。于是使用 disabled。 * 出现的问题 各家浏览器对于 disabled 属性有自己的样式设定,比如 IE 下是灰色的。苹果设备下也是。改变这些样式的方法也不是统一的。如果要兼容 Safari 必须加上 ``` background: #fff; -webkit-text-fill-color: rgba(0, 0, 0, 1); -webkit-opacity: 1; ``` 于是最终代码如下: ```css textarea:disabled { color:#000; background: #fff; -webkit-text-fill-color: rgba(0, 0, 0, 1); -webkit-opacity: 1; } ``` * 参考:[Disabled input text color 中的评论](http://stackoverflow.com/a/4648315)