一、HTML5
第1章 前言
1.1 认识HTML5
HTML5并不仅仅只是做为HTML标记语言的一个最新版本,更重要的是它制定了Web应用开发的一系列标准,成为第一个将Web做为应用开发平台的HTML语言。
HTML5定义了一系列新元素,如新语义标签、智能表单、多媒体标签等,可以帮助开发者创建富互联网应用,还提供了一些Javascript API,如地理定位、重力感应、硬件访问等,可以在浏览器内实现类原生应用,甚至结合Canvas我们可开发网页版游戏。
我们日常讨论的H5其实指的是一个范称,它是由HTML5 + CSS3 + Javascript等技术组合而成的一个应用开发平台。
1.2 语法规范
随着Web技术的更新,HTML也先后经历了HTML 4.01、XHTML 1.0、HTML5几个重要的版本,在版本的演变过程中新增或废弃了一些属性,同时对语法规范也做了一些调整。
1.2.1 html4
html4 严格模式 emmet语法 html:4s
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>Document</title>
</head>
<body>
<!--这是html4的严格模式的html骨架-->
<!--DOCTYPE 引入的严格模式的dtd规范 strict.dtd-->
</body>
</html>
html4 宽松模式 过渡时期
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title></title>
</head>
<body>
<!--这是html4的宽松模式并且是过渡时期的html骨架-->
<!--DOCTYPE 引入的严格模式的dtd规范 strict.dtd 并且是transtional 过渡时期-->
</body>
</html>
1.2.2 xhtml
xhtml 4.01升级版 emmet语法 html:xt
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>Document</title>
</head>
<body>
<!--这是xhtml过渡时期的html骨架(语法更严谨,是4.01的升级版)-->
<!--DOCTYPE 引入的xhtml过渡模式的dtd规范 xhtml1-transitional.dtd 并且是transtional 过渡时期-->
</body>
</html>
1.2.3 html5
为了能够保证浏览器可以兼容不同版本语法规范的,我们可以使用<!DOCTYPE>指示浏览器应该如何处理。
HTML5在语法规范上也做了比较大的调整,去除了许多冗余的内容,书写规则更加简洁、清晰。
html5 emmet语法 html:5 或者 !
<!--html doctype 申明规范-->
<!DOCTYPE html>
<html>
<!--声明当前页面的语言环境是英文-->
<head lang="en">
<!--声明当前页面的编码环境是utf-8-->
<meta charset="UTF-8">
<title></title>
</head>
<body>
<!--html5 特点:
1、更简介
2、更宽松
注意:在实际开发当中一定要遵守书写规范,养成良好的编码习惯。
-->
</body>
</html>
W3C验证地址
https://validator.w3.org/
第2章 语义标签
语义标签对于我们并不陌生,如<p>表示一个段落、<ul>表示一个无序列表<h1> ~ <h6>表示一系列标题等,在此基础上HTML5增加了大量更有意义的语义标签,更有利于搜索引擎或辅助设备来理解HTML页面内容。
传统的做法我们或许通过增加类名如class="header"、class="footer",使HTML页面具有语义性,但是不具有通用性。
HTML5则是通过新增语义标签的形式来解决这个问题,例如<header></header>、<footer></footer>等,这样就可以使其具有通用性。
此章节学习目的为了解增加语义标签的目的,以及各语义标签所表达的意义,在网页布局中能够合理使用标签。
2.1 常用新语义标签
本质上新语义标签与<div>、<span>没有区别,只是其具有表意性
使用时除了在HTML结构上需要注意外,其它和普通标签的使用无任何差别,可以理解成<div class="nav"> 相当于 <nav>。
不要好奇,它只是一个标签!
尽量避免全局使用header、footer、aside等语义标签。
2.1.1 结构标签
<article> 标记定义一篇文章
<header> 标记定义一个页面或一个区域的头部
<nav> 标记定义导航链接
<section> 标记定义一个区域
<aside> 标记定义页面内容部分的侧边栏
<hgroup> 标记定义文件中一个区块的相关信息
<figure> 标记定义一组媒体内容以及它们的标题
<figcaption> 标签定义 figure 元素的标题。
<footer> 标记定义一个页面或一个区域的底部
<dialog> 标记定义一个对话框(会话框)类似微信
2.1.2 多媒体交互标签
<video> 标记定义一个视频
<audio> 标记定义音频内容
<source> 标记定义媒体资源
<canvas> 标记定义图片
<embed> 标记定义外部的可交互的内容或插件 比如flash
2.1.3 Web应用标签
<command> menu标记定义一个命令按钮
<meter> 状态标签(实时状态显示:气压、气*)C、O
<progress> 状态标签 (任务过程:安装、加载) C、F、O
<datalist> 为input标记定义一个下拉列表,配合option F、O
<details> 标记定义一个元素的详细内容 ,配合dt、dd C
2.1.4 注释标签
<ruby> 标记定义 注释或音标
<rp> 告诉那些不支持 Ruby元素的浏览器如何去显示
<rt> 标记定义对ruby的注释内容文本
2.2 兼容处理
在不支持HTML5新标签的浏览器里,会将这些新的标签解析成行内元素(inline)对待,所以我们只需要将其转换成块元素(block)即可使用,但是在IE9版本以下,并不能正常解析这些新标签,但是却可以识别通过document.createElement(\'tagName\')创建的自定义标签,于是我们的解决方案就是将HTML5的新标签全部通过document.createElement(\'tagName\')来创建一遍,这样IE低版本也能正常解析HTML5新标签了,在实际开发中我们更多采用的是通过检测IE浏览器的版本来加载第三方的一个JS库来解决兼容问题。
第三方的js库:html5shiv.js
怎么使用:在html文档头部加入这个第三方的插件的js库就可以,但是要注意的是只在IE9一下才使用。
条件注释:<!--[if lt IE 9]> <![endif]--> 条件判断有 (lt lte gt gte)
<!--[if lt IE 9]>
<script src="js/html5shiv.min.js" ></script>
<![endif]-->
2.3 案例练习
博客文章:
<body>
<!-- 顶部导航 -->
<div class="topnav">
<dl class="wrap">
<dt>次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^</dt>
<dd>
<a href="javascript:;" class="rss"></a>
<a href="javascript:;" class="share"></a>
<a href="javascript:;" class="setting"></a>
<a href="javascript:;" class="network"></a>
</dd>
</dl>
</div>
<!-- 头部 -->
<header>
<div class="wrap">
<h2 class="logo">
<a href="javascript:;">Web技术研究所</a>
<small>我一直坚信着,Web将会成为未来应用程序的主流</small>
</h2>
<!-- 导航 -->
<nav>
<a href="javascript:;" class="active">网站首页</a>
<a href="javascript:;">文章一览</a>
<a href="javascript:;">系列专题</a>
<a href="javascript:;">神奇海螺</a>
<a href="javascript:;">次炭酸钴</a>
</nav>
</div>
</header>
<!-- 主体 -->
<div class="main wrap">
<!-- 侧边栏 -->
<aside>
<!-- 搜索框 -->
<section class="search">
<a href="javascript:;">搜</a>
<input type="search" placeholder="请输入搜索内容">
</section>
<section class="theme">
<header>神奇海螺</header>
</section>
<!-- 评论 -->
<section class="article_list">
<header>相关文章</header>
<ul>
<li><a href="javascript:;">关于运营商链路劫持</a></li>
<li><a href="javascript:;">局部 HTTPS 的安全隐患</a></li>
<li><a href="javascript:;">localStorage 跨 scheme 的坑</a></li>
<li><a href="javascript:;">predeclare.js</a></li>
<li><a href="javascript:;">HSTS 与 307 状态码</a></li>
<li><a href="javascript:;">字符串模板与正则</a></li>
<li><a href="javascript:;">关于 DNS 劫持</a></li>
<li><a href="javascript:;">JSON Stream</a></li>
<li><a href="javascript:;">火狐7开始就支持ellipsis了</a></li>
<li><a href="javascript:;">剪不断理还乱的规范</a></li>
</ul>
</section>
</aside>
<!-- 文章 -->
<div class="article">
<article>
<h4 class="title">https 并没有解决劫持的问题</h4>
<p>每次一提到防劫持,大*给出的终极方案总是 https。但是 https 真的可以完美解决运营商劫持的问题么?也许从安全的角度考虑,https 确实是最佳解决方案。但是从产品角度从用户体验上来考虑呢?使用 https 不但没有解决问题,甚至会变得比从前的 http 更糟糕。</p>
<p>自从某项目上了 https 后老有用户反馈说页面打不开。以前使用 http 的时候虽然有劫持,偶尔还会被插入一些恶心的广告,但页面总是可以打开,功能可以正常使用。现在上了 https 反而各种白屏,各种连接建立失败。虽然广告看不见了,但连功能也无法使用了。</p>
<p>很多时候网页上并不存在敏感信息,传输没有安全的必要,产品设计上只是为了让用户看到这个页面,所以即使被插入广告也比白屏好。对于这类页面,使用 https 可能适得其反。</p>
<p>但是即便是纯展示的页面也是有安全风险的。比如一个宣传页,如果使用 http,攻击者可以篡改页面上的二维码或下载链接,让用户下载到奇奇怪怪的东西,或者链进一个钓鱼网页。虽然比起 SessionID 泄露之类的风险要低得多,但这依然是一种风险。</p>
<p>Web 页面的运营商劫持问题目前就技术层面我也没想到什么解决方案,如果大*有什么方案可以一起聊一聊。但如果是 App 内部就可以解决。因为我们可以基于传输层协议自己封装一个运营商不知道的域名解析协议,并且自己搭建相应的 DNS 服务器。只要不是被针对性地攻击就可以免受劫持。</p>
<p>另外,比起白屏和被植入广告,我更愿意选择白屏(虽然产品经理不会这么想)。但是作为 Web 开发者,推进全面 https 才是我们该做的。如果全世界都 https 了,运营商自然也就不会去做劫持这种费力不讨好的事情。</p>
</article>
<div class="widget">
<a href="javascript:;" class=\'time\'>
<b>2015</b>
<br>
12 24
</a>
<a href="javascript:;" class="discuss">
<b>分享</b>
<br>
<span>+</span>
</a>
<a href="javascript:;" class="prev">
<b>上一篇</b>
<br>
<span>Newer</span>
</a>
<a href="javascript:;" class="next">
<b>下一篇</b>
<br>
<span>Older</span>
</a>
</div>
</div>
</div>
<!-- 底部 -->
<footer>
<p>Copyright ©2012-2016 次碳酸钴 All rights reserved</p>
</footer>
</body>
第3章 表单
伴随着互联网富应用以及移动开发的兴起,传统的Web表单已经越来越不能满足开发的需求,所以HTML5在Web表单方向也做了很大的改进,如拾色器、日期/时间组件等,使表单处理更加高效。
此章节学习目的,了解HTML5表单的新增的特性,以及PC和移动设备间的差异,其兼容性较差。
3.1 新增表单类型 type
email 限定输入内容为邮箱地址,表单提交时会校验格式
tel 手机号码
url 限定输入内容为URL,表单提交时会校验格式
number 限定输入内容为数字,表单提交时会校验格式 step 步数
search 搜索域,语义化,表示定义搜索框
range 数值范围选择器
color 拾色器
time 时间
date 日期时间选择器
样式不能修改,移动端用的比较多,因为移动端显示的是系统的时间或日期选择器
date - 选取日、月、年
month - 选取月、年
week - 选取周和年
time - 选取时间(小时和分钟)
datetime - 选取时间、日、月、年,浏览器兼容性不好,效果等同于datetime-local
datetime-local - 选取本地时间、日、月、年
部分类型是针对移动设备生效的,且具有一定的兼容性,在实际应用当中可选择性的使用。
3.2 表单元素(标签)
<datalist> 下拉选项,使用中文时要注意
<keygen> 生成加密字符串
<output> 不可当做数据提交
<meter> 表示度量器,不建议用作进度条
3.3 新增表单属性
3.3.1 form
autocomplete 设置整个表单是否开启自动完成 on|off
novalidate 设置H5的表单校验是否工作 true 不工作 不加该属性代表校验
3.3.1 input
autocomplete 单独设置每个文本框的自动完成
autofocus 设置当前文本域页面加载完了过后自动得到焦点
form 属性是让表单外的表单元素也可以跟随表单一起提交
form overrides
formaction 在submit上重写表单的特定属性,当点击当前submit时会以当前值使用
formenctype,
formmethod,
formnovalidate,
formtarget
list 作用就是指定当前文本框的自动完成列表的数据 datalist 在界面上是看不见的,只是用于定义数据列表的
min / max / step
min max 限制值的范围,但是不会再输入时限制,提交时校验,
step设置的是每次加减的增量
主要使用在number range datepicker上
multiple
文本域的多选
pattern
设置文本框的匹配格式(正则)
placeholder
文本框占位符
required
限制当前input为必须的
3.4 表单事件
oninput 用户输入内容时触发,可用于移动端输入字数统计
oninvalid 验证不通过时触发
setCustomValidity 设置自定义提示
3.5 案例练习
学生档案:
<form action="">
<fieldset>
<legend>学生档案</legend>
<label>
姓名: <input type="text" pattern="{6,10}" name="username" placeholder="请输入姓名" id="username" required autofocus >
</label>
<label>
手机号码: <input type="text" name="mobile" placeholder="请输入手机号" required pattern="^1\d{10}$" >
</label>
<label>
邮箱地址: <input type="email" name="email" placeholder="请输入邮箱地址" required >
</label>
<label>
所属学院: <input type="text" name="course" list="course" placeholder="请输入所属学院" >
<datalist id="course">
<option value="前端与移动开发"></option>
<option value="PHP"></option>
<option value="JAVA"></option>
<option value="Android"></option>
<option value="IOS"></option>
<option value="UI设计"></option>
<option value="C++"></option>
</datalist>
</label>
<label>
入学成绩: <input id="score" name="score" type="number" min="0" max="100" step="10" value="60"/>
</label>
<label>
基础水平: <meter id="level" name="level" min="0" max="100" low="40" high="80" value="60"></meter>
</label>
<label>
入学日期: <input type="date" value="2016-07-03">
</label>
<label>
毕业时间: <input type="date" value="2016-11-03">
</label>
<label>
课程进度: <progress max="100" value="30"></progress>
</label>
<input type="submit" value="保存"/>
</fieldset>
</form>
<script>
/*name 是一个关键字 event 尽快能的不使用*/
/*获取到姓名元素*/
var username = document.getElementById("username");
/*个这个元素绑定一个事件 监听元素值不符合要求才触发*/
username.onblur = function(){
this.setCustomValidity(\'\');
};
/*如果有提示内容 也会触发这个事件*/
username.oninvalid = function(){
console.log(\'oninvalid\');
/*自定义提示*/
this.setCustomValidity(\'请输入姓名!\');
/* 1 没有提示 2 数据正确*/
};
/*动态的展示入学成绩的水平*/
/*获取到入学成绩这个元素*/
var scoreInput = document.getElementById(\'score\');
/*水平元素*/
var levelMeter = document.getElementById(\'level\');
/*监听score的值的改变*/
scoreInput.oninput = function(){
/*this 指向的是当前的元素*/
console.log(this.value);
/*怎么样让水平状态改变*/
levelMeter.value = this.value;
}
</script>
第4章 网页多媒体
在HTML5之前,在网页上播放音频/视频的通用方法是利用Flash来播放,但是大多情况下,并非所有用户的浏览器都安装了Flash插件,由此使得处理音频/视频播放变的非常复杂,并且移动设备的浏览器并不支持Flash插件。
此章节学习目的,了解如何通过HTML5播放音频/视频,以及针对不同浏览器所支持的格式,做多浏览器兼容处理。
4.1 音频
HTML5通过<audio>标签来解决音频播放的问题。
定义音频播放组件
<audio src="要播放的音频文件"></audio>
并且可以通过附加属性可以更友好控制音频的播放,如:
autoplay 自动播放
controls 决定是否显示控制菜单
loop 循环播放
preload 预加载 是否在页面加载完成并且没有开始播放时就开始加载文件,如果有自动播放属性则该属性无意义
height/width 定义播放器的宽高,只会在视频标签中生效
由于版权等原因,不同的浏览器可支持播放的格式是不一样的
多浏览器支持的方案,如下图
4.2 视频
HTML5通过<video>标签来解决音频播放的问题。
定义播放视频组件:
<video src="要播放的视频文件"></video>
自定义播放器外观:
隐藏原生的控制菜单,也就是删除标签中的controls属性
自己设计一套界面控制元素,比如播放按钮,音量控制开关之类
为每个不同的控制元素注册对应的事件
在事件中通过视频元素的API实现自定义播放器的效果
同样,通过附加属性可以更友好的控制视频的播放
方法:
事件:
由于版权等原因,不同的浏览器可支持播放的格式是不一样的
video.js 第三方的视频插件
旧版本浏览器提示
如果HTML中遇到不能识别的标签,就会将该标签当做DIV(块级元素)
那么video中的innerHTML也就会直接显示在界面上
利用这个特点我们可以实现不支持video标签的浏览器提示
<video src="demo.mp4">
<!-- 如果浏览器不识别video标签,以下内容可以直接显示在浏览器上 -->
<p>抱歉,您的浏览器不支持视频播放!</p>
</video>
多浏览器支持的方案,
每个浏览器的音视频格式支持不同(版权问题)
需要兼容更多的浏览器,可以通过定义多个`<source>`的方式实现
html解析过程中会找其中第一个能认识的格式播放,一旦找到认识的视频格式,就不会再往后找了
因此不管是audio还是video都不要直接设置标签的src
如下所示:
<video controls width="500">
<!-- 分析第一个source格式是否支持,如果支持则加载该文件,不支持继续往下解析 -->
<source src="chrome.mp4">
<source src="chrome.ogv">
<source src="chrome.webm">
<p>抱歉,您的浏览器不支持视频播放!</p>
</video>
第5章 微数据
1、微数据
http://kayosite.com/html5-microdata.html
可以理解成新语义标签的一种补充
2、ARIA
http://www.zhangxinxu.com/wordpress/2012/03/wai-aria-%E6%97%A0%E9%9A%9C%E7%A2%8D%E9%98%85%E8%AF%BB/#ariaRole
第6章 DOM扩展
6.1 获取元素
1、document.getElementsByClassName (\'class\') 通过类名获取元素,以类数组形式存在。
2、document.querySelector(\'selector\') 通过CSS选择器获取元素,符合匹配条件的第1个元素。
3、document.querySelectorAll(\'selector\') 通过CSS选择器获取元素,以类数组形式存在。
6.2 类名操作
1、Node.classList.add(\'class\') 添加class
2、Node.classList.remove(\'class\') 移除class
3、Node.classList.toggle(\'class\') 切换class,有则移除,无则添加
4、Node.classList.contains(\'class\') 检测是否存在class
Node指一个有效的DOM节点,是一个通称。
eg:
classList 把当前元素上的所有类组合成一个数组
classList.contains("active") 匹配当前元素有没有"active"这个类
classList.remove("active") 删除当前元素的"active"类
classList.add("active") 给当前元素添加"active"类
classList.toggle("active") 切换"active"类 有就删除 没有就添加
6.3 自定义属性
在HTML5中我们可以自定义属性,data-开始的属性,都认作是自定义属性。其格式如下data-*="",eg:data-info="我是自定义属性",
dataset 存储的是当前元素的所有自定义属性 以键值的方式存在
dataset 自定义属性的取值和设置 都是按名字来的
①不包含data-
②在有-的情况下会转化成驼峰命名法
dataset是以对象形式存在的
/*获取属性*/
console.log(nav.dataset);//DOMStringMap {name: "nav", userName: "tab"}
console.log(nav.dataset["name"]);//nav
console.log(nav.dataset["userName"]);//tab
/*dataset 设置属性 会操作dom属性*/
/*jQuery data 设置属性 数据存储在内存中 不会操作dom属性*/
nav.dataset["userName"] = "xiao";
console.log(nav.dataset["userName"]);//xiao
6.4 案例练习
tab切换:
<div class="tabs">
<nav>
<a href="javascript:;" data-count="local">国内新闻</a>
<a href="javascript:;" data-count="global">国际新闻</a>
<a href="javascript:;" data-count="sports">体育新闻</a>
<a href="javascript:;" data-count="funny">娱乐新闻</a>
</nav>
<section class="cont" id="local">
<ol>
<li>河感在生矿难,死伤在全10</li>
<li>禽流感在感在广1处继续蔓延,***指示</li>
<li>南方大旱,农作物减产绝收面积上亩</li>
<li>猪流感在广在全国暴发</li>
<li>禽流感在全国多处继续蔓延,***指示</li>
<li>南方大旱,农作物减产绝收面积上亩</li>
<li>猪流感在广东群体性暴发</li>
</ol>
</section>
<section class="cont" id="global">
<ol>
<li>河南再次发生矿难,死伤人数超过100</li>
<li>禽流感次发生蔓延,***指示</li>
<li>南方大旱,农作物减产绝收面积上亩</li>
<li>猪流感在广减产绝收发</li>
<li>禽流感在全国多作物减产绝收面积上亩</li>
<li>猪流感在广东群体性暴发</li>
</ol>
</section>
<section class="cont" id="sports">
<ol>
<li>河南再次发生矿难,死伤人数超过100</li>
<li>禽流感在全国多处农作物农延,***指示</li>
<li>南方大旱,农作物减产绝收面积上亩</li>
<li>猪流感在广东群体性暴发</li>
<li>禽流感在全农作物继续蔓延,***指示</li>
<li>南方大农作物减产绝收面积上亩</li>
<li>猪流感在广东群体性暴发</li>
</ol>
</section>
<section class="cont" id="funny">
<ol>
<li>河南再次发生矿难,死伤人数超过101 </li>
<li>禽流感在全国多处农作物农延,***指示</li>
<li>南方大旱,农作物减产绝收面积上亩</li>
<li>猪流感在广东群体性暴发</li>
<li>禽流感在全农作物继续蔓延,***指示</li>
<li>南方大农作物减产绝收面积上亩</li>
<li>猪流感在广东群体性暴发</li>
</ol>
</section>
</div>
<script>
/**
* 1.页面初始化的时候 可以指定当前选中的页签
* 2.点击页签的时候 可以做到样式的切换
* 3.点击页签的时候 可以让对应的内容做对应的显示
*/
/*function tab(index) {
}
tab(0);*/
(function (index) {
var tabList = document.querySelectorAll("nav > a");
var sectionList = document.querySelectorAll("section");
for (var i = 0; i < tabList.length; i++) {
var tab = tabList[i];
/*1.页面初始化的时候 可以指定当前选中的页签*/
tab.classList.remove("active");
if (index === i) {
tab.classList.add("active");
document.querySelector("#" + tab.dataset["count"]).style.display = "block";
}
/*2.点击页签的时候 可以做到样式的切换*/
tab.onclick = function () {
if (this.classList.contains("active")) {
return false;
}
for (var j = 0; j < tabList.length; j++) {
tabList[j].classList.remove("active");
}
this.classList.add("active");
for (var k = 0; k < sectionList.length; k++) {
sectionList[k].style.display = "none";
}
document.querySelector("#" + this.dataset["count"]).style.display = "block";
};
}
})(0);
</script>
第7章 新增API
7.1 拖拽
在HTML5的规范中,我们可以通过为元素增加draggable="true"来设置此元素是否可以进行拖拽操作,其中图片、链接默认是开启的。
7.1.1 拖拽元素
页面中设置了draggable="true"属性的元素
7.1.2 目标元素
页面中任何一个元素都可以成为目标元素
7.1.3 事件监听
拖拽元素
ondrag 应用于拖拽元素,整个拖拽过程都会调用
ondragstart 应用于拖拽元素,当拖拽开始时调用
ondragleave 应用于拖拽元素,当鼠标离开拖拽元素时调用
ondragend 应用于拖拽元素,当拖拽结束时调用
目标元素
ondragenter 应用于目标元素,当拖拽元素进入时调用
ondragover 应用于目标元素,当停留在目标元素上时调用
ondrop 应用于目标元素,当在目标元素上松开鼠标时调用
ondragleave 应用于目标元素,当鼠标离开目标元素时调用
数据传递
ev.dataTransfer.setData() 设置数据
ev.dataTransfer.getData() 读取数据
7.2 历史管理
提供window.history,对象我们可以管理历史记录,可用于单页面应用,Single Page Application,可以无刷新改变网页内容。
7.2.1 旧版本
history.back() 回退
history.forward() 前进
history.go(n) 前进/后退n步,正值前进,负值后退
history.length历史记录条数
7.2.2 新增方法
1、pushState(data, title, url) 追加一条历史记录
data用于存储自定义数据,通常设为null
title网页标题,基本上没有被支持,一般设为空
url 以当前域为基础增加一条历史记录,不可跨域设置
eg:
btn.onclick = function () {
// 第3个参数表示新追加的历史记录
// 第2代表示网页的title,所有浏览器基本都忽略
// 第一个参数,代表我们自定义一些数据,可传可不传,不传给null
history.pushState(null, \'text\', \'/test.html\');
}
2、replaceState(data, title, url) 与pushState()基本相同,不同之处在于replaceState(),只是替换当前url,不会增加/减少历史记录。
Single Page Application单页面应用
7.2.3 事件监听
onpopstate事件,当前进或后退时则触发,通过事件对象ev.state可以读取到存储的数据,监听是要给window。
eg:
// 监听历史记录的变化 只有在点后退/前进时调用
window.onpopstate = function (state) {
console.log(state);
}
7.3 地理定位
在HTML规范中,增加了获取用户地理信息的API,这样使得我们可以基于用户位置开发互联网应用,即基于位置服务 (Location Base Service)
7.3.1 获取地理信息方式
1、IP地址
2、三维坐标
GPS(Global Positioning System,全球定位系统)
Wi-Fi
手机信号
3、用户自定义数据
如下图对不同获取方式的优缺点进行了比较,浏览器会自动以最优方式去获取用户地理信息。
7.3.2 隐私
HTML5 Geolocation 规范提供了一套保护用户隐私的机制。必须先得到用户明确许可,才能获取用户的位置信息。
7.3.3 API详解
navigator.getCurrentPosition(successCallback, errorCallback, options) 获取当前地理信息
navigator.watchPosition(successCallback, errorCallback, options) 重复获取当前地理信息
1、当成功获取地理信息后,会调用succssCallback,并返回一个包含位置信息的对象position。
position.coords.latitude纬度
position.coords.longitude经度
position.coords.accuracy精度
position.coords.altitude海拔高度
2、当获取地理信息失败后,会调用errorCallback,并返回错误信息error
3、可选参数 options 对象可以调整位置信息数据收集方式
a) enableHighAccuracy 高精度模式
b) timeout 超时设置,单位为ms
c) maximumAge表示浏览器重新获取位置信息的时间间隔,单位为ms
7.4 Web存储
随着互联网的快速发展,基于网页的应用越来越普遍,同时也变的越来越复杂,为了满足各种各样的需求,会经常性在本地存储大量的数据,传统方式我们以document.cookie来进行存储的,但是由于其存储大小只有4k左右,并且解析也相当的复杂,给开发带来诸多不便,HTML5规范则提出解决方案。
7.4.1 特性
1、设置、读取方便
2、容量较大,sessionStorage约5M、localStorage约20M
4、只能存储字符串,可以将对象JSON.stringify() 编码后存储
7.4.2 window.sessionStorage
1、生命周期为关闭浏览器窗口
2、在同一个窗口下数据可以共享
7.4.3 window.localStorage
1、永久生效,除非手动删除
2、可以多窗口共享
7.4.4 方法详解
setItem(key, value) 设置存储内容
getItem(key) 读取存储内容
removeItem(key) 删除键值为key的存储内容
clear() 清空所有存储内容
key(n) 以索引值来获取存储内容
7.4.5 其它
WebSQL、IndexDB
7.5 全屏
HTML5规范允许用户自定义网页上任一元素全屏显示。
requestFullScreen() 开启全屏显示
cancelFullScreen() 关闭全屏显示
不同浏览器需要添加前缀如:
webkitRequestFullScreen、mozRequestFullScreen
webkitCancelFullScreen、mozCancelFullScreen
规范允许所有元素可以取全屏,但实际测试结果关闭全屏只能添加到document元素上
通过document.fullScreen检测当前是否处于全屏状态
不同浏览器需要添加前缀
document.webkitIsFullScreen、document.mozFullScreen
全屏伪类
:full-screen .box {}、:-webkit-full-screen {}、:moz-full-screen {}
7.6 网络状态
我们可以通过window. navigator.onLine来检测,用户当前的网络状况,返回一个布尔值
addEventListener 进行绑定online用户网络连接时被调用
addEventListener 进行绑定.offline用户网络断开时被调用
事件是给window绑订的
7.7 应用缓存
HTML5中我们可以轻松的构建一个离线(无网络状态)应用,只需要创建一个cache manifest文件。
7.7.1 优势
1、可配置需要缓存的资源
2、网络无连接应用仍可用
3、本地读取缓存资源,提升访问速度,增强用户体验
4、减少请求,缓解服务器负担
7.7.2 缓存清单
一个普通文本文件,其中列出了浏览器应缓存以供离线访问的资源,推荐使用.appcache为后缀名,添加MIME类型
AddType text/cache-manifest .appcache
例如我们创建了一个名为demo.appcache的文件,然后在需要应用缓存在页面的根元素(html)添加属性manifest="demo.appcache",路径要保证正确。
7.7.3 manifest文件格式
1、顶行写CACHE MANIFEST
2、CACHE: 换行 指定我们需要缓存的静态资源,如.css、image、js等
3、NETWORK: 换行 指定需要在线访问的资源,可使用通配符
4、FALLBACK: 换行 当被缓存的文件找不到时的备用资源
7.7.4 事件监听
可自行查阅资料
7.7.5 其它
1、CACHE: 可以省略,这种情况下将需要缓存的资源写在CACHE MANIFEST
2、可以指定多个CACHE: NETWORK: FALLBACK:,无顺序限制
3、#表示注释,只有当demo.appcache文件内容发生改变时或者手动清除缓存后,才会重新缓存。
4、chrome 可以通过chrome://appcache-internals/工具和离线(offline)模式来调试管理应用缓存
7.8 文件读取
通过FileReader对象我们可以读取本地存储的文件,可以使用 File 对象来指定所要读取的文件或数据。其中File对象可以是来自用户在一个 <input> 元素上选择文件后返回的FileList 对象,也可以来自由拖放操作生成的 DataTransfer
7.8.1 FileList对象
由于HTML5中我们可以通过为表单元素添加multiple属性,因此我们通过<input>上传文件后得到的是一个FileList对象(伪数组形式)。
7.8.2 FileReader对象
HTML5新增内建对象,可以读取本地文件内容。
var reader = new FileReader; 可以实例化一个对象
实例方法
1、readAsDataURL() 以DataURL形式读取文件
事件监听
onload 当文读取完成时调用
属性
result 文件读取结果
参考资料
https://developer.mozilla.org/zh-CN/docs/Web/API/FileReader#toc
二、CSS3
第8章 CSS3简介
如同人类的的进化一样,CSS3是CSS2的“进化”版本,在CSS2基础上,增强或新增了许多特性, 弥补了CSS2的众多不足之处,使得Web开发变得更为高效和便捷。
8.1 CSS3的现状
1、浏览器支持程度差,需要添加私有前缀
在pc做开发的时候 一定要加上私有前缀
/*谷歌*/
-webkit-border-radius: 50px;
/*火狐*/
-moz-border-radius: 50px;
/*欧鹏*/
-o-border-radius: 50px;
/*IE*/
-ms-border-radius: 50px;
2、移动端支持优于PC端
3、不断改进中
4、应用相对广泛
8.2 如何对待
1、坚持渐进增强原则
2、考虑用户群体
3、遵照产品的方案
4、听Boss的
第9章 准备工作
9.1 统一环境
由于CSS3兼容性问题的普遍存在,为了避免因兼容性带来的干扰,我们约定统一的环境,以保证学习的效率,在最后会单独说明兼容性的问题。
1、Chrome浏览器 version 46+
2、Firefox浏览器 firefox 42+
3、PhotoShop CS6(建议)
1.1 如何使用手册
学会使用工具,可以让我们事半功倍。
[] 表示全部可选项
|| 表示或者
| 表示多选一
? 表示0个或者1个
* 表示0个或者多个
{} 表示范围
学会查看手册,培养自主学习能力。
第10章 基础知识
10.1 选择器
CSS3新增了许多灵活查找元素的方法,极大的提高了查找元素的效率和精准度。CSS3选择器与jQuery中所提供的绝大部分选择器兼容。
10.1.1 属性选择器
其特点是通过属性来选择元素,具体有以下5种形式:
1、[attr] 表示存在attr属性即可;
2、[attr=val] 表示属性值完全等于val;
3、[attr*=val] 表示的属性值里包含val字符并且在“任意”位置;
4、[attr^=val] 表示的属性值里包含val字符并且在“开始”位置;
5、[attr$=val] 表示的属性值里包含val字符并且在“结束”位置;
注意:[attr!=val]在CSS3中失效
10.1.2 伪类选择器
除了以前学过的:link、:active、:visited、:hover,CSS3又新增了其它的伪类选择器。
1、以某元素相对于其父元素或兄弟元素的位置来获取无素的结构伪类。
重点理解通过E来确定元素的父元素。
E:first-child选择第一个元素 父元素下面的子元素当中的第一个
E:last-child选择最后一个元素 父元素下面的子元素当中的最后一个
E:nth-child(n) 选择第几个元素 父元素下面的子元素当中的第几个 注意是序号 计算方法是E元素的全部兄弟元素;
E:nth-last-child(n) 同E:nth-child(n) 相似,只是倒着计算;
n遵循线性变化,其取值0、1、2、3、4、... 但是当n<=0时,选取无效。
n可是多种形式:nth-child(2n)、nth-child(2n+1)、nth-child(-1n+5)等;
注意:n一定要放在表达式的前面
E:empty 选中没有任何子节点的E元素;(使用不是非常广泛)
eg:span:empty表示当span标签内容为空时则会被选中
2、目标伪类
E:target 结合锚点进行使用,处于当前锚点的元素会被选中;
3、排除伪类
E:not
eg:
/* :not 排除.special选择器*/
.test:not(.special) {
}
10.1.3 伪元素选择器
E::first-letter文本的第一个字母或汉字(如中文、日文、韩文等),必须是一个块级元素;
E::first-line 文本第一行;
重点:E::before、E::after是一个行内元素,需要转换成块元素
E:after、E:before 在旧版本里是伪类,在新版本里是伪元素,新版本下E:after、E:before会被自动识别为E::after、E::before,按伪元素来对待,这样做的目的是用来做兼容处理。
E::after、E::before后面的练习中会反复用到,目前只需要有个大致了解
E::selection 可改变选中文本的样式【不能改变文字大小】;
":" 与 "::" 区别在于区分伪类和伪元素
伪类的效果可以通过添加一个实际的类来达到,而伪元素的效果则需要通过添加一个实际的元素才能达到,这也是为什么他们一个称为伪类,一个称为伪元素的原因
10.2 颜色
新增了RGBA、HSLA模式,其中的A 表示透明度通道,即可以设置颜色值的透明度,相较opacity,它们不具有继承性,即不会影响子元素的透明度。
RGBA即Red、Green、Blue、Alpha
R、G、B 取值范围0~255 alpha 透明度 取值范围 0~1
HSLA即Hue、Saturation、Lightness、Alpha
通过hsla我们可以对颜色的透明度进行控制
H 色调 取值范围0~360,0/360表示红色、120表示绿色、240表示蓝色
S 饱和度 取值范围0%~100%
L 亮度 取值范围0%~100%
A 透明度 取值范围0~1
关于透明度:
1、opacity只能针对整个盒子设置透明度,子盒子及内容会继承父盒子的透明度;
2 、transparent 不可调节透明度,始终完全透明
RGBA、HSLA可应用于所有使用颜色的地方。
10.3 文本
text-shadow,可分别设置偏移量、模糊度、颜色(可设透明度)。
1、水平偏移量 正值向右 负值向左;
2、垂直偏移量 正值向下 负值向上;
3、模糊度是不能为负值;
第一个参数 x轴的偏移量
第二个参数 y轴的偏移量
第三个参数 阴影的长度
第四个参数 阴影的颜色
注意:可以有多个,中间以逗号(,)分隔
10.4 边框
其中边框圆角、边框阴影属性,应用十分广泛,兼容性也相对较好,具有符合渐进增强原则的特征,我们需要重点掌握。
10.4.1 边框圆角
border-radius
圆角处理时,脑中要形成圆、圆心、横轴、纵轴的概念,正圆是椭圆的一种特殊情况。如下图
可分别设置长、短半径,以“/”进行分隔,遵循“1,2,3,4”规则,“/”前面的1~4个用来设置横轴半径(分别对应横轴1、2、3、4位置 ),“/”后面1~4个参数用来设置纵轴半径(分别对应纵轴1、2、3、4位置 )
border-top-left-radius: 50px;
border-top-right-radius: 50px;
border-bottom-left-radius: 50px;
border-bottom-right-radius: 50px;
eg:
/*1、2、3、4四个角都是100px*/
border-radius: 100px;
/*13对应 24对应*/
border-radius: 100px 50px;
/*1 24对应 3*/
border-radius: 100px 50px 80px;
/*分别是1 2 3 4四个角的值*/
border-radius: 100px 100px 100px 100px;
/* X1 X2 X3 X4/Y1 Y2 Y3 Y4 */
border-radius: 100px 100px 100px 100px/100px 100px 100px 100px;
10.4.2 边框阴影
box-shadow
1、水平偏移量 正值向右 负值向左;
2、垂直偏移量 正值向下 负值向上;
3、模糊度不能为负值;
4、inset可以设置内阴影;
5、如果有5个参数,第四个参数代表阴影的延伸
eg:box-shadow: 3px 3px 3px 3px #ccc;
设置边框阴影不会改变盒子的大小,即不会影响其兄弟元素的布局。
可以设置多重边框阴影,实现更好的效果,增强立体感。
10.4.3 边框图片 【切4刀】
border-image
/*边框图片合写*/
border-image: url("") 27/20px round;
/*边框图片路径*/
border-image-source: url("");
/*边框图片切割的尺寸 不带单位 默认单位是px*/
border-image-slice: 27 27 27 27; /*上 右 下 左*/
/*边框图片的宽度 自适应显示图片内容*/
border-image-width: 20px;
/*边框图片平铺方式 默认是stretch 拉伸
round:环绕
repeat:平铺 以中心位置向两侧平铺
stretch:拉伸*/
border-image-repeat: round;
设置的图片将会被“切割”成九宫格形式,然后进行设置。如下图
“切割”完成后生成虚拟的9块图形,然后按对应位置设置背景,
其中四个角位置、形状保持不变,中心位置水平垂直两个方向平铺。如下图
1、round和repeat之间的区别
round 会自动调整尺寸,完整显示边框图片。
repeat 单纯平铺多余部分,会被“裁切”而不能完整显示。
2、更改裁切尺寸
background-slice: 34 36 27 27 分别设置裁切如下图
关于边框图片重点理解9宫格的裁切及平铺方式,实际开发中应用不广泛,但是如能灵活动用会给我们带来不少便利。
10.5 盒模型
CSS3中可以通过box-sizing 来指定盒模型,即可指定为content-box、border-box,这样我们计算盒子大小的方式就发生了改变。
box-sizing 有 border-box、content-box【默认】,不支持padding-box
box-sizing: border-box 以百分比布局的时候可以防止溢出
可以分成两种情况:
1、box-sizing: border-box 计算方式为width = border + padding + content
2、box-sizing: content-box 计算方式为width = content
注:上面的标注的width指的是CSS属性里设置的width: length,content的值是会自动调整的。
兼容性比较好
10.6 背景
背景在CSS3中也得到很大程度的增强,比如背景图片尺寸、背景裁切区域、背景定位参照点、多重背景等。
1、background-size设置背景图片的尺寸
可以通像素和百分比来调整背景图片的尺寸
百分比是根据当前容器的,而不是图片的百分比
cover会自动调整缩放比例,保证图片始终填充满背景区域,如有溢出部分则会被隐藏。
contain会自动调整缩放比例,保证图片始终完整显示在背景区域。
2、background-origin设置背景平铺的原点
border-box以边框做为参考原点;
padding-box以内边距做为参考原点;【默认】
content-box以内容区做为参考点;
3、background-clip设置背景区域裁切
border-box裁切边框以内为背景区域;【默认】
padding-box裁切内边距以内为背景区域;
content-box裁切内容区做为背景区域;
4、以逗号( ,)分隔可以设置多背景,可用于自适应局
eg:
background:
url("images/bg1.png") left top no-repeat,
url("images/bg2.png") right top no-repeat,
url("images/bg3.png") right bottom no-repeat,
url("images/bg4.png") left bottom no-repeat,
url("images/bg5.png") center no-repeat;
背景图片尺寸在实际开发中应用十分广泛。
10.7 渐变
渐变是CSS3当中比较丰富多彩的一个特性,通过渐变我们可以实现许多炫丽的效果,有效的减少图片的使用数量,并且具有很强的适应性和可扩展性。
可分为线性渐变、径向渐变
10.7.1 线性渐变
linear-gradient线性渐变指沿着某条直线朝一个方向产生渐变效果。
上图是从黄色渐变到绿色
1、必要的元素:
a、渐变的方向
to right(90deg)| to left(360deg)| to top(0deg)| to bottom(180deg) 还可以使用角度 deg 0deg是从下往上
b、起始颜色
c、终止颜色
eg:background-image: linear-gradient(0deg, yellow, green);
d、必须要有距离(渐变范围)
2、定义渐变的距离
to right 角度,#fff 25%,#000 25%
3、关于方向如下图
10.7.2 径向渐变
radial-gradient径向渐变指从一个中心点开始沿着四周产生渐变效果
1、必要的元素:
a、辐射范围即圆半径 at
b、中心点的位置即圆的中心
中心点的位置是以盒子自身为参照
c、渐变起始颜色
d、渐变终止颜色
e、渐变范围
2、关于中心点:中心位置参照的是盒子的左上角
3、关于辐射范围:其半径可以不等,即可以是椭圆
eg:background-image: radial-gradient(100px at 100px 100px, #fff, #00f);
关于渐变不同浏览器有不同的版本,即语法格式不一样,我们以最新语法为准,可自行查找资料了解即可。
http://www.w3cplus.com/css3/new-css3-linear-gradient.html
10.8 过渡(transition)
过渡transition是CSS3中具有颠覆性的特征之一,可以实现元素不同状态间的平滑过渡(补间动画),经常用来制作动画效果。
帧动画:通过一帧一帧的画面按照固定顺序和速度播放。如电影胶片
补间动画:自动完成从起始状态到终止状态的的过渡。
关于补间动画更多学习可查看http://mux.alimama.com/posts/1009
特点:当前元素只要有“属性”发生变化时,可以平滑的进行过渡。
eg:transition: all 1s;
eg:transition: all 2s cubic-bezier(0, 0, 0.4, 1.4);
1)transition-property设置过渡属性 all 代表的是全部的属性
2)transition-duration设置过渡时间 一定要带单位:秒
3)transition-timing-function设置过渡速度【cubic-bezier】
ease(默认)
linear
ease-in
ease-out
ease-in-out
4)transition-delay设置过渡延时
transition: all 1s linear;
/*过渡的属性 可以写all 代表的是全部的属性*/
transition-property: left;
/*过渡时间*/
transition-duration: 2s;
/*过渡速度*/
transition-timing-function: linear;
/*设置延时*/
transition-delay: 3s;
transition: width 2s linear, height 2s 2s;
注意:任何的属性的改变都会触发过渡
10.9 2D转换(transform)
转换transform是CSS3中具有颠覆性的特征之一,可以实现元素的位移、旋转、变形、缩放,甚至支持矩阵方式,配合即将学习的过渡和动画知识,可以取代大量之前只能靠Flash才可以实现的效果。
1、移动 translate(x, y) 可以改变元素的显示位置
1)x轴正方向朝右、y轴正方向朝下
2)x、y可以是固定像素值,也可以是百分比(基于本身)
3)相对于自身原来的位置移动
4)和盒子的任何定位都没有关系
5)x、y可以为负值;
2、缩放 scale(x, y) 可以对元素进行水平和垂直方向的缩放,x、y的取值可为小数,不可为负值;
3、旋转 rotate(deg) 可以对元素进行旋转,正值为顺时针,负值为逆时针;
当元素旋转以后,xy轴的方向也会发生改变
4、倾斜 skew(deg,deg) 可以使元素按一定的角度进行倾斜,参数为负表示相反方向倾斜
1)一般的话只会设置一个值
2)只写一个参数的时候,第二个参数默认为0
3)x轴 正值是逆时针
4)y轴 正值是顺时针
5、矩阵matrix() 把所有的2D转换组合到一起,需要6个参数。
6、transform-origin
1)可以调整元素转换的原点,但是对于transform: translate(x,y) 没有影响。
2)可以是像素值,也可以是百分比(相对于本身)
3)转换原点不影响translate位移
7、可以同时使用多个转换,以空格衔接,其格式为:transform: translate() rotate() scale() ...等,其顺序会影转换的效果。
10.10 3D转换
1、CSS中的3D坐标轴
用X、Y、Z分别表示空间的3个维度,三条轴互相垂直。如下图
2、左手坐标系
伸出左手,让拇指和食指成“L”形,大拇指向右,食指向上,中指指向前方。这样我们就建立了一个左手坐标系,拇指、食指和中指分别代表X、Y、Z轴的正方向。如下图
3、左手法则
左手握住旋转轴,竖起拇指指向旋转轴正方向,正向就是其余手指卷曲的方向。
4、rotateX 绕X轴旋转 如果是负的就是顺时针,正的是逆时针
rotateY 绕Y轴旋转 如果是负的就是顺时针,正的是逆时针
rotateZ 绕Z轴旋转 如果是负的就是顺时针,正的是逆时针
rotate3d(x,y,z)
如果你的设备有gpu加速、3d加速引擎,优先使用高性能的方式来渲染页面
translateX 在X轴移动
translateY 在Y轴移动
translateZ 在Z轴移动
translate3d(x,y,z)
如果你的设备有gpu加速、3d加速引擎,优先使用高性能的方式来渲染页面
5、透视(perspective)
电脑显示屏是一个2D平面,图像之所以具有立体感(3D效果),其实只是一种视觉呈现,通过透视可以实现此目的。
透视可以将一个2D平面,在转换的过程当中,呈现3D效果。
注:并非任何情况下需要透视效果,根据开发需要进行设置。
1)perspective有两种写法
a) 作为一个属性,设置给父元素,作用于所有3D转换的子元素
b) 作为transform属性的一个值,做用于元素自身
2)理解透视距离
透视会产生“近大远小”的效果
6、3D呈现(transform-style)
设置内嵌的元素在3D空间如何呈现,这些子元素必须为变形原素。
transform-style: flat 所有子元素在2D平面上呈现【默认】
transform-style: preserve-3d 保留3D空间
7、backface-visibility: visible;
设置元素背面是否可见 visible | hidden
默认是visible
注意:1)
transform: translateZ(2px);/*低版本浏览器需要*/
2)
content: attr(data-text);/*动态获取属性*/
10.11 动画(animation)
动画是CSS3中具有颠覆性的特征之一,可通过设置多个节点来精确控制一个或一组动画,常用来实现复杂的动画效果。
1、必要元素:
a、通过@keyframes指定动画序列;
声明动画序列 @keyframes + 动画序列的名称
b、通过百分比将动画序列分割成多个节点;
编写动画节点 from 0% to 100% 百分比是时间节点【相对于动画的执行时间】
c、在各节点中分别定义各属性
添加动画属性
d、通过animation将动画应用于相应元素;
调用animation动画
2、animation动画的关键属性
a、animation-name动画序列的名称
b、animation-duration动画执行时间
c、animation-timing-function动画执行速度,linear、ease【默认】、ease-in、ease-out、ease-in-out等
d、animation-delay动画延时时间
e、animation-play-state动画播放状态,running、paused等
f、animation-direction动画逆播放【作用:衔接动画】,alternate等
g、animation-fill-mode动画执行完毕后的状态,
forwards保持动画结束后的状态
backwards返回动画起始的状态【默认】
h、animation-iteration-count动画执行次数,infinate等
i、steps(60) 表示动画分成60步完成 注意:不要与速度一起用
注意:参数值的顺序:
关于几个值,除了名字、动画时间、延时有严格顺序要求,其它参数值随意
不要使用E:target调用animation动画
参考文档:http://isux.tencent.com/css3/index.html?transform
CSS3动画库:animate.css
10.12 综合案例
eg1:切割轮播图
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CSS3 3D切割轮播图</title>
<style>
body {
margin: 0;
padding-top: 0;
}
/*按钮*/
.prev, .next {
display: block;
width: 60px;
height: 60px;
text-align: center;
line-height: 60px;
margin-top: -30px;
font-size: 40px;
color: #FFF;
text-decoration: none;
background-color: rgba(0, 0, 0, 0.5);
position: absolute;
top: 50%;
}
.next {
right: 0;
}
.view {
width: 560px;
height: 300px;
margin: 100px auto;
border: 1px solid #CCC;
position: relative;
}
ul {
height: 100%;
margin: 0;
padding: 0;
list-style: none;
}
li {
position: absolute;
top: 0;
left: 0;
width: 112px;
height: 100%;
transform-style: preserve-3d;
transition: all 1s;
}
li:nth-child(1) {
left: 0;
}
li:nth-child(2) {
left: 112px;
}
li:nth-child(3) {
left: 224px;
}
li:nth-child(4) {
left: 336px;
}
li:nth-child(5) {
left: 448px;
}
li span {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
li span:nth-child(1) {
background: url("images/1.jpg") no-repeat;
transform: translateZ(150px);
}
li span:nth-child(2) {
background: url("images/2.jpg") no-repeat;
transform: translateY(-150px) rotateX(90deg);
}
li span:nth-child(3) {
background: url("images/3.jpg") no-repeat;
transform: translateZ(-150px) rotateX(180deg);
}
li span:nth-child(4) {
background: url("images/4.jpg") no-repeat;
transform: translateY(150px) rotateX(270deg);
}
li:nth-child(2) span {
background-position: -112px 0;
}
li:nth-child(3) span {
background-position: -224px 0;
}
li:nth-child(4) span {
background-position: -336px 0;
}
li:nth-child(5) span {
background-position: -448px 0;
}
</style>
</head>
<body>
<div class="view">
<ul>
<li><span></span><span></span><span></span><span></span></li>
<li><span></span><span></span><span></span><span></span></li>
<li><span></span><span></span><span></span><span></span></li>
<li><span></span><span></span><span></span><span></span></li>
<li><span></span><span></span><span></span><span></span></li>
</ul>
<a href="javascript:;" class="prev"><</a>
<a href="javascript:;" class="next">></a>
</div>
<script src="js/jquery.min.js"></script>
<script>
$(function () {
var count = 0;
$(".next").on("click", function () {
count--;
$(\'li\').each(function (key) {
$(this).css({
\'transform\': \'rotateX(\' + count * 90 + \'deg)\',
\'transition-delay\': key * 0.25 + \'s\'
});
});
});
$(".prev").on("click", function () {
count++;
$(\'li\').each(function (key) {
$(this).css({
\'transform\': \'rotateX(\' + count * 90 + \'deg)\',
\'transition-delay\': key * 0.25 + \'s\'
});
});
});
});
</script>
</body>
</html>
eg2:携程旅游
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>携程网</title>
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"/>
<style>
body{
margin: 0;
padding: 0;
}
ul{
list-style: none;
padding: 0;
margin: 0;
}
a{
color: #fff;
text-decoration: none;
}
/*轮播图*/
.banner a{
width: 100%;
display: block;
}
.banner a img{
width: 100%;
display: block;/*清除间隙*/
}
/*导航栏*/
.nav{
padding: 0 5px;
}
.nav ul{
display: flex;
height: 90px;
margin-top: 5px;
border-radius: 5px;
}
.nav ul:nth-child(1){background: #FF697A}
.nav ul:nth-child(2){background: #3d98ff}
.nav ul:nth-child(3){background: #44c522}
.nav ul:nth-child(4){background: #fc9720}
.nav ul.nav_top li:first-child{
flex: 1;
border-right: 1px solid #fff;
}
.nav ul.nav_top li:last-child{
flex: 2;
display: flex;
flex-wrap: wrap;
}
.nav ul.nav_top li:last-child a{
width: 50%;
height: 45px;
display: block;
text-align: center;
line-height: 45px;
box-sizing: border-box;
}
/*边框*/
.border_right{
border-right: 1px solid #fff;
}
.border_bottom{
border-bottom: 1px solid #fff;
}
.nav ul.nav_bottom{
flex-wrap: wrap;
}
.nav ul.nav_bottom li{
width: 33.33%;
}
.nav ul.nav_bottom li a{
display: block;
text-align: center;
line-height: 45px;
height: 45px;
}
/*主体*/
.product{
display: flex;
}
.product a{
width: 50%;
}
.product a img{
width: 100%;
display: block;
}
/*底部*/
.footer ul{
display: flex;
border-bottom: 1px solid #ccc;
border-top: 1px solid #ccc;
}
.footer ul li{
flex: 1;
}
.footer ul li a{
display: block;
text-align: center;
line-height: 40px;
height: 40px;
color: #666;
font-size: 12px;
}
.footer p{
text-align: center;
padding: 10px;
margin: 0;
}
</style>
</head>
<body>
<!--banner-->
<header class="banner">
<a href=""><img src="images/banner.jpg" alt=""/></a>
</header>
<!--导航栏-->
<nav class="nav">
<ul class="nav_top">
<li></li>
<li>
<a class="border_right border_bottom" href="">海外酒店</a>
<a class="border_bottom" href="">团购</a>
<a class="border_right" href="">特惠酒店</a>
<a href="">客栈公寓</a>
</li>
</ul>
<ul class="nav_top">
<li></li>
<li>
<a class="border_right border_bottom" href="">海外酒店</a>
<a class="border_bottom" href="">团购</a>
<a class="border_right" href="">特惠酒店</a>
<a href="">客栈公寓</a>
</li>
</ul>
<ul class="nav_top">
<li></li>
<li>
<a class="border_right border_bottom" href="">海外酒店</a>
<a class="border_bottom" href="">团购</a>
<a class="border_right" href="">特惠酒店</a>
<a href="">客栈公寓</a>
</li>
</ul>
<ul class="nav_bottom">
<li><a class="border_right border_bottom" href="#">门票玩乐</a></li>
<li><a class="border_right border_bottom" href="#">门票玩乐</a></li>
<li><a class="border_bottom" href="#">门票玩乐</a></li>
<li><a class="border_right" href="#">门票玩乐</a></li>
<li><a class="border_right" href="#">门票玩乐</a></li>
<li><a href="#">门票玩乐</a></li>
</ul>
</nav>
<!--主体-->
<main class="product">
<a href=""><img src="images/extra_1.png" alt=""/></a>
<a href=""><img src="images/extra_2.png" alt=""/></a>
</main>
<!--底部-->
<footer class="footer">
<ul>
<li><a href="#">电话预订</a></li>
<li><a href="#">电话预订</a></li>
<li><a href="#">电话预订</a></li>
</ul>
<p>网站地图 | ENGLISH | 电脑版</p>
<p>©2015 携程旅行</p>
</footer>
</body>
</html>
onmousewheel 鼠标滚动事件
<script>
window.onload = function(){
var count = 0;
document.onmousewheel = function(e){
/*鼠标滚动的量 下滚是负 上滚是正*/
if(e.wheelDelta < 0){
count ++;
}else{
count --;
}
console.log(count);
}
}
</script>
eg3:360浏览器
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>360浏览器</title>
<link rel="stylesheet" href="css/index【me】.css"/>
</head>
<body>
<!--大容器-->
<main>
<!--第一屏-->
<section class="section">
<!--logo-->
<div class="logo"><img src="images/logo.png" alt=""/></div>
<!--文字-->
<div class="text">
<img src="images/text_1.png" alt=""/>
<img src="images/text_2.png" alt=""/>
<img src="images/text_3.png" alt=""/>
<img src="images/text_4.png" alt=""/>
<img src="images/text_5.png" alt=""/>
<img src="images/text_6.png" alt=""/>
<img src="images/text_7.png" alt=""/>
<img src="images/text_8.png" alt=""/>
</div>
<!--信息-->
<div class="info"><img src="images/info_1.png" alt=""/></div>
</section>
<!--第二屏-->
<section class="section">
<!--盾牌-->
<div class="shield">
<img src="images/shield_1.png" alt=""/>
<img src="images/shield_2.png" alt=""/>
<img src="images/shield_3.png" alt=""/>
<img src="images/shield_4.png" alt=""/>
<img src="images/shield_5.png" alt=""/>
<img src="images/shield_6.png" alt=""/>
<img src="images/shield_7.png" alt=""/>
<img src="images/shield_8.png" alt=""/>
<img src="images/shield_9.png" alt=""/>
</div>
<!--信息-->
<div class="info"><img src="images/info_2.png" alt=""/></div>
</section>
<!--第三屏-->
<section class="section">
<!--信息-->
<div class="info"><img src="images/info_3.png" alt=""/></div>
<!--圆-->
<div class="circle"><img src="images/circle.png" alt=""/></div>
<!--火箭-->
<div class="rocket"><img src="images/rocket.png" alt=""/></div>
</section>
<!--第四屏-->
<section class="section">
<div class="search">
<div class="toolbar"><img src="images/search.png" alt=""/></div>
<div class="keys"><img src="images/key.png" alt=""/></div>
<div class="content"><img src="images/result.png" alt=""/></div>
</div>
<div class="info"><img src="images/info_4.png" alt=""/></div>
</section>
<!--第五屏-->
<section class="section">
<!--信息-->
<div class="info"><img src="images/info_5.png" alt=""/></div>
<!--浏览器-->
<div class="browser">
<!--工具栏-->
<div class="tool"><img src="images/toolbar.png" alt=""/></div>
<div class="toolbar"></div>
<!--四边线-->
<div class="line_top"></div>
<div class="line_right"></div>
<div class="line_bottom"></div>
<div class="line_left"></div>
<!--中间线-->
<div class="line_middle"></div>
<!--底部-->
<div class="other"><img src="images/extra.png" alt=""/></div>
</div>
</section>
</main>
<!--引入jQuery文件-->
<script src="js/jquery.min.js"></script>
<!--引入fullpage全屏切换插件-->
<script src="js/jquery.fullPage.js"></script>
<!--定义自己的代码-->
<script>
$(function () {
$("main").fullpage({
sectionsColor: [\'#0da5d6\', \'#2AB561\', \'#DE8910\', \'#16BA9D\', \'#0DA5D6\'],
afterLoad: function (link, index) {
$(".section").removeClass("current");
var $this = $(this);
setTimeout(function () {
//$(".section").eq(index - 1).addClass("current");
$this.addClass("current");
}, 200);
}
});
$(window).resize();
});
</script>
</body>
</html>
10.13 伸缩布局(display:flex)
CSS3在布局方面做了非常大的改进,使得我们对块级元素的布局排列变得十分灵活,适应性非常强,其强大的伸缩性,在响应式开中可以发挥极大的作用。
如下图,学习新的概念:
主轴:Flex容器的主轴主要用来配置Flex项目,默认是水平方向
侧轴:与主轴垂直的轴称作侧轴,默认是垂直方向的
方向:默认主轴从左向右,侧轴默认从上到下
主轴和侧轴并不是固定不变的,通过flex-direction可以互换。
1、必要元素:
a、指定一个盒子为伸缩容器 display: flex
b、设置属性来调整此盒的子元素的布局方式 例如:flex-direction
c、明确主侧轴及方向
d、可互换主侧轴,也可改变方向
2、各属性详解
a、flex-direction调整主轴方向【默认为水平方向】
包括row 水平排列、column 垂直排列、row-reverse 水平反向排列、column-reverse 垂直反向排列
b、justify-content调整主轴方向对齐方式
包括flex-start 起始点对齐、flex-end 终止点对齐、center 居中对齐、space-around 四周环绕、space-between两端对齐
c、align-items调整侧轴方向对齐方式
包括flex-start 起始点对齐、flex-end 终止点对齐、center居中对齐、stretch 拉伸
d、flex-wrap控制是否换行
包括nowrap 不换行、wrap 换行
e、align-content堆栈(由flex-wrap产生的独立行)对齐方式
堆栈排列,可对应用flex-wrap: wrap后产生的换行进行控制
包括flex-start 起始点对齐、flex-end 终止点对齐、center 居中对齐、space-between 两端对齐、space-around 四周环绕、stretch 拉伸
f、flex-flow是flex-direction、flex-wrap的简写形式
g、flex子项目在主轴的缩放比例【分配剩余宽度】,不指定flex属性,则不参与伸缩分配
h、align-self
同align-items
可覆盖父元素设置的algin-items,包括flex-start 起始点对齐、flex-end 终止点对齐、center 居中对齐、stretch拉伸
i、order控制子项目的排列顺序 正序方式排序 “先小后大”
10.14 多列布局
类似报纸或杂志中的排版方式,主要用以控制大篇幅文本。
/*指定列数*/
-webkit-column-count: 4;
/*指定列宽*/
-webkit-column-width: 400px;
/*定义边框线 和 border一样*/
-webkit-column-rule: 2px dashed #CCC;
/*调整列间距*/
-webkit-column-gap: 50px;
-webkit-column-span: all;
第11章 Web字体
开发人员可以为自已的网页指定特殊的字体,无需考虑用户电脑上是否安装了此特殊字体,从此把特殊字体处理成图片的时代便成为了过去。
支持程度比较好,甚至IE低版本浏览器也能支持。
11.1 字体格式
不同浏览器所支持的字体格式是不一样的,我们有必要了解一下有关字体格式的知识。
1、TureType(.ttf)格式
.ttf字体是Windows和Mac的最常见的字体,是一种RAW格式,支持这种字体的浏览器有IE9+、Firefox3.5+、Chrome4+、Safari3+、Opera10+、iOS Mobile、Safari4.2+;
2、OpenType(.otf)格式
.otf字体被认为是一种原始的字体格式,其内置在TureType的基础上,支持这种字体的浏览器有Firefox3.5+、Chrome4.0+、Safari3.1+、Opera10.0+、iOS Mobile、Safari4.2+;
3、Web Open Font Format(.woff)格式
woff字体是Web字体中最佳格式,他是一个开放的TrueType/OpenType的压缩版本,同时也支持元数据包的分离,支持这种字体的浏览器有IE9+、Firefox3.5+、Chrome6+、Safari3.6+、Opera11.1+;
4、Embedded Open Type(.eot)格式
.eot字体是IE专用字体,可以从TrueType创建此格式字体,支持这种字体的浏览器有IE4+;
5、SVG(.svg)格式
.svg字体是基于SVG字体渲染的一种格式,支持这种字体的浏览器有Chrome4+、Safari3.1+、Opera10.0+、iOS Mobile Safari3.2+;
了解了上面的知识后,我们就需要为不同的浏览器准备不同格式的字体,通常我们会通过字体生成工具帮我们生成各种格式的字体,因此无需过于在意字体格式间的区别差异。
推荐http://www.zhaozi.cn/、http://www.youziku.com/ 查找更多中文字体
eg:
/*声明字体*/
@font-face {
/*第三方字体名称*/
font-family: \'testfont\';
/*引入第三方字体的文件*/
src: url(\'../fonts/LiDeBiao-Xing3/LiDeBiao-Xing3.eot\') format(\'embedded-opentype\'),
url(\'../fonts/LiDeBiao-Xing3/LiDeBiao-Xing3.woff\') format(\'woff\'),
url(\'../fonts/LiDeBiao-Xing3/LiDeBiao-Xing3.ttf\') format(\'truetype\'),
url(\'../fonts/LiDeBiao-Xing3/LiDeBiao-Xing3.svg\') format(\'svg\');
font-weight: normal;
font-style: normal;
}
p.demo {
font-family: testfont;
font-size: 24px;
}
<p class="demo">
英雄不问出处,流氓不看岁数这个字行不行
</p>
<p class="demo">非英雄,非流氓</p>
11.2 字体图标
其实我们可以把文字理解成是一种特殊形状的图片,反之我们是不是也可以把图片制作成字体呢?
答案是肯定的。
常见的是把网页常用的一些小的图标,借助工具帮我们生成一个字体包,然后就可以像使用文字一样使用图标了。
优点:
1、将所有图标打包成字体库,减少请求;
2、具有矢量性,可保证清晰度;
3、使用灵活,便于维护;
Font Awesome 使用介绍
http://fontawesome.dashgame.com/
定制自已的字体图标库
http://iconfont.cn/
https://icomoon.io/
SVG素材
http://www.iconsvg.com/
第12章 兼容性
通过http://caniuse.com/ 可查询CSS3各特性的支持程度,一般兼容性处理的常见方法是为属性添加私有前缀,如不能解决,应避免使用,无需刻意去处理CSS3的兼容性问题。
三、移动web开发
第13章【第一天】
13.1移动web开发准备
13.1.1流式布局
流式布局就是百分比自适应布局,通过盒子的宽度设置成百分比来根据屏幕的宽度来进行伸缩,不受固定像素的限制,内容向两侧填充。
这样的布局方式,就是移动web开发使用的常用布局方式
13.1.2viewport【页面的适配】
- 我们猜想下pc页面在移动设备上显示情况。
放不下,缩放?
- 我们测试下pc页面在移动设备上显示。
默认的缩放的显示的
3. 认识viewport
在移动端用来承载网页的这个区域,就是我们的视觉窗口,即viewport(视口),这个区域可设置高度宽度,可按比例放大缩小,而且能设置是否允许用户自行缩放。
- viewport的参数:
☞width 设置宽度
默认的单位是px
viewport默认宽度为980px
有一个特殊的值:device-width,表示当前设备的宽度
☞initial-scale 设置初始化的缩放比
☞user-scalable 设置是否允许用户自行缩放
yes or no(1 or 0)
☞maximum-scale=1.0 最大的允许缩放比例
☞minimum-scale=1.0 最小的允许缩放比例
- 构建一个标准的移动web页面
<!--适配方案:
1.①设置viewport宽度与浏览器宽度一致 ②设置网页内容与viewport宽度一致
2.缩放比 保持1:1的比例显示,即与pc保持一致
规范的写法是两个都要设置
3.不允许用户自行缩放
-->
<!--国际上或者行业统一的viewport视口标准化设置-->
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0"/>
<!--Emmet语法: meta:vp-->
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"/>
13.1.3Retina屏(视网膜屏)
所谓“Retina”是一种显示技术,可以将把更多的像素点压缩至一块屏幕里,从而达到更高的分辨率并提高屏幕显示的细腻程度。
物理像素 像素点
屏幕尺寸 1px
eg:淘*移动站【使用viewport的非标准化设置】
13.2首页切图
如果按1:1的比例显示在移动设备当中,图片及背景图标会失真。使其不失真的解决方案:将图标缩小1倍
图片:width、height
背景图标:background-size
在行业中通用的设计稿:640px
目的:熟练的使用百分比布局
首页的布局:是以百分比布局为主的,定最小宽度和最大宽度的布局。
适用:图片比较多的首页、门户、电商等。
第14章【第二天】
14.1复习遇到的问题
14.1.1取消a链接的点击高亮效果
-webkit-tap-highlight-color: transparent; /*tap 轻击*/
14.1.2所有盒子以边框开始计算
/*设置宽度以边框开始计算*/
-webkit-box-sizing: border-box;
box-sizing: border-box;
在移动端通常使用的是百分比布局,那么这样的布局如果使用border或者padding会使容器的宽度超出屏幕的宽度产生滚动条。那么我们的解决方案是用css3属性box-sizing设置所有的盒子重边框开始计算宽度。
14.1.3input清除默认的样式
/*在移动端清除浏览器默认样式*/
-webkit-appearance: none;
在移动设备的浏览器当中表单一般会有默认的属性
通过border:none、outline:none是无法完全清除的,还是会有一些浏览器默认的属性,比如:内阴影,立体感、、、向这些浏览器默认加上的样式我们怎么去除呢?我们有一个属性:-webkit-appearance 这个属性指的是设置成 none
14.1.4最小宽度和最大宽度的限制
max-width: 640px; /*在行业当中的移动端的设计图一般使用的是640px 如果设计稿是750px,就把最大宽度设置成750px*/
min-width: 320px; /*在移动设备当中现在最小的尺寸是320px*/
适用:图片比较多的首页、门户、电商等。
作用:保证页面在尺寸比较大的设备当中保证页面的效果也就是清晰度
保证页面在小尺寸的设备当中有较好的布局效果。
14.1.5搜索按钮调用
<!--可以在移动端调出虚拟键盘,并且虚拟键盘带有搜索按钮-->
<form action="#">
<input type="search" placeholder="提示"/>
</form>
在移动端调用输入法的时候会弹出虚拟键盘,键盘一般是enter键,那么在搜索框当中我们要求调用是搜索按钮,那么这样的结构才能调用出来。
14.2移动端常见的事件
14.2.1Touch事件
☞Touch事件
◆touchstart:当手指触碰屏幕时候触发。不管当前有多少只手指
绑定触摸开始事件的方法:
/*绑定触摸开始事件*/
dom.addEventListener("touchstart", function (e) {
console.log("touchstart");
console.log(e);
});
事件返回的e对象包含一些移动端特有的属性:
originalEvent (原生事件)是jquery 封装的事件
touches 页面上的所有触摸点
clientX:触摸目标在视口中的X坐标
clientY:触摸目标在视口中的Y坐标
pageX:触摸目标在页面中的x坐标
pageY:触摸目标在页面中的y坐标
screenX:触摸目标在屏幕中的x坐标
screenY:触摸目标在屏幕中的y坐标
targetTouches 目标(当前)元素的所有当前触摸点
changedTouches 页面上最新更改的所有触摸点
注意:在touchend事件的时候event只会记录changedTouches
◆touchmove:当手指在屏幕上滑动时连续触发。通常我们在滑屏页面,
会调用event的preventDefault()可以阻止默认情况的发生:阻止页面滚动
绑定触摸滑动事件的方法:
/*绑定触摸滑动事件*/
dom.addEventListener("touchmove", function (e) {
console.log("touchmove");
console.log(e);
});
◆touchend:当手指离开屏幕时触发
绑定触摸离开事件的方法:
/*绑定触摸离开事件*/
dom.addEventListener("touchend", function (e) {
console.log("touchend");
console.log(e);
});
◆touchcancel:系统停止跟踪触摸时候会触发。
eg:在触摸过程中页面突然alert()出一个提示框,此时会触发该事件,这个事件比较少用
☞Touch触摸事件的响应顺序
① touchstart
② touchmove
③ touchend
④ click 300ms延时
14.2.2过渡和动画结束事件
☞transitionEnd 过渡结束后触发
绑定事件的方法:
dom.addEventListener(\'webkitTransitionEnd\',function(e){ });
dom.addEventListener(\'transitionEnd\',function(e){ });
☞animationEnd 动画结束后触发
绑定事件的方法:
dom.addEventListener(\'webkitAnimationEnd\',function(e){ });
dom.addEventListener(\'animationEnd\',function(e){ });
14.2.3Gesture事件(不常用)
☞gesturestart
当一个手指触摸屏幕之后,第二个手指再触摸屏幕时触发。
☞gesturechange
当上面的事件触发后立即触发。
☞gestureend
第二根手指离开屏幕时触发,之后将不会再次触发gesturechange。
☞在event当中会返回另外两个参数
scale 根据两个手指的滑动距离计算的缩放比例 初始1
rotation 根据两个手指的滑动距离计算的旋转角度 初始 0
第15章【第三天】
15.1复习遇到的问题
15.1.1移动端的滑动效果
在移动端特有的事件touch中,包含了touchstart、touchmove、touchend三个事件,
首先:
我们可以通过touchstart事件中返回的event对象中的第一个触摸点信息中的client坐标,
然后:
我们再通过监听touchmove事件的时候获取到滑动的时候的触摸点,再获取event对象中返回的client坐标,这样就可以计算滑动的时候改变的距离。同时改变当前元素的translate就可以。
最后:
在touchend的时候利用记录下当前元素的定位。
注意:在移动端是利用transform来做定位。
滑动的时候改变距离的方向问题。
15.1.2过渡结束事件
dom.addEventListener(\'webkitTransitionEnd\',function(e){ });
dom.addEventListener(\'transitionEnd\',function(e){ });
注意:为了兼容浏览器,在绑定事件的时候需要同时绑定一个带webkit前缀的事件和不带的这样达到兼容主流浏览器。
给目标元素绑定事件后,每一次过渡结束都会触发transitionEnd事件。
15.1.3使用过渡和改变注意问题
在移动端为了兼容老版本的一些webkit浏览器时,在css中或者js中一定要做兼容处理。
css中的处理方法是加上-webkit-前缀和一个不加的。
js中处理方法是style设置的时候需要设置一个webkit前缀的属性和一个不加的。
15.1.4两栏其中一栏宽度自适应
我们首先知道文本环绕的的概念:
那么当文本在另一个容器当中,容器是overflow:hidden【触发bfc(块级元素格式化上下文),将页面中的元素设置为独立的元素】的时候。那么这个时候这个盒子就变成了一个绝缘的盒子,不去影响任何外部的元素并且内容使用剩余的宽度。
这样也可是做一个自适应的两栏布局方式。
15.1.5按钮问题
这里的按钮设置的是 40*44的大小 但是内容只有20px,为什么要这么设置呢?
在移动端如果按钮太小,触发起来相对来说比较困难,用户体验非常不好。那么在设置按钮的时候需要设置的更大一点。
注意:不能使用margin,应为a标签触发不了。
background-clip: content-box;
background-origin:content-box;
15.2移动端事件原理
在移动端tap、swipe等事件的封装原理
tap:
由于在移动端click会有300ms左右的延时,为了响应速度更快移动端框架一般会封装一个加tap的事件,原理:利用touch事件当没有滑动过并且响应时间在一定的时间内(比click快)那么这样的一个过程就是一个tap事件。
15.2.1 tap事件的封装
/*定义了一个命名空间*/
window.itcast = {};
/**
* 过渡结束事件
* @param dom 给谁加事件
* @param callback 事件触发后处理什么业务
* @returns {boolean}
*/
itcast.transitionEnd = function (dom, callback) {
if (!dom || typeof dom != "object") {
return false;
}
dom.addEventListener("transitionEnd", function () {
/*if (callback) {
callback();
}*/
callback && callback();
/*短路与*/
});
dom.addEventListener("webkitTransitionEnd", function () {
callback && callback();
/*短路与*/
});
};
/**
* 封装一个tap事件
* @param dom
* @param callback
* @returns {boolean}
*/
itcast.tap = function (dom, callback) {
if (!dom || typeof dom != "object") {
return false;
}
var isMove = false;
var time = 0;//刚刚触摸到屏幕的时间 touchstart的触发时间
dom.addEventListener("touchstart", function () {
/*new Date().getTime();*/
time = Date.now();//时间戳 毫秒
});
dom.addEventListener("touchmove", function () {
isMove = true;
});
window.addEventListener("touchend", function (e) {
/**
* 1.没有滑动过
* 2.响应事件在150ms以内 要求比click要响应快
*/
if (!isMove && (Date.now() - time) < 150) {
callback && callback(e);
}
/*重置参数*/
isMove = false;
time = 0;
});
};
swipe:
在移动端有手势事件,也是一些移动端框架封装出来的那么这种事件也是touch事件开始的位置和结束的位置来判断手势的情况。是向下滑还是向右滑,是向下滑还是向上滑。
15.2.2 购物车页面切图
购物车页面是一个移动端最常使用的布局方式,完全的试用通栏流式布局的方式,宽度自适应。
这个页面需要注意的地方。
怎么自定义checkbox:属性选择器
移动端弹出框的特点:animte.css的使用,思路理解。
15.2.3 推荐网站
动画网站:https://daneden.github.io/animate.css/
这个网站可以提供一些常用的动画,可以在做移动开发的时候可以参考这个网站的效果完成动画。
zepto:http://zeptojs.com/
zepto是一个轻量级的针对现代高级浏览器的JavaScript库, 它与jquery有着类似的api。 如果你会用jquery,那么你也会用zepto。
swiper: http://www.swiper.com.cn/demo/index.html
常用于移动端网站的内容触摸滑动
是纯javascript打造的滑动特效插件,面向手机、平板电脑等移动终端。
能实现触屏焦点图、触屏Tab切换、触屏多图切换等常用效果。
开源、免费、稳定、使用简单、功能强大,是架构移动终端网站的重要选择!
iscroll: http://cubiq.org/iscroll-5
无论是在iphone、ipod、android 或是更早前的移动webkit都没有提供一种原生的方式来支持在一个固定高度的容器内滚动,它可以支持这样的滑动效果。
fastclick: https://github.com/ftlabs/fastclick/
消除点击延时提高程序的运行效率
tap缺点:击穿
15.2.4 项目三种布局分析
首页的适用场景:
门户电商的首页 而且内容比较丰富
分类页面的使用场景:
是单页面 全屏的布局当中会使用
异步的交互 ajax web app 的开发模式当中会使用到
web app 网页程序 网页应用
移动web页面优点:跨平台、android、ios
Hybird app 现在流行起来的 混合应用 开发模式 webview
套用 嵌入 移动web页面的 应用所有的移动页面都可以
Native app 原生应用
购物车页面:
任何地方都可以用到这样的布局。
第16章【第四天】
16.1响应式开发
16.1.1回顾移动web开发
适配 手机 pad
针对移动设备 开发 尽量的精简 浏览的流畅性 用户体验
16.1.2什么是响应式开发
在移动互联日益成熟的时候,我们在桌面浏览器上开发的网页已经无法满足移动设备的阅读。
通常的做法是针对移动端单独做一套特定的版本。
但是如果终端越来越多那么你需要开发的版本就会越来越多(大屏移动设备普及)。
那么Twitter 公司Ethan Marcotte在2010年5月份提出的一个概念,简而言之,就是一个网站能够兼容多个终端。
16.1.3响应式开发的原理
CSS3中的Media Query(媒介查询)
通过查询screen的宽度来指定某个宽度区间的网页布局。
超小屏幕(移动设备) 768px以下
小屏设备 768px-992px
中等屏幕 992px-1200px
宽屏设备 1200px以上
eg:
/*1.在超小屏设备【768px以下】 宽度100% 背景 红色*/
@media screen and (max-width: 768px) {
.container {
width: 100%;
background: red;
}
.row {
display: none;
}
}
/*2.在小屏设备 【768px-992px】 宽度750px 背景 黄色*/
@media screen and (max-width: 992px) and (min-width: 768px) {
.container {
width: 750px;
background: yellow;
}
}
/*3.在中屏设备 【992px-1200px】 宽度970px 背景 蓝色*/
@media screen and (max-width: 1200px) and (min-width: 992px) {
.container {
width: 970px;
background: blue;
}
}
/*4.在大屏设备 【1200px以上】 宽度1170px 背景 粉色*/
@media screen and (min-width: 1200px) {
.container {
width: 1170px;
background: pink;
}
}
or:
/*默认查询的就是屏幕*/
.container {
width: 1170px;
background: pink;
}
@media (max-width: 1200px) {
.container {
width: 970px;
background: blue;
}
}
@media (max-width: 992px) {
.container {
width: 750px;
background: yellow;
}
}
@media (max-width: 768px) {
.container {
width: 100%;
background: red;
}
.row {
display: none;
}
}
16.1.4响应式开发的前景
现在的移动设备屏幕越来越大。
越来越多的设计师也采用了这种设计。
在新建站的一些网站现在普遍采用的响应式开发。
那么在前端开发当中也是一项必备的技能。
16.1.5响应式开发和移动web开发的区别
16.2Bootstrap框架
16.2.1 简介
作者:Twitter 公司两位前端工程师(mark otto && jacob thornton)在2011发起开发完成的。
bootstrap 是最受欢迎的 HTML、CSS 和 JS 框架,用于开发响应式布局、移动设备优先的 WEB 项目。
bootstrap的特点:简洁、直观、强悍的前端开发框架,让web开发更迅速、简单
注意:bootstrap的所有JavaScript插件都依赖于jQuery。
中文网站:中文官网 http://www.bootcss.com/
特点:
16.2.2 为什么选择bootstrap
优点:
有自己的生态圈,不断的更新迭代。
提供了一套简洁、直观、强悍的组件。
标配准化的html+css编码规范。
让开发更简单,提高了开发的效率。
注意:虽然界面组件样式已经定义好了,但是扩展性相对较强,也就是说我们还可以自定义,修改默认样式。
16.2.3 版本
2.x.x 停止维护
优点:兼容性好
缺点:代码不够简洁,功能不够完善。
3.x.x 目前使用最多
稳定,但是放弃了IE6-IE7。对IE8支持但是界面效果不好。
偏向用于开发响应式布局、移动设备优先的 WEB 项目。
4.x.x 测试阶段
更偏响应式,移动设备,代码更精简。
16.2.4 Map文件
通常使用css和js 压缩的过程。
如果出错 显示浏览会提示那一行出错。
Map就是提供了记录代码位置的文件
16.2.5 Bootstrap基本模板
<!--html5标准文档模式-->
<!DOCTYPE html>
<!--使用的语言是中文简体-->
<html lang="zh-CN">
<head>
<!--编码格式-->
<meta charset="utf-8">
<!--告诉浏览器用最新的渲染引擎来渲染页面-->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!--用标准的移动端viewport设置来渲染页面-->
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0">
<!--上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后!-->
<!--首先告诉浏览器 优先解析-->
<!--标题-->
<title>Bootstrap基本模板</title>
<!-- 引入bootstrap的核心css文件 -->
<link href="lib/bootstrap/css/bootstrap.css" rel="stylesheet">
<!-- HTML5 shiv and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn\'t work if you view the page via file:// -->
<!--条件注释 小于IE9的浏览器会加载这么两句js-->
<!--gt gte lt lte 条件判断-->
<!--[if lt IE 9]>
<script src="lib/html5shiv/html5shiv.js"></script>
<script src="lib/respond/respond.js"></script>
<![endif]-->
<!--TODO 自己的css文件-->
</head>
<body>
<h1>你好,世界!</h1>
<!-- jQuery (necessary for Bootstrap\'s JavaScript plugins) -->
<!--引入jQuery文件-->
<!--∵bootstrap的所有javascript插件都依赖于jQuery-->
<script src="lib/jQuery/jquery.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<!--引入bootstrap的核心js文件-->
<script src="lib/bootstrap/js/bootstrap.js"></script>
<!--TODO 自己的js文件-->
</body>
</html>
16.2.6 Bootstrap布局容器
<!--布局容器-->
<!--响应式布局容器-->
<div class="container"></div>
<!--流式布局容器-->
<div class="container-fluid"></div>
16.2.7 Bootstrap栅格系统
<!--布局容器-->
<!--响应式布局容器-->
<div class="container">
<!--行 row-->
<div class="row">
<!--列 column 一行分成12等份 类名后面的数字代表的是占多少份-->
<div class="col-md-4"></div>
<div class="col-md-4"></div>
<div class="col-md-4"></div>
</div>
</div>
16.2.8 Bootstrap栅格系统-响应式
<!--布局容器-->
<!--响应式布局容器-->
<div class="container">
<!--行 row-->
<div class="row">
<!--列 column 一行分成12等份 类名后面的数字代表的是占多少份-->
<!--大屏及以上 lg 四等份
中屏及以上 md 三等份
小屏及以上 sm 二等份
超小屏及以上 xs 一份
-->
<div class="col-lg-3 col-md-4 col-sm-6 col-xs-12 col-lg-offset-1">
<div class="col-xs-6"></div>
<div class="col-xs-6"></div>
</div>
<div class="col-lg-3 col-md-4 col-sm-6 col-xs-12"></div>
<div class="col-lg-3 col-md-4 col-sm-6 col-xs-12"></div>
<div class="col-lg-3 col-md-4 col-sm-6 col-xs-12"></div>
</div>
</div>
16.2.9 Bootstrap栅格系统-排序
<!--布局容器-->
<!--响应式布局容器-->
<div class="container">
<!--行 row-->
<div class="row">
<div class="col-md-8 col-md-push-4">.col-md-8 .col-md-push-4</div>
<div class="col-md-4 col-md-pull-8">.col-md-4 .col-md-pull-8</div>
</div>
</div>
16.2.10 扩展选择器
/*选中当前元素的下一个同级元素*/
/*div + div {
color: red;
}*/
/*选中当前元素的下面同级所有的元素*/
div.red ~ div {
color: red;
}
第17章【第五天】
17.1复习和总结
17.1.1轮播图
在pc端:使用的是背景图片
在移动端使用的是图片
在写静态demo的时候使用的是响应是工具来完成的图片响应
但是会加载两种图片
那么这时候就需要做图片的响应式了
首先我们准备了json 中有两种数据
然后通过模版引擎解析成html
最终把解析完成的html渲染在页面当中。
17.2 underscore-template
<!--不会被解析成js 是单纯的字符串 认作是一个模板 有一些固定的语法-->
template语法:
1.在<% %>之间可以执行js代码
2.在使用 = 号的时候可以取值
3.在使用 - 号取值的时候,是直接渲染成字符串
① jQuery用法:
<% $.each(model,function(key,value){ %>
<tr>
<td><%=value.name%></td>
<td><%=value.age%></td>
</tr>
<% }); %>
② underscore用法:
<% _.each(model,function(value,key){ %>
<tr>
<td><%=value.name%></td>
<td><%=value.age%></td>
</tr>
<% }); %>
eg:
<table>
<thead>
<tr>
<th>名字</th>
<th>年龄</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<script type="text/template" id="template">
<% _.each(model,function(value,key){ %>
<tr>
<td><%-value.name%></td>
<td><%-value.age%></td>
</tr>
<% }); %>
</script>
<script src="lib/jQuery/jquery.js"></script>
<script src="lib/underscore/underscore.js"></script>
<script>
/*利用underscore template*/
/*准备数据*/
/*跨站脚本攻击(Cross Site Scripting) xss
* sql 数据库脚本
* js 网页脚本
*/
var personList = [
{name: "<script>alert(0);<\/script>", age: 16},
{name: "小丽", age: 18},
{name: "小明", age: 19}
];
/*把数据转换成html结构*/
/*使用template*/
/*1.需要模板*/
/*2.拿到模板中的字符串*/
var templateStr = document.querySelector("#template").innerHTML;
/*3.利用template方法转成一个模板方法*/
/* $ jQuery _ underscore*/
var templateFuc = _.template(templateStr);
/*4.利用转化过后的模板方法 转化成html结构*/
var templateHtml = templateFuc({model: personList});
//var html = _.template($("#template").html())({model: personList});
/*渲染到页面中*/
//document.querySelector("tbody").innerHTML = templateHtml;
$("tbody").html(templateHtml);
</script>
第18章 【第六天】
18.1 less
18.1.1Less环境安装
安装nodejs
在部分win8系统当中无法安装
(解决办法的是 已管理员权限运行cmd然后再按写命令切换到安装包目录,直接命令执行)
安装完成nodejs之后
检测是否安装完成 node –v 查看版本
然后检测 npm是否自带 npm –v 查看版本
在线安装
然后 运行 npm install –g less (部分电脑要 sudo 管理权限)
Lessc –v 查看版本 是否安装成功
离线安装
Npm.Zip解压进去。
Webstorm配置
18.1.2学习less
[官网](http://lesscss.org/)
[中文网](http://lesscss.cn/)
Webstrom 插件
Lessc less.less less.css 编译less文件成css
18.1.3简介
CSS(层叠样式表)是一门历史悠久的标记性语言,同 HTML 一道,被广泛应用于万维网(World Wide Web)中。HTML 主要负责文档结构的定义,CSS 负责文档表现形式或样式的定义。
作为一门标记性语言,CSS 的语法相对简单,对使用者的要求较低,但同时也带来一些问题:CSS 需要书写大量看似没有逻辑的代码,不方便维护及扩展,不利于复用,尤其对于非前端开发工程师来讲,往往会因为缺少 CSS 编写经验而很难写出组织良好且易于维护的 CSS 代码,造成这些困难的很大原因源于 CSS 是一门非程序式语言,没有变量、函数、SCOPE(作用域)等概念。LESS 为 Web 开发者带来了福音,它在 CSS 的语法基础之上,引入了变量,Mixin(混入),运算以及函数等功能,大大简化了 CSS 的编写,并且降低了 CSS 的维护成本,就像它的名称所说的那样,LESS 可以让我们用更少的代码做更多的事情。
18.1.4 LESS 原理及使用方式
本质上,LESS 包含一套自定义的语法及一个解析器,用户根据这些语法定义自己的样式规则,这些规则最终会通过解析器,编译生成对应的 CSS 文件。LESS 并没有裁剪 CSS 原有的特性,更不是用来取代 CSS 的,而是在现有 CSS 语法的基础上,为 CSS 加入程序式语言的特性。
18.1.5语法
变量
Mixin混入
嵌套
Import
函数(内置函数)
18.1.6变量
LESS 允许开发者自定义变量,变量可以在全局样式中使用,变量使得样式修改起来更加简单。
/*-----------------变量-----------------*/
@mainColor:#E93223;
body{
color: @mainColor;
}
18.1.7Mixin混入
Mixin(混入)功能对用开发者来说并不陌生,很多动态语言都支持 Mixin(混入)特性,它是多重继承的一种实现,在 LESS 中,混入是指在一个 CLASS 中引入另外一个已经定义的 CLASS,就像在当前 CLASS 中增加一个属性一样。
/*-----------------mixin 混入----------------*/
/*颜色*/
.red{
color: @mainColor;
}
.border{
border: 1px solid #ccc;
}
.redBorder(){
color: @mainColor;
border: 1px solid #ccc;
}
.mixin-class{
.red();
.border();
}
.mixin-fuc{
.redBorder();
}
18.1.8嵌套
在我们书写标准 CSS 的时候,遇到多层的元素嵌套这种情况时,我们要么采用从外到内的选择器嵌套定义,要么采用给特定元素加 CLASS 或 ID 的方式
/*------------------嵌套------------------*/
/*轮播图*/
#wjs_banner{
.carousel-inner{
> div.item{
a.img_box{
background: url("../images/slide_01_2000x410.jpg") no-repeat center center;
height: 410px;
/*调用redBorder mixin*/
display: block;
.redBorder();
/*调用@mainColor 变量*/
&:hover{
color: @mainColor;
}
}
a.img_mobile{
width: 100%;
display: block;
img{
width: 100%;
display: block;
}
}
}
}
}
18.1.9Import 导入
/*---------------------Import 引入------------------------*/
@import "base";
.f_left{
float: @right;
}
18.1.10运算及函数
在我们的 CSS 中充斥着大量的数值型的 value,比如 color、padding、margin 等,这些数值之间在某些情况下是有着一定关系的,那么我们怎样利用 LESS 来组织我们这些数值之间的关系呢?
http://www.1024i.com/demo/less/reference.html
escape(@string); // 通过 URL-encoding 编码字符串
e(@string); // 对字符串转义
%(@string, values...); // 格式化字符串
unit(@dimension, [@unit: ""]); // 移除或替换属性值的单位
color(@string); // 将字符串解析为颜色值
data-uri([mimetype,] url); // * 将资源内嵌到css中,可能回退到url()
ceil(@number); // 向上取整
floor(@number); // 向下取整
percentage(@number); // 将数字转换为百分比,例如 0.5 -> 50%
round(number, [places: 0]); // 四舍五入取整
sqrt(number); // * 计算数字的平方根
abs(number); // * 数字的绝对值
sin(number); // * sin函数
asin(number); // * arcsin函数
cos(number); // * cos函数
acos(number); // * arccos函数
tan(number); // * tan函数
atan(number); // * arctan函数
pi(); // * 返回PI
pow(@base, @exponent); // * 返回@base的@exponent次方
mod(number, number); // * 第一个参数对第二个参数取余
convert(number, units); // * 在数字之间转换
unit(number, units); // * 不转换的情况下替换数字的单位
color(string); // 将字符串或者转义后的值转换成颜色
rgb(@r, @g, @b); // 转换为颜色值
rgba(@r, @g, @b, @a); // 转换为颜色值
argb(@color); // 创建 #AARRGGBB 格式的颜色值
hsl(@hue, @saturation, @lightness); // 创建颜色值
hsla(@hue, @saturation, @lightness, @alpha); // 创建颜色值
hsv(@hue, @saturation, @value); // 创建颜色值
hsva(@hue, @saturation, @value, @alpha); // 创建颜色值
hue(@color); // 从颜色值中提取 hue 值(色相)
saturation(@color); // 从颜色值中提取 saturation 值(饱和度)
lightness(@color); // 从颜色值中提取 \'lightness\' 值(亮度)
hsvhue(@color); // * 从颜色中提取 hue 值,以HSV色彩空间表示(色相)
hsvsaturation(@color); // * 从颜色中提取 saturation 值,以HSV色彩空间表示(饱和度)
hsvvalue(@color); // * 从颜色中提取 value 值,以HSV色彩空间表示(色调)
red(@color); // 从颜色值中提取 \'red\' 值(红色)
green(@color); // 从颜色值中提取 \'green\' 值(绿色)
blue(@color); // 从颜色值中提取 \'blue\' 值(蓝色)
alpha(@color); // 从颜色值中提取 \'alpha\' 值(透明度)
luma(@color); // 从颜色值中提取 \'luma\' 值(亮度的百分比表示法)
saturate(@color, 10%); // 饱和度增加 10%
desaturate(@color, 10%); // 饱和度降低 10%
lighten(@color, 10%); // 亮度增加 10%
darken(@color, 10%); // 亮度降低 10%
fadein(@color, 10%); // 透明度增加 10%
fadeout(@color, 10%); // 透明度降低 10%
fade(@color, 50%); // 设定透明度为 50%
spin(@color, 10); // 色相值增加 10
mix(@color1, @color2, [@weight: 50%]); // 混合两种颜色
greyscale(@color); // 完全移除饱和度,输出灰色
contrast(@color1, [@darkcolor: black], [@lightcolor: white], [@threshold: 43%]); // 如果 @color1 的 luma 值 > 43% 输出 @darkcolor,否则输出 @lightcolor
multiply(@color1, @color2);
screen(@color1, @color2);
overlay(@color1, @color2);
softlight(@color1, @color2);
hardlight(@color1, @color2);
difference(@color1, @color2);
exclusion(@color1, @color2);
average(@color1, @color2);
negation(@color1, @color2);
iscolor(@colorOrAnything); // 判断一个值是否是颜色
isnumber(@numberOrAnything); // 判断一个值是否是数字(可含单位)
isstring(@stringOrAnything); // 判断一个值是否是字符串
iskeyword(@keywordOrAnything); // 判断一个值是否是关键字
isurl(@urlOrAnything); // 判断一个值是否是url
ispixel(@pixelOrAnything); // 判断一个值是否是以px为单位的数值
ispercentage(@percentageOrAnything); // 判断一个值是否是百分数
isem(@emOrAnything); // 判断一个值是否是以em为单位的数值
isunit(@numberOrAnything, "rem"); // * 判断一个值是否是指定单位的数值
eg:
/*-------------------运算和函数--------------------------*/
@back:#333;
.test{
border: 1px solid @back*2;
background: lighten(#000, 10%);
color:darken(#000, 10%);
}
18.1.11 Less在浏览器上使用的方法
<link rel="stylesheet/less" type="text/css" href="styles.less" />
<script src="less.js" type="text/javascript"></script>
18.2 rem
em 计算的基数是16px
rem 计算的基数是16px
r root 根元素 html
rem 计算的基数:html的font-size的大小
任何使用单位的地方都可以使用rem
四、HTTP服务&AJAX编程
第19章 服务器
通俗的讲,能够提供某种服务的机器(计算机)称为服务器。
19.1服务器类型
按照不同的划分标准,服务可划分为以下类型:
1、按服务类型可分为:文件服务器、数据库服务器、邮件服务器、Web服务器等;
2、按操作系统可分为:Linux服务器、Windows服务器等;
3、按应用软件可分为 Apache服务器、Nginx 服务器、IIS服务器、Tomcat服务器、weblogic服务器、WebSphere服务器、boss服务器、 Node服务器等;
19.2服务器软件
使计算机具备提供某种服务能力的应用软件,称为服务器软件,通过安装相应的服务软件,然后进行配置后就可以使计算具备了提供某种服务的能力。
常见的服务器软件有:
1、文件服务器:Server-U、FileZilla、VsFTP等
FTP 是File Transfer Protocol(文件传输协议);
2、数据库服务器:oracle、mysql、SQL server、DB2、ACCESS等;
3、邮件服务器:Postfix、Sendmail等;
4、HTTP 服务器:Apache、Nginx、IIS、Tomcat、NodeJS等;
19.3 HTTP服务器
即网站服务器,主要提供文档(文本、图片、视频、音频)浏览服务,一般安装Apache、Nginx服务器软件。
HTTP服务器可以结合某一编程语言处理业务逻辑,由此进行的开发,通常称之为服务端开发。
常见的运行在服务端的编程语言包括 PHP、Jsp、Asp、Python、Ruby、Perl等。
第20章 客户端
具有向服务器索取服务能力的终端,如比如 手机、电脑等,通过安装不同的客户端软件,可以获取不同的服务,比如通过QQ获得即时通讯服务、通过迅雷获得下载服务等。
常见的客户端软件:浏览器、QQ、迅雷、Foxmail等。
以浏览器为宿主环境,结合 HTML、CSS、Javascript等技术,而进行的一系列开发,通常称之为前端开发。
第21章 网络基础
21.1 IP地址
所谓IP地址就是给每个连接在互联网上的主机分配的一个32位地址。(就像每部手机能正常通话需要一个号码一样)
查看本机IP地址 ping、ipconfig、ifconfig(linux)
21.2 域名
由于IP地址基于数字,不方便记忆,于是便用域名来代替IP地址,域名是一个IP地址的“面具”
查看域名对应的IP地址 ping
21.3 DNS服务
DNS(Domain Name System)因特网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。
简单的说就是记录IP地址和域名之间对应关系的服务。
查找优先级 本机hosts文件、DNS服务器
ipconfig /flushdns
21.4 端口
端口号是计算机与外界通讯交流的出口,每个端口对应不同的服务。
现实生活中,银行不同的窗口办理不同的业务。
查看端口占用情况 netstat -an
常见端口号 80、8080、3306、21、22
第22章 C/S和B/S
22.1 C/S结构
即Client、Server
C/S工作流程图
在C/S结构的情况下,不同的服务需要安装不同的客户端软件,
比如QQ、迅雷、Foxmail这种情况下安装的软件会越来越多,同时也有许多弊端,
比如A出差,需要在B电脑上查收邮件,但是B电脑并未安装Foxmail等类似的客户端软件,这样不得不先去下载Foxmail,非常不方便。
22.2 B/S结构
B/S(即Broswer、Server)解决了C/S所带来的不便,将所有的服务都可以通过浏览器来完成(因为基本所有浏览器都安装了浏览器),但B/S也有一些不利,比如操作稳定性、流畅度等方面相对较弱。
第23章 搭建HTTP服务
Windows + Apache + Mysql + PHP,首字母组合。
23.1 安装WampServer
安装wampserver,和普通软件安装无差别,除指定安装路径外,其它默认安装。
23.2 管理HTTP服务
任务图标绿色为正常启动状态
通过图形控制台可以启动、重启、停止所有服务
或者单独启动、重启、停止特定服务
注意事项:
1、检查网络是不是通的 ping 对方IP
2、检查防火墙是否开启,如果开启将不能正常被访问
3、检查访问权限 Allow from all
4、理解默认索引
5、确保端口没有被其它程序占用
6、“#”表示注释
7、修改配置要格外小心,禁止无意修改其它内容
23.3 配置根目录
网站根目录是Web服务器上存放网站程序的空间,可通过修改配置文件自定义,如E:/www
具体步骤如下
1、打开配置文件,控制台选择
或者 wampserver安装目录下
bin\apache\Apache2.2.21\conf\httpd.conf
2、设定根目录,查找并修改
例如:
这样就指定了 "E:/www/"为存放网站的根目录。
3、配置根目录,查找
修改成
4、修改完后,并不能立即生效,需要重启Apache
注:可以指定任意目录为根目录
23.4 网站部署
将我们制作好的网页拷贝到配置好的根目录下,浏览器访问127.0.0.1即可。
23.5 配置虚拟主机
在一台Web服务器上,我们可以通过配置虚拟主机,然后分别设定根目录,实现对多个网站的管理。
具体步骤如下:
1、开启虚拟主机辅配置,在httpd.conf 中找到
去掉前面的#号注释,开启虚拟主机配置
2、配置虚拟主机,打开conf/extra/httpd-vhosts.conf
分别修改以下三项
DocumentRoot "E:/www/example"
ServerName "example.com "
ServerAlias "www.example.com"
其它项无需指定。
3、修改DNS(hosts)文件
打开C:\Windows\System32\drivers\etc\hosts
目录是固定的
注:修改hosts文件权限
4、重启Apache
5、浏览器访问www.example.com
第24章 PHP基础
文件以.php后缀结尾,所有程序包含在<?php /** 这里是代码 **/ ?>
避免使用中文目录和中文文件名
php页面无法直接打开需要运行在服务器环境当中
eg:最简单的php程序
<?php
//用来指定字符编码集
header(\'Content-Type:text/html; charset=utf-8\');
/*这是一个最简单的php程序*/
echo \'hello world!\';/*在页面当中输出字符*/
?>
24.1 变量
1、变量以 $ 开头 字母/数字/下划线
2、不能以数字、特殊字符开头
3、大小写敏感(区分大小写)
eg:
// 声明一个变量$a并赋值为10
$a = 10;
// 输出一个变量$a
echo $a; /*10*/
// 声明一个变量$b并赋值为10
$b = 10;
// 输出一个变量$b
echo $b; /*10*/
// 输出顺序是自上向下的
// 相当于 js中 dcoument.write()
24.2 数据类型
1、字符型
$str = \'你好!\';
echo $str;//你好!
2、整型
$int = 10;
echo $int;//10
3、浮点型
$float = 10.5;
echo $float;//10.5
4、布尔型
$boolean = true;
echo $boolean;//true 1 false 空
5、数组
1)索引数组
/*js中 var array = []; var array = new Array(); var array = [1, 2, 3]; array[0]*/
$arrayIndex = array(1, \'abcd\', 3);
//echo $arrayIndex[0];//1
print_r($arrayIndex);//Array ( [0] => 1 [1] => abcd [2] => 3 )
var_dump($arrayIndex);/*array
0 => int 1
1 => string \'abcd\' (length=4)
2 => int 3
*/
2)关联数组 php中 关联用\'=>\'
/*js中 var array = {name:\'小红\', age:18}; array.name or array[\'name\']*/
/*php中 关联是用\'=>\'*/
$arrayRel = array(\'name\' => \'小红\', \'age\' => 10);
//echo $arrayRel[\'name\'];//小红
print_r($arrayRel);//Array ( [name] => 小红 [age] => 10 )
var_dump($arrayRel);/*array
\'name\' => string \'小红\' (length=6)
\'age\' => int 10
*/
6、对象
// Javascript中 var obj = {name: itcast, age: 10}
/*声明一个类*/
class Person {
public $name = \'小红\';
public $age = 18;
}
/*初始化*/
$person = new Person;
//echo $person;//echo 只能打印简单数据类型
print_r($person);//Person Object ( [name] => 小红 [age] => 18 )
var_dump($person);/*object(Person)[1]
public \'name\' => string \'小红\' (length=6)
public \'age\' => int 18
*/
取值 -> 取对象当中的属性,属性名不需要带$
echo $person -> name;//小红
// obj[\'name\']; obj.name 不行
7、NULL
PHP中一种特殊的数据类型,表示空值,
即表示没有为该变量设置任何值null(空值)
不区分大小写,null和NULL是一样的。
eg:
$null = NULL;
echo $null;//空
8、单引号&双引号的区别:
1)单引号内部的变量不会执行
2)双引号内部的变量会执行
如果是双引号定义的字符 如果有字符能匹配到一个变量 就会当作变量来解释
注意:在php中最好使用单引号
eg:
$name = \'小红\';
$age = \'10\';
echo $name."$age";//小红10
/*如果是双引号定义的字符 如果有字符能匹配到一个变量 就会当作变量来解释*/
/*$age 作为变量来解析*/
echo $name.\'$age\';//小红$age
/*注意:最好使用单引号*/
24.3 字符串拼接
PHP中 .号表示字符串拼接符,Javascript中为 + 号
eg:
$name = \'小红\';
$time = \'今年\';
$age = \'10岁\';
$str = $name.$time.$age;
echo $str;//小红今年10岁
24.4 常用输出函数
1、echo:输出简单数据类型,如字符串、数值 **不能输出object**
eg:
/**
* 连接符
* Javascript中用+号表示连接符
* PHP中使用.号
*/
$hello = \'hello\';
$world = \'world!\';
// PHP连接符用.号
echo $hello . \' \' .$world;//hello world!
2、print_r():输出复杂数据类型,如数组 **能够看到数组结构**
eg:
$arr = array(\'itcast\', \'今年\', \'10岁了\');
// 只能输出简单类型
echo $arr;
// 可以打印数组,但是输出的是一个数组的结构
print_r($arr);//Array ( [0] => itcast [1] => 今年 [2] => 10岁了 )
3、var_dump():输出详细信息,如对象、数组 **用在object**
eg:
$arr = array(\'itcast\', \'今年\', \'10岁了\');
// 只能输出简单类型
echo $arr;
// 输出详细信息
var_dump($arr);/*array
0 => string \'itcast\' (length=6)
1 => string \'今年\' (length=6)
2 => string \'10岁了\' (length=8)
*/
24.5 运算符
基本与Javascript语法一致
. 号表示字符串拼接符,Javascript中为 + 号
24.6 函数
基本与Javascript基本一致
函数名对大小写不敏感
函数可以设置默认参数
eg:
/*
1、PHP中函数不可以省略参数
2、PHP中可以设置默认参数
*/
function sayHello($name=\'小红\'){
echo $name.\'你好!\';
}
sayHello();//小红
echo \'<br><br>\';
sayHello(\'小丽\');//小丽
24.7 分支、循环语句
/**
* 分支控制语句、循环语句
* 与Javascript一样
* foreach 数组遍历函数,类似Javascript中的 for in
*/
$name = \'itcast\';
if($name == \'itcast\') {
echo \'我已经在\' . $name . \'学习\';
} else {
echo \'我还没有学习过编程\';
}
1)索引数组
$arrIndex = array(\'itcast\', \'今年\', \'10岁了\');
// PHP函数,计算数组的长度
$length = count($arrIndex);
// echo $length;//3
// 和Javascript是一样的
// for($i=0; $i<$length; $i++) {
// echo $arrIndex[$i];
// }
foreach($arrIndex as $k=>$v) {
echo $k . \'~~~\' . $v . \' \';//0~~~itcast 1~~~今年 2~~~10岁了
};
2)关联数组
$arrRel = array(\'name\'=>\'itcast\', \'age\'=>\'10\');
//关联数组不可以按索引下标来访问
// echo $arrRel[0];
//PHP遍历一个关联数组
foreach($arrRel as $key=>$val) {
echo $key . \'~~~\' . $val . \' \';//name~~~itcast age~~~10
}
// 实际开发都是用foreach来遍历数组的
24.8 文件引入
include 引入html页面
require 引入php程序
eg:
/*include 引入html页面*/
include \'03form.html\';
/*require 引入php程序*/
require \'01.php\';
24.9 表单处理
1、只有input中的type是submit时,才会提交表单
2、表单name属性:用来方便服务器端接收所传递的数据(key => value)
3、表单action属性:提交表单的地址 处理表单的php程序的地址
4、表单method属性:设置发送数据的方式 get | post
①如果没有设置method,默认提交是以get方式提交 数据的形式是 数
据?拼接在url上 name=值&name=值
传输的数据有限
简单的拉取信息
eg:
<form action="03form.php" method="get">
<div>
用户名:<input type="text" name="username">
</div>
<div>
密 码:<input type="password" name="password">
</div>
<div>
<input type="submit">
</div>
</form>
$_GET 对象 用来接收以get方式提交的数据
/*1.获取以get方式进行的数据提交*/
/*$_GET对象 用来接收以get方式提交的数据*/
var_dump($_GET);
/*array
\'username\' => string \'小红\' (length=6)
\'password\' => string \'123456\' (length=6)
*/
echo \'用户名:\'.$_GET[\'username\'];//用户名:小红
echo \'<br>\';
echo \'密 码:\'.$_GET[\'password\'];//密 码:123456
②当设置post方式提交时,是不会在url上显示 包含在请求当中
传输的数据比get大得多
对数据库进行操作
eg:
<form action="03form.php" method="post">
<div>
用户名:<input type="text" name="username">
</div>
<div>
密 码:<input type="password" name="password">
</div>
<div>
<input type="submit">
</div>
</form>
$_POST 对象 用来接收以post方式提交的数据
/*2.获取以post方式进行的数据提交*/
/*$_POST对象 用来接收以post方式提交的数据*/
var_dump($_POST);
/*array
\'username\' => string \'小丽\' (length=6)
\'password\' => string \'123456\' (length=6)
*/
echo \'用户名:\'.$_POST[\'username\'];//用户名:小丽
echo \'<br>\';
echo \'密 码:\'.$_POST[\'password\'];//密 码:123456
5、上传文件:
1).文件提交必须以post方式提交
2).必须设置 enctype="multipart/form-data"
注意:上传的文件大小有限
eg:
<!--
1.文件提交必须以post方式提交
2.必须设置 enctype="multipart/form-data"
注意:上传的文件大小有限
-->
<form action="04formfile.php" method="post" enctype="multipart/form-data">
<div>
图 片:<input type="file" name="image">
</div>
<div>
<input type="submit">
</div>
</form>
$_FILES 对象 拿到文件相关信息
/*接收提交的文件*/
/*$_FILES对象 才能拿到文件相关信息*/
var_dump($_FILES);
/*array
\'image\' =>
array
\'name\' => string \'photo_745028_500.jpg\' (length=20)
\'type\' => string \'image/jpeg\' (length=10)
\'tmp_name\' => string \'C:\wamp\tmp\phpBDF8.tmp\' (length=23)
\'error\' => int 0
\'size\' => int 91658 字节(bite)
*/
/*把文件按照原来的名字上传到服务器*/
echo $_FILES[\'image\'][\'name\'];//photo_745028_500.jpg
echo \'<br>\';
echo $_FILES[\'image\'][\'tmp_name\'];//C:\wamp\tmp\phpBDF8.tmp
/*move_uploaded_file 移动上传完的文件*/
/*第1个参数 临时文件的目标路径*/
/*第2个参数 保存文件的目标路径*/
move_uploaded_file($_FILES[\'image\'][\'tmp_name\'], $_FILES[\'image\'][\'name\']);
24.10 数组嵌套
$arr = array(
\'image\' => array(\'name\' => \'png\')
);
var_dump($arr);
/*array
\'image\' =>
array
\'name\' => string \'png\' (length=3)
*/
24.11 常用PHP函数
$array = array(\'name\' => \'itcast\', \'age\' => \'10\');
echo \'获取数组的长度:\'.count($array);//获取数组的长度:2
echo \'<br>\';
echo \'判断是否在数组中:\'.in_array(\'itcast\',$array);//判断是否在数组中:1
echo \'<br>\';
echo \'检测数组中是否存在key:\'.array_key_exists(\'name\',$array);//检测数组中是否存在key:1
24.12 注意
php代码无法在html页面当中直接执行
只有在php环境当中,html页面中的php代码才能执行
24.13 应用实例
1、用户登录
2、动态网站
第25章 网络传输协议
指服务器和客户端间进行通信时的约束和规范,客户端与服务端的数据交互并不是杂乱无章的,需要遵照(基于)一定的规范进行。
25.1 常见协议
1、HTTP、HTTPS 超文本传输协议
2、FTP 文件传输协议
3、SMTP 简单邮件传输协议
25.2 HTTP协议
即超文本传输协议,网站是基于HTTP协议的,例如网站的图片、CSS、JS等都是基于HTTP协议进行传输的。
HTTP协议是由从客户机到服务器的请求(Request)和从服务器到客户机的响应(Response)进行了约束和规范。
即HTTP协议主要由请求和响应构成。
常用请求方法 POST、GET、PUT、DELETE
我们通过浏览器插件 FireFox:httpFox 调试
快捷键:ctrl + shift + F2
25.2.1 请求/请求报文
请求由客户端发起,其规范格式为:请求行、请求头、请求内容。
1、请求行
由请求方式、请求URL和协议版本构成
GET /day01/code/login.php?username=123&password=123 HTTP/1.1
POST /day01/code/login.php HTTP/1.1
2、请求头
Host:localhost请求的主机
Cache-Control:max-age=0控制缓存
Accept:*/* 接受的文档MIME类型
User-Agent:很重要
Referer:从哪个URL跳转过来的
Accept-Encoding:可接受的压缩格式
If-None-Match:记录服务器响应的ETag值,用于控制缓存
此值是由服务器自动生成的
If-Modified-Since:记录服务器响应的Last-Modified值
此值是由服务器自动生成的
3、请求主体
即传递给服务端的数据 【Query String】
注:只有当以post形式提交表单时,请求头里会设置这两个属性,并且属性值是固定的,而以get形式提交表单时请求头则不会设置这两个属性
1)Content-Type: application/x-www-form-urlencoded
2)Content-Length:28
25.2.2 响应/响应报文
响应由服务器发出,其规范格式为:状态行、响应头、响应内容。
1、状态行
由协议版本号、状态码和状态信息构成
响应状态码:
常见的有:\'200\'代表成功、304文档未修改、403没有权限、404未找到、500服务器错误
2、响应头
Date:响应时间
Server:服务器信息
Last-Modified:资源最后修改时间
由服务器自动生成
ETag:资源修改后生成的唯一标识
由服务器自动生成
Content-Length:响应主体长度
Content-Type:响应资源的MIME类型
MIME是标识文件类型的,文件后缀并不能正确无误的标识文件的类型。
思考?客户端与服务器间传递数据时,是以什么形式传输的?
客户端与服务器在进行数据传输的时候都是以字节形式进行的,咱们可以理解成是以文本形式传输,这时浏览器就需要明确知道该怎么样来解析这些文本形式的数据,MIME就是明确告知浏览器该如何来处理。
3、响应主体
即服务端返回给客户端的内容;【Content】
状态码
常见的有:200代表成功、304文档未修改、403没有权限、404未找到、500服务器错误
25.2.3 调试工具
利用HTTP抓包工具在开发中可以帮我们进行调试,常用抓包工具HttpWatch、Fiddler、Charles、FireBug等
浏览器插件
Firebug、HttpWatch、chrome dev tools
代理软件
Charles、Fiddler
25.2.4 协商缓存(性能优化)
此知识点属性扩展内容,不做具体分析
前端优化雅虎35条
http://www.tuicool.com/articles/J3uyaa
重绘&回流
http://www.zhangxinxu.com/wordpress/2010/01/%E5%9B%9E%E6%B5%81%E4%B8%8E%E9%87%8D%E7%BB%98%EF%BC%9Acss%E6%80%A7%E8%83%BD%E8%AE%A9javascript%E5%8F%98%E6%85%A2%EF%BC%9F/
利用浏览器的缓存机制,可以有效的减少HTTP的请求,提高页面加载速度,增强用户体验,同时也能极大的减轻服务器的负担,结合HTTP协议,缓存协商就是根据HTTP协议实现缓存控制的一种机制。
问题:是否见过某些网站CSS地址后面会带有一些参数,通常为xxx.css?cache=20160106形式
这种做法是用来强制清除缓存的,实际开发过程中,每当新功能上线时最容易引起BUG的即CSS的缓存,但是浏览器的缓存能减少请求,如果每次都强制清除,会对性能有损失,所以控制浏览器缓存成为前端性能化的一个重点
1、Last-Modified时间精确到了秒,但如果1秒内修改了多次,并不能精确的更新缓存。
2、ETag则是判断文件内容任何改变后,便会由服务器自动生成一个唯一标识。
3、Expires 过期时间,HTTP1.0的规范,一个绝对的时间
4、Cache-Control HTTP1.1规范,设置过期时间,优先级高于Expires。
第26章 AJAX编程
即 Asynchronous Javascript And XML,AJAX 不是一门的新的语言,而是对现有持术的综合利用。
本质是在HTTP协议的基础上以异步的方式与服务器进行通信。
26.1 异步
指某段程序执行时不会阻塞其它程序执行,其表现形式为程序的执行顺序不依赖程序本身的书写顺序,相反则为同步。
其优势在于不阻塞程序的执行,从而提升整体执行效率。
现实生活中的一个例子
打电话时同步 发消息是异步
XMLHttpRequest可以以异步方式的处理程序。
26.2 XMLHttpRequest——AJAX的核心对象
浏览器内建对象,用于在后台与服务器通信(交换数据) ,由此我们便可实现对网页的部分更新,而不是刷新整个页面。
下面是一个简单的例子:
/*js 内置的 http 请求对象 XMLHttpRequest*/
/*1.怎么使用 这个内置对象*/
var xhr = new XMLHttpRequest();
/*2.怎么样设置请求*/
/*请求行*/
xhr.open(\'post\', \'01.php\');
/*请求头*/
//在以get请求的时候 不需要设置请求头
//在以post请求的时候 一定要设置Content-Type: application/x-www-form-urlencoded
xhr.setRequestHeader(\'Content-Type\', \'application/x-www-form-urlencoded\');
/*请求内容*/
/*3.发送请求*/
//在以get提交的时候 数据是在url后面的 传null
//在以post提交的时候 key1=value1&key2=value2
xhr.send("name=xjj&age=10");
由于XMLHttpRequest本质基于HTTP协议实现通信,所以结合HTTP协议和上面的例子我们分析得出如下结果:
26.2.1 请求
HTTP请求3个组成部分与XMLHttpRequest方法的对应关系注意书写顺序
1、请求行
xhr.open(\'get\', \'02.data02.php\');
2、请求头
post请求需要设置
xhr.setRequestHeader(\'Content-Type\', \'application/x-www-form-urlencoded\');
get请求不需要设置
3、请求主体
post请求 xhr.send("name=xjj&age=10");
get请求 传空 null
26.2.2 响应
HTTP响应是由服务端发出的,作为客户端更应关心的是响应的结果。
HTTP响应3个组成部分与XMLHttpRequest方法或属性的对应关系。
由于服务器做出响应需要时间(比如网速慢等原因),所以我们需要监听服务器响应的状态,然后才能进行处理。
if(xhr.readyState == 4 && xhr.status == 200){
console.log(\'ok\');
console.log(xhr.responseText);
/*把内容渲染在页面当中*/
document.querySelector(\'#result\').innerHTML = xhr.responseText;
}
onreadystatechange是Javascript的事件的一种,其意义在于监听响应状态 监听readystate属性值的改变
readyState 通讯状态:
0:请求未初始化(还没有调用 open())。
1:请求已经建立,但是还没有发送(还没有调用 send())。
2:请求已发送,正在处理中(通常现在可以从响应中获取内容头)。
3:请求在处理中;通常响应中已有部分数据可用了,但是服务器还没有完成响应的生成。
4:响应已完成;您可以获取并使用服务器的响应了。
1、获取状态行(包括状态码&状态信息)
xhr.status 状态码
常见的状态码有:\'200\'代表成功、\'304\'文档未修改、\'403\'没有权限、\'404\'未找到、\'500\'服务器错误
xhr.statusText 状态码详细信息
2、获取响应头
xhr.getResponseHeader(\'Content-Type\'); 根据键来获取响应头部信息
xhr.getAllResponseHeaders(); 获取响应头当中的所有信息
3、响应主体
xhr.responseText 响应内容
xhr.responseXML xml数据格式的响应内容
我们需要检测并判断响应头的MIME类型后确定使用request.responseText或者request.responseXML
26.2.3 API详解
xhr.open() 发起请求,可以是get、post方式
xhr.setRequestHeader() 设置请求头
xhr.send() 发送请求主体 get方式使用xhr.send(null)
xhr.onreadystatechange = function () {} 监听响应状态
xhr.readyState = 0时,UNSENT open尚未调用
xhr.readyState = 1时,OPENED open已调用
xhr.readyState = 2时,HEADERS_RECEIVED 接收到头信息
xhr.readyState = 3时,LOADING 接收到响应主体
xhr.readyState = 4时,DONE 响应完成
xhr.status表示响应码,如200
xhr.statusText表示响应信息,如OK
xhr.getAllResponseHeaders() 获取全部响应头信息
xhr.getResponseHeader(\'key\') 获取指定头信息
xhr.responseText、xhr.responseXML都表示响应主体
26.2.4 GET和POST请求方式的差异(面试题)
1、GET没有请求主体,使用xhr.send(null)
2、GET可以通过在请求URL上添加请求参数
3、POST可以通过xhr.send(\'name=itcast&age=10\')
4、POST需要设置请求头 xhr.setRequestHeader(\'Content-Type\',\'application/x-www-form-urlencoded\');
5、GET效率更好(应用多)
6、GET大小限制约4K,POST则没有限制
26.3 XML
XML是一种标记语言,很类似HTML,其宗旨是用来传输数据,具有自我描述性(固定的格式的数据)。
26.3.1 语法规则
1、XML的声明必须顶行
2、必须有一个根元素
3、标签的名字可以随意,但是一定要有根元素
4、不可以有空格
5、不可以数字或.开头、大小写敏感
6、不可交叉嵌套
7、如果有属性,属性需要带引号,单引号默认渲染成双引号
8、不能包含特殊字符、特殊符号要使用实体
9、注释和HTML一样
虽然可以描述和传输复杂数据,但是其解析过于复杂并且体积较大,所以实现开发已经很少使用了。
26.3.2 XML示例
xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!--xml的声明必须顶行-->
<!--必须有根元素-->
<!--标签的名字可以随意 但是一定要有根元素-->
<!--不能以数字开头、不能包含特殊字符-->
<!--如果有属性,属性需要带引号,单引号默认渲染成双引号-->
<root>
<array name=\'productList\'>
<item>
<url data-src="images/detail01.jpg">images/detail01.jpg</url>
<nowPrice>10.00</nowPrice>
<oldPrice>1000.00</oldPrice>
</item>
<item>
<url>images/detail02.jpg</url>
<nowPrice>9.00</nowPrice>
<oldPrice>900.00</oldPrice>
</item>
<item>
<url>images/detail01.jpg</url>
<nowPrice>100.00</nowPrice>
<oldPrice>1999.00</oldPrice>
</item>
</array>
</root>
php:
<?php
/*以xml格式传输数据的时候要求响应内容格式是 text/xml or application/xml*/
header(\'Content-Type:text/xml;charset=utf-8\');
/*file_get_contents 获取文件内容*/
/*获取到的是字符串*/
$xml = file_get_contents(\'01.xml\');
/*输出xml内容*/
echo $xml;
?>
javascript:
window.onload = function () {
var xhr = new XMLHttpRequest();
xhr.open(\'get\', \'01.php\');
xhr.send(null);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
/*响应成功*/
/*返回的是xml格式的字符串 并且后台返回的格式是xml,responseXML获取到的是xml dom对象*/
var xmlDom = xhr.responseXML;
var items = xmlDom.querySelectorAll(\'item\');
var html = \'\';
for (var i = 0; i < items.length; i++) {
html += \'<tr>\';
html += \'<td>\' + items[i].querySelector(\'url\').innerHTML + \'</td>\';
html += \'<td>\' + items[i].querySelector(\'nowPrice\').innerHTML + \'</td>\';
html += \'<td>\' + items[i].querySelector(\'oldPrice\').innerHTML + \'</td>\';
html += \'</tr>\';
}
document.querySelector(\'tbody\').innerHTML = html;
}
};
};
26.4 JSON
即 JavaScript Object Notation,另一种轻量级的文本数据交换格式,独立于语言。
26.4.1 语法规则
1、数据在名称/值对中
2、数据由逗号分隔(最后一个健/值对不能带逗号)
3、花括号保存对象方括号保存数组
4、使用双引号
5、不能写注释
[
{"src":"images/detail01.jpg","oldPrice":"10.12","newPrice":"130.00"},
{"src":"images/detail02.jpg","oldPrice":"1.00","newPrice":"11.00"},
{"src":"images/detail03.jpg","oldPrice":"100.00","newPrice":"1000.00"}
]
26.4.2 JSON解析
JSON数据在不同语言进行传输时,类型为字符串,不同的语言各自也都对应有解析方法,需要解析完成后才能读取
1、Javascript 解析方法
JSON.parse() 把json格式的字符串 转成js当中的json对象
JSON.stringify() 把js当中的json对象 转化成json格式的字符串
为了解决IE6、7不支持json内置对象的兼容问题,引入json2.js
<!--为了解决IE6、7不支持json内置对象的兼容问题-->
<script src="js/json2.js"></script>
eg:
var jsonStr = \'[{"url":"images\/detail01.jpg","nowPrice":"10.00","oldPrice":"1000.00"},{"url":"images\/detail02.jpg","nowPrice":"9.00","oldPrice":"900.00"},{"url":"images\/detail03.jpg","nowPrice":"100.00","oldPrice":"1999.00"}]\';
/*JSON.parse() 把json格式的字符串 转成js当中的json对象*/
var jsonObject = JSON.parse(jsonStr);
console.log(jsonObject);
/*JSON.stringify() 把js当中的json对象 转化成json格式的字符串*/
var objectJson = [
{
"url": "images/detail01.jpg",
"nowPrice": "10.00",
"oldPrice": "1000.00"
},
{
"url": "images/detail02.jpg",
"nowPrice": "9.00",
"oldPrice": "900.00"
},
{
"url": "images/detail03.jpg",
"nowPrice": "100.00",
"oldPrice": "1999.00"
}];
console.log(objectJson);
var object2json = JSON.stringify(objectJson);
console.log(object2json);
2、PHP解析方法
json_encode() 把php对象解析成json格式的字符串
json_decode() 把json字符串解析成php对象
eg:
<?php
/*以json格式传输数据的时候要求响应内容格式是 text/json or application/json*/
header(\'Content-Type:text/json;charset=utf-8\');
/*注意也可以不设置 但是这遵循的一个规范*/
/*file_get_contents 获取文件内容 获取的是json数据格式的字符串*/
$json = file_get_contents(\'01.json\');
echo $json;/*[ { "url": "images/detail01.jpg", "nowPrice": "1.00", "oldPrice": "100.00" }, { "url": "images/detail02.jpg", "nowPrice": "9.00", "oldPrice": "900.00" }, { "url": "images/detail01.jpg", "nowPrice": "10.00", "oldPrice": "1000.00" } ]*/
echo \'<br><br>\';
/*json_decode 把json字符串解析成php对象*/
$json2php = json_decode($json);
var_dump($json2php);/*array
0 =>
object(stdClass)[1]
public \'url\' => string \'images/detail01.jpg\' (length=19)
public \'nowPrice\' => string \'1.00\' (length=4)
public \'oldPrice\' => string \'100.00\' (length=6)
1 =>
object(stdClass)[2]
public \'url\' => string \'images/detail02.jpg\' (length=19)
public \'nowPrice\' => string \'9.00\' (length=4)
public \'oldPrice\' => string \'900.00\' (length=6)
2 =>
object(stdClass)[3]
public \'url\' => string \'images/detail01.jpg\' (length=19)
public \'nowPrice\' => string \'10.00\' (length=5)
public \'oldPrice\' => string \'1000.00\' (length=7)
*/
echo $json2php[0] -> url;//images/detail01.jpg
echo \'<br><br>\';
$productList = array(
array(
\'url\' => \'images/detail01.jpg\',
\'nowPrice\' => \'10.00\',
\'oldPrice\' => \'1000.00\'
),
array(
\'url\' => \'images/detail02.jpg\',
\'nowPrice\' => \'9.00\',
\'oldPrice\' => \'900.00\'
),
array(
\'url\' => \'images/detail03.jpg\',
\'nowPrice\' => \'100.00\',
\'oldPrice\' => \'1999.00\'
)
);
/*json_encode 把php对象解析成json格式的字符串*/
$php2json = json_encode($productList);
echo $php2json;/*[{"url":"images\/detail01.jpg","nowPrice":"10.00","oldPrice":"1000.00"},{"url":"images\/detail02.jpg","nowPrice":"9.00","oldPrice":"900.00"},{"url":"images\/detail03.jpg","nowPrice":"100.00","oldPrice":"1999.00"}]*/
var_dump($php2json);//string \'[{"url":"images\/detail01.jpg","nowPrice":"10.00","oldPrice":"1000.00"},{"url":"images\/detail02.jpg","nowPrice":"9.00","oldPrice":"900.00"},{"url":"images\/detail03.jpg","nowPrice":"100.00","oldPrice":"1999.00"}]\' (length=213)
?>
总结:JSON体积小、解析方便且高效,在实际开发成为首选。
26.5 兼容性
IE5、IE6中使用 ActiveObject("Microsoft.XMLHTTP")
function XHR() {
var xhr;
try {
xhr = new XMLHttpRequest();
}
/*如果 try内的程序运行错误 抛出异常 捕捉异常 上面程序当中运行的错误*/
catch(e) {
/*在不同的IE版本下初始 ActiveXObject 需要传入的标识*/
var IEXHRVers =["Msxml3.XMLHTTP","Msxml2.XMLHTTP","Microsoft.XMLHTTP"];
for (var i=0;i<IEXHRVers.length;i++) {
try {
xhr = new ActiveXObject(IEXHRVers[i]);
}
catch(e) {
/*如果出现错误的时候 停止当次的循环*/
continue;
}
}
}
return xhr;
}
关于IE的兼容方面,了解即可。
26.6 封装AJAX工具函数
为了提升我们的开发效率,我们自已将XMLHttpRequest封装成一个函数。
/*封装一个ajax的方法*/
/*定义一个全局变量 $ */
window.$ = {};
/*声明一个ajax方法*/
/**
* 方法需求分析:
* =====请求=====
* 1. 请求方式 type get|post 默认 get
* 2. 请求地址 url 默认 当前页面的地址
* 3. 是否异步 async true|false 默认 true
* 4. 传输数据 data {} 默认 空对象{}
*
* =====响应=====
* 5. 成功回调函数 success function 异步通讯成功做的事情
* 6. 失败回调函数 error function 异步通讯失败做的事情
*
* @param options
* @returns {boolean}
*/
/*对象形式的传参方式*/
$.ajax = function (options) {
/*参数判断*/
if (!options || typeof options != \'object\') {
/*程序停止执行*/
return false;
}
/*参数的默认设置*/
/*请求方式*/
var type = options.type || \'get\';
/*请求地址*/
/*BOM window.location.pathname 当前页面的地址*/
var url = options.url || location.pathname;
/*是否异步*/
var async = options.async === false ? false : true;
/*传输数据*/
var data = options.data || {};
/*ajax原生 键值对 以&拼接*/
var dataStr = \'\';
/*遍历对象*/
for (var key in data) {
/*key=value*/
dataStr += key + \'=\' + data[key] + \'&\';
}
/*去掉最后面的&*/
/*dataStr.slice(0, -1) === dataStr.slice(0, dataStr.length - 1)*/
dataStr = dataStr && dataStr.slice(0, -1);//截掉最后一个字符
/*ajax编程*/
var xhr = new XMLHttpRequest();
/*设置请求行*/
/*get url 拼接*/
xhr.open(type, type == \'get\' ? url + \'?\' + dataStr : url, async);
/*设置请求头*/
/*post 才需要设置*/
if (type == \'post\') {
xhr.setRequestHeader(\'Content-Type\', \'application/x-www-form-urlencoded\');
}
/*设置请求内容*/
xhr.send(type == \'post\' ? dataStr : null);
/*响应*/
xhr.onreadystatechange = function () {
/*判断通讯有没有完成*/
if (xhr.readyState == 4) {
/*判断请求的状态*/
if (xhr.status == 200) {
/*异步通讯成功做的事情*/
/*按照约定过滤返回数据*/
var contentType = xhr.getResponseHeader(\'Content-Type\');
/*返回数据*/
var response = null;
/*判断是不是xml*/
if (contentType.indexOf(\'xml\') > -1) {
/*xml 对象*/
response = xhr.responseXML;
} else if (contentType.indexOf(\'json\') > -1) {
/*json 对象*/
response = JSON.parse(xhr.responseText);
} else {
response = xhr.responseText;
}
/*返回数据准备好了 返回给回掉函数*/
options.success && options.success(response);
} else {
/*异步通讯失败做的事情*/
var status = xhr.status;
var statusText = xhr.statusText;
options.error && options.error({code: status, message: statusText});
}
}
};
};
/*get请求的ajax*/
$.get = function (options) {
options.type = \'get\';
$.ajax(options);
};
/*post请求的ajax*/
$.post = function (options) {
options.type = \'post\';
$.ajax(options);
};
26.7 jQuery中的Ajax
jQuery为我们提供了更强大的Ajax封装
$.ajax({}) 可配置方式发起Ajax请求
$.get(url, [data], [callback], [type]) 以GET方式发起Ajax请求
url:待载入页面的URL地址
data:待发送 key/value 参数。
callback:载入成功时回调函数。
type:返回内容格式:xml, html, script, json, text, _default。
$.post(url, [data], [callback], [type]) 以POST方式发起Ajax请求
url:待载入页面的URL地址
data:待发送 key/value 参数。
callback:载入成功时回调函数。
type:返回内容格式:xml, html, script, json, text, _default。
$(\'form\').serialize() 序列化表单(即格式化key=val&key=val)
$(\'form\').serializeArray() 序列化表单(即[Object, Object])
url 接口地址
type 请求方式
timeout 请求超时 单位:毫秒
dataType 服务器返回格式
data 发送请求数据
beforeSend: function () {} 请求发起前调用
success 成功响应后调用
error 错误响应时调用
complete 响应完成时调用(包括成功和失败)
jQuery Ajax介绍
http://www.w3school.com.cn/jquery/jquery_ref_ajax.asp
26.8 案例练习
1、Loading状态
2、禁止重复提交
3、表单处理
4、数据验证
5、接口化开发
请求地址即所谓的接口,通常我们所说的接口化开发,其实是指一个接口对应一个功能,并且严格约束了请求参数和响应结果的格式,这样前后端在开发过程中,可以减少不必要的讨论,从而并行开发,可以极大的提升开发效率,另外一个好处,当网站进行改版后,服务端接口只需要进行微调。
6、具体参考代码
html:
<div class="register">
<form id="ajaxForm">
<ul>
<li>
<label for="name">用户名</label>
<input type="text" name="name" class="name" id="name">
</li>
<li>
<label for="pass">请设置密码</label>
<input type="password" name="pass" class="pass" id="pass">
</li>
<li>
<label for="repass">请确认密码</label>
<input type="password" name="repass" class="repass" id="repass">
</li>
<li>
<label for="mobile">验证手机</label>
<input type="text" name="mobile" class="mobile" id="mobile">
</li>
<li>
<label for="code">短信验证码</label>
<input type="text" name="code" class="code" id="code">
<input type="button" value="获取验证码" class="verify">
</li>
<li>
<label for="submit"></label>
<input type="button" class="submit" value="立即注册" id="submit">
</li>
</ul>
</form>
</div>
<div class="tips">
<p>用户名不能为空</p>
</div>
jQuery中的Ajax:
<script src="js/jquery.min.js"></script>
<script>
$(function () {
/**
* 短信验证码
* 1. 当没有输入手机号时 提示 "请输入手机号"
* 2. 当输入不正确的手机号时 提示 "请输入正确的手机号"
* 3. 合法之后 发送异步请求
* 3.1 在发送之后把按钮置灰 并且 不能再次点击 "正在发送中..."
* 3.2 当响应成功之后 倒计时 "多少秒之后再次获取"
* 3.3 当倒计时完成之后 置为可用的按钮 还原
*/
/*获取提示盒子*/
var tipBox = $(\'.tips > p\');
/*获取按钮*/
var $getMsgCodeBtn = $(\'.verify\');
/*绑定事件*/
$getMsgCodeBtn.on(\'click\', function () {
var $mobile = $(\'#mobile\');
var phoneNumber = $mobile.val();
/*3. 合法之后 发送异步请求*/
/**
* post
* getCode.php
* phoneNumber
* time
* phoneNumber
*/
$.ajax({
type: \'post\',
url: \'getCode.php\',
data: {phoneNumber: phoneNumber},
dataType: \'json\',
beforeSend: function () {
/*1 当没有输入手机号时 提示 "请输入手机号"*/
if (!phoneNumber || !$.trim(phoneNumber)) {
tipBox.html(\'请输入手机号\')
.fadeIn(500)
.delay(1500)
.fadeOut(500);
return false;
}
/*2. 当输入不正确的手机号时 提示 "请输入正确的手机号"*/
if (!/^1\d{10}$/.test(phoneNumber)) {
tipBox.html(\'请输入正确的手机号\')
.fadeIn(500)
.delay(1500)
.fadeOut(500);
return false;
}
/*防止重复提交*/
if ($getMsgCodeBtn.hasClass(\'disabled\')) {
return false;
}
/*3.1 在发送之后把按钮置灰 并且 不能再次点击 "正在发送中..."*/
$getMsgCodeBtn.addClass(\'disabled\')
.val(\'正在发送中...\');
},
success: function (data) {
/*3.2 当响应成功之后 倒计时 "多少秒之后再次获取"*/
var time = parseInt(data.time || 60);
var timer = setInterval(function () {
time--;
if (time < 0) {
/*3.3 当倒计时完成之后 置为可用的按钮 还原*/
$getMsgCodeBtn.removeClass(\'disabled\')
.val(\'获取验证码\');
clearInterval(timer);
return false;
}
$getMsgCodeBtn.val(time + \'秒之后再次获取\');
}, 1000);
},
error: function () {
tipBox.html(\'短信接口繁忙,稍后再试!\')
.fadeIn(500)
.delay(1500)
.fadeOut(500);
$getMsgCodeBtn.removeClass(\'disabled\')
.val(\'获取验证码\');
}
});
});
/***防止重复提交***/
/**
* 注册
* 1.当用户名不存在时 提示 "请输入用户名"
* 2.当输入的时候 可以提交
* 3.在提交中这个状态 不能重复提交
* 4.等待提交完成 把按钮变回原来的状态
* 5.当请求失败的时候 提示网络错误
*/
/*获取按钮*/
var $submitBtn = $(\'#submit\');
/*绑定事件*/
$submitBtn.on(\'click\', function () {
/*获取用户名输入框*/
var $name = $(\'.name\');
var name = $name.val();
/*表单序列化*/
/*jQuery的ajax支持这样的数据格式的发送*/
/*name=123&pass=&repass=&mobile=&code=*/
//var dataForm = $(\'#ajaxForm\').serialize();
//console.log(dataForm);
/*var dataObj = {};
var dataArr = dataForm.split(\'&\');
$.each(dataArr, function (key, value) {
var objArr = value.split(\'=\');
dataObj[objArr[0]] = objArr[1];
});
console.log(dataObj);*/
/*jQuery的ajax支持这样的数据格式的发送*/
/*[Object, Object, Object, Object, Object]*/
var dataForm = $(\'#ajaxForm\').serializeArray();
//console.log(dataForm);
var dataObj = {};
$.each(dataForm, function (key, value) {
dataObj[value.name] = value.value;
});
//console.log(dataObj);
/*1.当用户名不存在时 提示 "请输入用户名"*/
if (!dataObj.name) {
tipBox.html(\'请输入用户名\')
.fadeIn(500)
.delay(1500)
.fadeOut(500);
return false;
}
/*3.在提交中这个状态 不能重复提交*/
/*防止重复提交*/
/*if ($(\'#ajaxForm\').has(\'.disabled\').length) {
return false;
}*/
if ($submitBtn.hasClass(\'disabled\')) {
return false;
}
/*改为提交状态*/
$submitBtn.addClass(\'disabled\').val(\'正在提交...\');
/*2.当输入的时候 可以提交*/
$.ajax({
type: \'post\',
url: \'register.php\',
data: dataObj,
dataType: \'json\',
//timeout: 3000,
success: function (data) {
/*4.等待提交完成 把按钮变回原来的状态*/
tipBox.html(data.msg)
.fadeIn(500)
.delay(1500)
.fadeOut(500);
},
error: function () {
/*5.当请求失败的时候 提示 \'提示网络错误\'*/
tipBox.html(\'网络错误\')
.fadeIn(500)
.delay(1500)
.fadeOut(500);
},
complete: function () {
$submitBtn.removeClass(\'disabled\').val(\'立即注册\');
}
});
});
/*注意:jQuery 中的$.get()、$.post()*/
$.post(\'register.php\', {name: \'xiao\'}, function (data) {
console.log(data);
}, \'json\');
});
</script>
第27章 模板引擎
27.1 模板引擎原理
其本质是利用正则表达式,替换模板当中预先定义好的标签。
正则表达式exec()用法
http://www.w3school.com.cn/jsref/jsref_exec_regexp.asp
eg1:
<script type="text/template">
我的名字叫<%=name%>我今年<%=age%>岁。
</script>
<script>
/*模板引擎 <%= %> 取值*/
var templateStr = "我的名字叫<%=name%>我今年<%=age%>岁。";
var data = {
name: \'小红\',
age: 18
};
/*利用正则来匹配*/
/*匹配到 <%=xxx%> xxx*/
var macth = /<%=\s*([^%>]+\S)\s*%>/.exec(templateStr);
console.log(macth);//["<%=name%>", "name", index: 5, input: "我的名字叫<%=name%>我今年<%=age%>岁。"]
console.log(macth[0]);//<%=name%>
console.log(macth[1]);//name
console.log(data[macth[1]]);//小红
templateStr = templateStr.replace(macth[0], data[macth[1]]);
console.log(templateStr);//我的名字叫小红我今年<%=age%>岁。
macth = /<%=\s*([^%>]+\S)\s*%>/.exec(templateStr);
console.log(macth);//["<%=age%>", "age", index: 10, input: "我的名字叫小红我今年<%=age%>岁。"]
console.log(macth[0]);//<%=age%>
console.log(macth[1]);//age
console.log(data[macth[1]]);//18
templateStr = templateStr.replace(macth[0], data[macth[1]]);
console.log(templateStr);//我的名字叫小红我今年18岁。
/*如果没有 match是null*/
var macth = /<%=\s*([^%>]+\S)\s*%>/.exec(templateStr);
console.log(macth);//null
</script>
eg2:
<script type="text/template">
我的名字叫<%=name%>我今年<%=age%>岁。
</script>
<script>
/*模板引擎 <%= %> 取值*/
var templateStr = "我的名字叫<%=name%>我今年<%=age%>岁。";
var data = {
name: \'小红\',
age: 18
};
/*利用正则来匹配*/
/*匹配到 <%=xxx%> xxx*/
var macth = /<%=\s*([^%>]+\S)\s*%>/.exec(templateStr);
console.log(macth);//["<%=name%>", "name", index: 5, input: "我的名字叫<%=name%>我今年<%=age%>岁。"]
while (macth) {
templateStr = templateStr.replace(macth[0], data[macth[1]]);
macth = /<%=\s*([^%>]+\S)\s*%>/.exec(templateStr);
}
console.log(templateStr);//我的名字叫小红我今年18岁。
</script>
eg3:
1)
var template = function (data, templateStr) {
var macth = /<%=\s*([^%>]+\S)\s*%>/.exec(templateStr);
while (macth) {
templateStr = templateStr.replace(macth[0], data[macth[1]]);
macth = /<%=\s*([^%>]+\S)\s*%>/.exec(templateStr);
}
console.log(templateStr);
console.log(this);
};
template(data, templateStr);
/*我的名字叫小红我今年18岁。
Window {speechSynthesis: SpeechSynthesis, caches: CacheStorage, localStorage: Storage,
sessionStorage: Storage, webkitStorageInfo: DeprecatedStorageInfo…}
*/
2)
var template = function (data, templateStr) {
var macth = /<%=\s*([^%>]+\S)\s*%>/.exec(templateStr);
while (macth) {
templateStr = templateStr.replace(macth[0], data[macth[1]]);
macth = /<%=\s*([^%>]+\S)\s*%>/.exec(templateStr);
}
console.log(templateStr);
console.log(this);
};
/*apply 改变函数的上下文当中this的指向*/
template.apply({name: \'xiao\'}, [data, templateStr]);
/*我的名字叫小红我今年18岁。
Object {name: "xiao"}
*/
3)
var template = function (data, templateStr) {
var macth = /<%=\s*([^%>]+\S)\s*%>/.exec(templateStr);
while (macth) {
templateStr = templateStr.replace(macth[0], data[macth[1]]);
macth = /<%=\s*([^%>]+\S)\s*%>/.exec(templateStr);
}
return templateStr;
};
console.log(template(data, templateStr));//我的名字叫小红我今年18岁。
4)
/*也是一个方法,也是一个函数*/
var template = new Function(\'templateStr\', \'data\', \'var macth = /<%=\s*([^%>]+\S)\s*%>/.exec(templateStr);while (macth) {templateStr = templateStr.replace(macth[0], data[macth[1]]);macth = /<%=\s*([^%>]+\S)\s*%>/.exec(templateStr);}console.log(templateStr);\');
template(templateStr, data);//我的名字叫<%=name%>我今年<%=age%>岁。
27.2 流行模板引擎
BaiduTemplate:http://tangram.baidu.com/BaiduTemplate/
ArtTemplate:https://github.com/aui/artTemplate
velocity.js:https://github.com/shepherdwind/velocity.js/
Handlebars:http://handlebarsjs.com/
http://blog.jobbole.com/56689/
27.3 artTemplate 原生 js 模板语法
1、在页面中引用模板引擎:
<script src="js/template-native.js"></script>
下载(https://raw.github.com/aui/artTemplate/master/dist/template-native.js)
2、表达式
<% 与 %> 符号包裹起来的语句则为模板的逻辑表达式。
3、输出表达式
1)对内容编码输出:
<%=content%>
2)不编码输出:可以防止数据中含有 HTML 字符串,避免引起 XSS 攻击。
<%=#content%>
4、逻辑
1)支持使用 js 原生语法
<h1><%=title%></h1>
<ul>
<% for(i = 0; i < list.length; i ++) { %>
<li>条目内容 <%=i + 1%> :<%=list[i]%></li>
<% } %>
</ul>
2)模板包含表达式
3)用于嵌入子模板。
<% include(\'template_name\') %>
子模板默认共享当前数据,亦可以指定数据:
<% include(\'template_name\', news_list) %>
5、注意:模版当中没有其他全局变量
辅助方法:
使用template.helper(name, callback)注册公用辅助方法,例如一个基本的 UBB 替换方法:
template.helper(\'$ubb2html\', function (content) {
// 处理字符串...
return content;
});
模板中使用的方式:
<% $ubb2html(content) %>
6、案例
<div id="box"></div>
<script src="js/template-native.js"></script>
<script src="js/jquery.min.js"></script>
<!--
<% for (var i = 0; i < model.length; i++) { %>
<%=model[i].name%>今年<%=model[i].age%><br><br>
<% } %>
-->
<!--**注意:模板当中没有其他全局变量**-->
<script type="text/template" id="box_template">
<% var $ = jQuery(); %>
<% $.each(model,function(index,value){ %>
<%=value.name%>今年<%=value.age%><br><br>
<% }); %>
</script>
<script>
/*1、准备数据*/
var dataList = [
{name: \'xiao\', age: 10},
{name: \'sheng\', age: 12},
{name: \'li\', age: 15},
{name: \'wang\', age: 18},
{name: \'xiao\', age: 19},
];
/*把全局变量 $ 引入模板引擎*/
template.helper(\'jQuery\', function () {
return $;
});
/*2、转化成html结构*/
var html = template(\'box_template\', {model: dataList});
/*3、渲染页面*/
document.querySelector(\'#box\').innerHTML = html;
</script>
27.4 artTemplate 简洁语法模板
1、在页面中引用模板引擎:
<script src="js/template.js"></script>
下载(https://raw.github.com/aui/artTemplate/master/dist/template.js)
2、编写模板
<script id="test" type="text/template">
<h1>{{title}}</h1>
<ul>
{{each list as value i}}
<li>索引 {{i + 1}} :{{value}}</li>
{{/each}}
</ul>
</script>
3、渲染数据
var data = {
title: \'标签\',
list: [\'文艺\', \'博客\', \'摄影\', \'电影\', \'民谣\', \'旅行\', \'吉他\']
};
var html = template(\'test\', data);
document.getElementById(\'content\').innerHTML = html;
4、简洁语法
{{if admin}}
{{include \'admin_content\'}}
{{each list}}
<div>{{$index}}. {{$value.user}}</div>
{{/each}}
{{/if}}
5、案例
<div id="box"></div>
<script src="js/template.js"></script>
<!--
{{ each model as value key }}
{{value.name}}今年{{value.age}}<br><br>
{{ /each }}
-->
<script type="text/template" id="box_template">
{{ each model }}
{{$index}} {{$value.name}}今年{{$value.age}}<br><br>
{{ /each }}
</script>
<script>
/*1、准备数据*/
var dataList = [
{name: \'xiao\', age: 10},
{name: \'sheng\', age: 12},
{name: \'li\', age: 15},
{name: \'wang\', age: 18},
{name: \'xiao\', age: 19},
];
/*2、转化成html结构*/
var html = template(\'box_template\', {model: dataList});
/*3、渲染页面*/
document.querySelector(\'#box\').innerHTML = html;
</script>
第28章 同源&跨域
28.1 同源
同源策略是浏览器的一种安全策略,所谓同源是指,域名,协议,端口完全相同。
引用外部资源:资源引用的标签
<iframe src="http://www.baidu.com" frameborder="0"></iframe>
<img src="http://www.jd.com/images/l1.jpg" alt=""/>
<link rel="stylesheet" href="http://www.jd.com/css/index.css"/>
<script src="http://www.jd.com/js/index.js"></script>
注意:同源的iframe可以操作其内嵌页面中的内容
28.2 跨域
不同源则跨域
注意:不同源(即跨域)的iframe不能操作其内嵌页面中的内容
例如http://www.example.com/
|
http://api.example.com/detail.html |
不同源 |
域名不同 |
|
https//www.example.com/detail.html |
不同源 |
协议不同 |
|
http://www.example.com:8080/detail.html |
不同源 |
端口不同 |
|
http://api.example.com:8080/detail.html |
不同源 |
域名、端口不同 |
|
https://api.example.com/detail.html |
不同源 |
协议、域名不同 |
|
https://www.example.com:8080/detail.html |
不同源 |
端口、协议不同 |
|
http://www.example.com/detail/index.html |
同源 |
只是目录不同 |
28.3 跨域方案
顶级域名相同的跨域方案:
1、document.domain + iframe 即同时设置 domain.name = 顶级域名(如example.com)
2、window.name + iframe
3、location.hash + iframe
4、window.postMessage()
参考资料
http://rickgray.me/2015/09/03/solutions-to-cross-domain-in-browser.html
28.4 补充:
img onload
new Image();
var img = new Image();
img.src = \'\';
img.onload = function () {
};
iframe.onload = function () {
// 获取iframe的window对象 通过iframe.contentWindow
iframe.contentWindow.document.getElementById(\'txt\').style.color = \'red\';
};
28.5 JSONP
即JSON with Padding
1、原理剖析
其本质是利用了<script src=""></script>标签具有可跨域的特性,由服务端返回一个预先定义好的Javascript函数的调用,并且将服务器数据以该函数参数的形式传递过来,此方法需要前后端配合完成。
只能以GET方式请求
<!--当我们用script标签去加载的时候 会把内容解析成js去执行-->
<script>
function fn(data){
var data = JSON.parse(data);
console.log(data.name);
}
</script>
<script src="http://api.study.com/01jsonpCopy.php?callback=fn"></script>
28.6 jQuery中的JSONP
jQuery 的$.ajax() 方法当中集成了JSONP的实现,可以非常方便的实现跨域数据的访问。
dataType: \'jsonp\' 设置dataType值为jsonp即开启跨域访问
jsonp 可以指定服务端接收的参数的“key”值,默认为callback
jsonpCallback 可以指定相应的回调函数,默认自动生成
案例练习
天气接口(必须掌握)
接口地址:http://developer.baidu.com/map/carapi-7.htm
url:\'http://api.map.baidu.com/telematics/v3/weather?output=json&ak=0A5bc3c4fb543c8f9bc54b77bc155724\',
天气接口页面:weather.html
<body>
<input type="text" id="city"/> <a href="javascript:;" id="search">天气查询</a>
<table>
<thead>
<tr>
<th>日期</th>
<th>白天</th>
<th>晚上</th>
<th>*度</th>
<th>天气</th>
<th>风力</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<script type="text/template" id="template">
<% for(var i = 0 ; i < list.length ; i ++){%>
<tr>
<% var item = list[i]; %>
<td><%=item.date%></td>
<td><img src="<%=item.dayPictureUrl%>" alt=""/></td>
<td><img src="<%=item.nightPictureUrl%>" alt=""/></td>
<td><%=item.temperature%></td>
<td><%=item.weather%></td>
<td><%=item.wind%></td>
</tr>
<%}%>
</script>
<script src="./js/jquery.min.js"></script>
<script src="./js/template-native.js"></script>
<script>
/*
* 1.获取城市
* 2.发送jsop请求
* 3.渲染html
* */
$(function(){
$(\'body\').on(\'click\',\'#search\',function(){
$.ajax({
type:\'get\',
url:\'http://api.map.baidu.com/telematics/v3/weather?output=json&ak=0A5bc3c4fb543c8f9bc54b77bc155724\',
data:{
location:$(\'#city\').val()||\'上海\'
},
dataType:\'jsonp\',
success:function(data){
console.log(data.results[0].weather_data);
/*模版渲染*/
var html = template(\'template\',{list:data.results[0].weather_data})
$(\'tbody\').html(html);
}
});
});
});
</script>
</body>
第29章 综合练习
29.1 异步加载瀑布流案例(必须掌握)
jQuery封装的瀑布流插件:jquery.waterFall.js
(function ($) {
$.fn.watarFall = function () {
/*this 调用这个方法的 jQuery选择到的dom对象*/
/*$this 拿到的瀑布流容器 其中需要去做定位的盒子*/
var $this = $(this);
/*父容器的宽度*/
var parentWidth = $this.width();
/*子容器*/
var items = $this.children();
/*子容器的宽度*/
var childWidth = items.width();
/*多少列*/
var columnCount = 5;
/*间距*/
var space = (parentWidth - childWidth * columnCount) / (columnCount - 1);
/*核心布局代码*/
/**
* 1.第一排的盒子 top = 0
* 2.距离左边的距离 根据当前所属的列 第几列 索引*宽度+间距
* 3.计算top的定位 找到最矮的那列 把它追加上去
* 4.容器是没有高度的 需要计算最高的那列 设置高度
* 核心:怎么样实时的记录每一列的高度 需要有一个记录每一列高度的变量 数组记录五列的高度
*/
var colArray = [];
/*遍历所有的盒子*/
$.each(items, function (index, item) {
/*当前盒子*/
var $item = $(item);
/*索引0-4就是第一排的五个子盒子*/
if (index < 5) {
/*初始化数组*/
colArray[index] = $item.height();
/*1.第一排的盒子 top = 0*/
/*2.距离左边的距离 根据当前所属的列 第几列 索引*(宽度+间距)*/
$item.css({
top: \'0\',
left: index * (childWidth + space)
});
} else {
/*计算定位*/
/*3.计算top的定位 找到最矮的那列 把它追加上去*/
var minItem = colArray[0];//最小的高度
var minIndex = 0;//最小的列的索引
for (var i = 0; i < colArray.length; i++) {
if (minItem > colArray[i]) {
minItem = colArray[i];
minIndex = i;
}
}
/*因为要定位left 需要这列的索引*/
$item.css({
top: minItem + space,
left: minIndex * childWidth + space
});
/*colArray 高度变了 所以要重新设值*/
colArray[minIndex] = minItem + space + $item.height();
}
});
/*布局完成再来设置容器的高度*/
/*4.容器是没有高度的 需要计算最高的那列 设置高度*/
var maxItem = colArray[0];
for (var i = 0; i < colArray.length; i++) {
if (maxItem < colArray[i]) {
maxItem = colArray[i];
}
}
$this.height(maxItem);
};
})(jQuery);
后台数据处理:data.php
<?php
header(\'Content-Type:text/html; charset=utf-8\');
/* 接口化编程
1.请求方式type get
2.请求地址url data.php
3.请求传递的参数 page 当前页数 pageSize 每一页多少条数据
4.后台在处理
5.返回数据 {page:\'下一页的页码\',items:[{path:\'图片路径\',text:\'文字\'},{},{}...]}
*/
/*获取数据 字符串*/
$data = file_get_contents(\'data.json\');
/*转化成php对象 需要对其操作*/
$data = json_decode($data);
/*当前页数*/
$page = $_GET[\'page\'];
/*每一页的条数*/
$pageSize = $_GET[\'pageSize\'];
/*获取数据的起始索引*/
$offset = ($page - 1) * $pageSize;
/*array_slice() 从什么位置开始切割 切割多少条*/
$result = array_slice($data, $offset, $pageSize);
/*下一页的页码*/
$page++;
echo json_encode(array(\'page\'=>$page, \'items\'=>$result));//{page:\'\',items:[]}
sleep(1);
?>
瀑布流页面:waterFall.html
<div class="container">
<div class="items"></div>
<div data-page="1" class="btn loading">正在加载...</div>
</div>
<script type="text/template" id="items_template">
<% if(model.items && model.items.length) { %>
<% for (var i = 0; i < model.items.length; i++) { %>
<div class="item">
<img src="<%=model.items[i].path%>" alt="">
<p><%=model.items[i].text%></p>
</div>
<% } %>
<% } %>
</script>
<script src="js/jquery.min.js"></script>
<!--原生语法-->
<script src="js/template-native.js"></script>
<script src="js/jquery.waterFall.js"></script>
<script>
/** 接口化编程
* 1.请求方式type get
* 2.请求地址url data.php
* 3.请求传递的参数 page 当前页数 pageSize 每一页多少条数据
* 4.后台在处理
* 5.返回数据 {page:\'下一页的页码\',items:[{path:\'图片路径\',text:\'文字\'},{},{}...]}
*/
/** 需求
* 1.第一屏默认加载 第一页的数据
* 2.点击加载更多 加载下一页的内容
* 3.点击的时候 防止重复提交
* 4.加载数据完成之后 渲染在页面当中
* 5.由于是瀑布流布局 需要初始化布局方式
* 6.当没有数据的时候 不能让用户再请求 提示没有更多数据
* 7.当滚动到页面底部一定距离的时候 自动加载
*【异步加载的时候 需要后台返回图片的尺寸】
*/
$(function () {
/*获取dom元素*/
/*瀑布流容器渲染*/
var $items = $(\'.items\');
/*加载按钮*/
var $btn = $(\'.btn\');
/*1.第一屏默认加载 第一页的数据*/
/*4.加载数据完成之后 渲染在页面当中*/
/*5.由于是瀑布流布局 需要初始化布局方式*/
var renderHtml = function () {
$.ajax({
type: \'get\',
url: \'data.php\',
dataType: \'json\',
data: {
page: $btn.data(\'page\') || 1,//默认加载第一页
pageSize: 10//每一页10条数据
},
beforeSend: function () {
$btn.addClass(\'loading\').html(\'正在加载中...\');
},
success: function (data) {
/*把数据解析成html结构 渲染到页面当中*/
var htmlStr = template(\'items_template\', {model: data});
$items.append(htmlStr);
/*插件初始化*/
$items.watarFall();
/*渲染完成之后*/
if (!data.items.length) {
/*6.当没有数据的时候 不能让用户再请求 提示没有更多数据*/
$btn.addClass("loading").html("没有更多数据了");
} else {
$btn.removeClass("loading").html("加载更多");
}
/* jQuery data()
* $(\'.btn\').data(\'page\',1); 设置自定义属性
* $(\'.btn\').data(\'page\'); 获取自定义属性的值
* data-page = "1" 自定义属性定义的规范 而通过jQuery data拿到的属性的名称是去掉data
* 数据的设置是在内存当中
* */
$btn.data(\'page\', data.page);
}
});
};
/*初始化第一页数据*/
renderHtml();
/*2.点击加载更多 加载下一页的内容*/
/*4.加载数据完成之后 渲染在页面当中*/
/*5.由于是瀑布流布局 需要初始化布局方式*/
$btn.on(\'click\', function () {
/*3.点击的时候 防止重复提交*/
if ($btn.hasClass("loading")) {
return false;
}
/*加载下一页*/
renderHtml();
});
/*7.当滚动到页面底部一定距离的时候 自动加载*/
$(window).on(\'scroll\', function () {
/*布局容器距离顶部的高度*/
var offsetTop = $(\'.items\').offset().top;
/*布局容器的高度*/
var height = $(\'.items\').height();
/*当前文档距离浏览器顶部的高度*/
var scrollTop = $(this).scrollTop();
/*浏览器的高度*/
var winHeight = $(this).height();
/*整个文档多余的高度*/
var offset = offsetTop + height - scrollTop - winHeight;
/*整个文档多余的高度小于200 去加载下一页的数据*/
if (offset <= 200 && !$(\'.btn\').hasClass(\'loading\')) {
renderHtml();
}
});
});
</script>
29.2 省/市/区县三级联动