概念 head 标签 页面切换动画 CSS Processing 安装 编译 补充 安全 分类 关于 XSS XSS 防护 性能优化 模块化 AMD规范 CommonJS规范 为什么要用 requireJS requireJS AMD和CMD 参考 前端工程化 参考 最终作品 ToDo WebApp Version Details 其他 -webkit-tap-highlight-color 属性 textarea 标签 disabled 颜色 往前推2到3年,前端工程师还在忧心忡忡地想,移动互联网时代下,前端是不是没有生存空间了。但今天一看,在我们团队,前端工程师超过一半的工作都是在做移动端的Web或者APP的开发。移动Web或者APP在技术本质上是和做桌面端Web没有本质区别,但是移动端的坑那是非常的多,通过学习这部分内容,让你成为一名桌面移动通吃的前端开发工程师。 概念 参考: 移动 Web 开发入门 上面这个 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 调试工具 head 标签 参考: 移动前端不得不了解的html5 head 头标签 上面的链接详细的讲解了: DOCTYPE charset lang属性 优先使用 IE 最新版本和 Chrome 360 使用Google Chrome Frame SEO 优化部分:页面标题标签(head 头部必须),页面关键词 keywords,页面描述内容 description,定义网页作者 author,网页搜索引擎索引方式 为移动设备添加 viewport 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 --> content 参数: width viewport 宽度(数值/device-width) height viewport 高度(数值/device-height) initial-scale 初始缩放比例 maximum-scale 最大缩放比例 minimum-scale 最小缩放比例 user-scalable 是否允许用户缩放(yes/no) ios 设备,iOS 图标,Android,Windows 8 总结: <!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>标题</title> </head> <body> </body> </html> 页面切换动画 移动端重构系列13——页面切换 CSS3 3D Transform 关于 HammerJS 的一个中文文档 Hammer.js CSS Processing CSS语言由于其自身语言设计的问题,加上一些浏览器兼容性问题,往往会使得我们在写它的时候,要写很多冗余代码,或者为了兼容性对同一个样式设定写好几遍。针对这些问题,诞生了CSS预处理和后处理的概念及相关方法、工具。 这些工具和方法帮助我们能够更加高效地书写可维护性更强的CSS代码。 这里我尝试使用了 Sass,果然很好用。下面记录几个 sass 教程。 Sass入门-w3cplus SASS用法指南-阮一峰 安装 首先要有 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 响应式十日谈第一日:使用 rem 设置文字大小-一丝 安全 安全是大家经常容易忽视,但其实一旦出现影响会非常大的问题,尤其对于没有经历过企业开发,或者没有踩过坑的同学,如果等到公司工作,做实际项目后非常容易发生安全问题。 分类 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 防护 浏览器解析顺序: HTML Parser » CSS Parser » JavaScript Parser 浏览器解码顺序: HTML Decoding » URL Decoding » JavaScript Decoding 具体的防护方式: 验证输入并且基于语境和按照正确的顺序转义不可信数据 HTML 中的字符串 HTML 属性中的字符串 事件句柄属性和 JavaScript 中的字符串 HTML 属性中的 URL 路径 HTML 风格属性和 CSS 中的字符串 JavaScript 中的 HTML 始终遵循白名单优于黑名单的做法 使用 UTF-8 为默认的字符编码以及设置 content 为 text/html 不要将用户可以控制的文本放在标签前。通过使用不同的字符集注射可以导致 XSS。 使用 <!DOCTYPE html> 使用推荐的 HTTP 响应头进行 XSS 防护 防止 CRLF 注入/HTTP 响应拆分 禁止 TRACE 和其他非必要方法 对于 innerHTML 的方式输出的,我们可以采用如下的方式转码 /** * 转码 XSS 防护 * @param {String} str 用户输入的字符串 * @return {String} 转码后的字符串 */ function changeCode(str) { str = str.replace(/&/g, "&") .replace(/</g, "<") .replace(/>/g, ">") .replace(/"/g, """) .replace(/'/g, "'") .replace(/\//g, "/"); return str; } 参考: 浅谈WEB安全性(前端向) XSS的原理分析与解剖 原创翻译:给开发者的终极XSS防护备忘录 性能优化 在自己做一些小项目时,可能是学校的一些网站项目,流量可能日均都不超过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表达式 用<link>代替@import 避免使用Filters Javascript 将脚本置底 使用外部Javascirpt和CSS文件 精简Javascript和CSS 去除重复脚本 减少DOM访问 使用智能事件处理 图片 优化图像 优化CSS Sprite 不要在HTML中缩放图片 使用小且可缓存的favicon.ico 移动客户端 保持单个内容小于25KB 打包组建成符合文档 具体细节参考文章: 毫秒必争,前端网页性能最佳实践 我在 ToDo 这个任务中主要使用了 CDN 来加载静态资源。比如我使用了 百度静态资源公共库。引用了里面的 fontawesome,速度果然比在 GitHub 仓库里快很多。下一步是压缩我自己写的静态资源。 其他参考资料: 给网页设计师和前端开发者看的前端性能优化 梳理:提高前端性能方面的处理以及不足 css sprite原理优缺点及使用 CSS Sprites:鱼翅还是三鹿? 大型网站的灵魂——性能 编写高效的 CSS 选择器 模块化 对于一个复杂项目,特别是多人协作的复杂项目,如何合理划分模块,如何更加方便地进行模块加载,如何管理模块之间的依赖,是一个项目团队都会面临的问题,目前业界已经有了一些较为普遍的解决方案,如AMD。这个部分希望你能够通过学习JavaScript的模块化,学习如何合理地规划项目模块,合理使用模块化工具来优化你的项目代码结构。 一个模块就是实现特定功能的文件,有了模块,我们就可以更方便地使用别人的代码,想要什么功能,就加载什么模块。模块开发需要遵循一定的规范,否则就都乱套了。 根据AMD规范,我们可以使用 define 定义模块,使用 require 调用模块。 目前,通行的 js 模块规范主要有两种:CommonJS 和 AMD。 AMD规范 AMD 即 Asynchronous Module Definition,中文名是“异步模块定义”的意思。它是一个在浏览器端模块化开发的规范,服务器端的规范是 CommonJS 模块将被异步加载,模块加载不影响后面语句的运行。所有依赖某些模块的语句均放置在回调函数中。 AMD 是 RequireJS 在推广过程中对模块定义的规范化的产出。 详细 API 如下: AMD(中文版) CommonJS规范 CommonJS 是服务器端模块的规范,Node.js 采用了这个规范。Node.JS 首先采用了 js 模块化的概念。 根据 CommonJS 规范,一个单独的文件就是一个模块。每一个模块都是一个单独的作用域,也就是说,在该模块内部定义的变量,无法被其他模块读取,除非定义为 global 对象的属性。 输出模块变量的最好方法是使用 module.exports 对象。 为什么要用 requireJS 试想一下,如果一个网页有很多的js文件,那么浏览器在下载该页面的时候会先加载js文件,从而停止了网页的渲染,如果文件越多,浏览器可能失去响应。其次,要保证js文件的依赖性,依赖性最大的模块(文件)要放在最后加载,当依赖关系很复杂的时候,代码的编写和维护都会变得困难。 RequireJS就是为了解决这两个问题而诞生的: (1)实现js文件的异步加载,避免网页失去响应; (2)管理模块之间的依赖性,便于代码的编写和维护。 requireJS requireJS 官网 requireJS 中文网 AMD和CMD CMD(Common Module Definition) 通用模块定义。该规范明确了模块的基本书写格式和基本交互规则。该规范是在国内发展出来的。AMD是依赖关系前置,CMD是按需加载。 AMD 是 RequireJS 在推广过程中对模块定义的规范化产出。 CMD 是 SeaJS 在推广过程中对模块定义的规范化产出。 CMD 模块定义规范 对于依赖的模块,AMD 是提前执行,CMD 是延迟执行。 AMD:提前执行(异步加载:依赖先执行)+延迟执行 CMD:延迟执行(运行到需加载,根据顺序执行) 参考 Javascript模块化编程(一):模块的写法–阮一峰 Javascript模块化编程(二):AMD规范 Javascript模块化编程(三):require.js的用法 详解 JavaScript 模块开发 浅谈模块化的JavaScript 再谈 SeaJS 与 RequireJS 的差异 玩转AMD系列 by erik@EFE 玩转AMD - 写在前面 玩转AMD - 设计思路 玩转AMD - 应用实践 玩转AMD - Loader 前端工程化 业界目前有非常多的前端开发工具,完成一些开发过程中可以自动化完成的工作,提高研发效率,并且可以提高多人协作时的开发过程一致性,提高整个项目的运维效率。 在EFE日常工作中,我们是基于EDP,完成项目开发过程中的项目构建、包管理、调试、单测、静态检测、打包、压缩、优化、项目部署等一系列所有工作。 注: 如果网络不好,可以使用 淘宝 NPM 镜像。 参考 前端工程与模块化框架 手机百度前端工程化之路 对话百度前端工程师张云龙:F.I.S与前端工业化 EDP Grunt教程——初涉Grunt gulp入门指南 Gulp开发教程(翻译) Gulp 中文网 npm的package.json中文文档 最终作品 在任务三中,做了一个 PC 端的 ToDo 应用。任务四是将它优化,以适应移动端设备。 ToDo WebApp Version 任务四要求 源代码 在线 demo 手机查看 ↓ 二维码 ↓ 我的博客 HyG 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 指出。 safari移动端点击的时候会闪一下加上 -webkit-tap-highlight-color: transparent; 就不会闪了。 参考: -webkit-tap-highlight-color css88 -webkit-tap-highlight-color 属性 textarea 标签 disabled 颜色 为什么用 disabled 属性? 因为我发现仅仅使用 readonly 属性,在 IE 下是显示光标的。于是使用 disabled。 出现的问题 各家浏览器对于 disabled 属性有自己的样式设定,比如 IE 下是灰色的。苹果设备下也是。改变这些样式的方法也不是统一的。如果要兼容 Safari 必须加上 background: #fff; -webkit-text-fill-color: rgba(0, 0, 0, 1); -webkit-opacity: 1; 于是最终代码如下: textarea:disabled { color:#000; background: #fff; -webkit-text-fill-color: rgba(0, 0, 0, 1); -webkit-opacity: 1; } 参考:Disabled input text color 中的评论