1. 本文是在学习廖雪峰先生的JavaScrip教程 后的归纳
一、浏览器对象
- 常用的浏览器: Chrome,Firefox,Sarafi
- window 对象
-
window
对象不但充当全局作用域,而且表示浏览器窗口 -
window
对象有innerWidth
和innerHeght
属性,可以获取浏览器窗口的内部宽度和高度(内部宽高指的是除去菜单栏、工具栏、边框等占位元素后,用于显示网页的净宽高) -
outerWidth
和outerHeight
属性,可以获取浏览器窗口的整个宽高 -
navigator
对象表示浏览器的信息,最常用的属性包括:-
navigator.appName
: 浏览器名称; -
navigator.appVersion
:浏览器版本; -
navigator.language
: 浏览器设置的语言 -
navigator.platform
: 操作系统类型 -
navigator.userAgent
:浏览器设定的User-Agent
字符串 -
navigator
的值可以被用户修改,JavaScript读取的值不一定正确
-
-
- screen对象
-
screen
对象表示屏幕的信息,常用的属性有:-
screen.width
:屏幕宽度,以像素为单位 -
screen.height
: 屏幕高度,以像素为单位 -
screen.colorDepth
:返回颜色位数,如8、16、24
-
-
- location对象
-
location
对象表示当前页面的URL
信息-
location.protocol
; //'http' -
location.host
;//'www.example.com' -
location.port
;//'8080' -
location.pathname
;//'/path/index.html` -
location.search
;//'?a=1&b=2' -
location.hash
;//'TOP' -
location.assign('')
//加载一个新页面 -
location.reload()
//重新加载当前页面
-
-
- document对象
-
document
对象表示当前页面,由于HTML在浏览器中以DOM形式表示为树形结构,document
对象就是整个DOM数的根节点 -
document
的title
属性是从HTML文档中<title>xxx<title>
读取的,可以动态改变document.title='ab';
-
查找DOM数的某个节点,需要从
document对象开始查找,最常用的查找是根据
ID和
TAGName` -
document
对象提供的getElementeById()
和getElementsByTagName()
-
document
还有一个cookie
属性,可以获取当前页面的cookie
- Cookie是有服务器发送的
key-value
标识符, 因为HTTP协议是无状态的,服务器使用Cookie区分哪个用户 - Cookie还存储网站的一些设置:如页面显示的语言等
- JavaScript通过
document.cookie
读取到当前页面的Cookie - 为了安全,服务器端设置Cookie时可以使用
httpOnly
,设定了httpOnly
的Cookie将不能被JavaScript读取,这个行为由浏览器实现,主流浏览器均支持httpOnly
选项
-
- histroy对象
- history 对象保存了浏览器的的历史记录
- 调用
history
对象的back()
或forward()
后退或前进 - 由于交互不好,建议不要使用
history
对象
二、操作DOM
- DOM简介
- DOM是一个树形结构
- 操作DOM的操作有:
- 更新: 更新该DOM节点的内容
- 遍历: 遍历该DOM节点下的子节点
- 添加: 添加子节点
- 删除: 从HTML中删除该节点
- 取得节点方法有:
document.getElementById()
和document.getElementByTagName()
,以及CSS选择器document.getElementsByClassName()
-
document.getElemnetById()
定位唯一的一个DOM节点,而document.getElementByTagName()
和documente.getElementesByClassName()
返回一组DOM节点 -
querySelector()
和querySelectorAll()
// 通过querySelector获取ID为q1的节点: var q1 = document.querySelector('#q1'); // 通过querySelectorAll获取q1节点内的符合条件的所有节点: var ps = q1.querySelectorAll('div.highlighted > p'); 注意:低版本的IE<8不支持querySelector和querySelectorAll。IE8仅有限支持。
- DOM节点实际上是
Node
,而Node
包括Element
和Comment
,CDATA_SECTION
等很多种以及根节点Document
类型,绝大多数我们仅关心Element
,即实际控制页面结构的Node
,其他类型的Node
忽略即可 - 根节点
Document
已经自动绑定为全局变量document
- 更新DOM
- 方法1: 修改
innerHTML
属性,不仅仅可以修改一个DOM节点的文本内容,还可以直接通过HTML片段修改DOM节点内部的子树 - 方法2: 修改
innerText
或textContent
属性,可以自动对字符串进行HTML编码,保证无法设置任何HTML标签 - 区别:
innerText
不返回隐藏元素的文本,而textContent
返回所有文本,另外,IE<9不支持textContent
- DOM节点的
style
属性对应所有的CSS,可以直接获取或设置,CSS允许font-size
这样的名称,它并非JavaScript有效的属性名,所以需要在JavaScript中改写为驼峰式命名fontSize
// 获取<p id="p-id">...</p> var p = document.getElementById('p-id'); // 设置CSS: p.style.color = '#ff0000'; p.style.fontSize = '20px'; p.style.paddingTop = '2em';
- 方法1: 修改
- 插入DOm
-
innerHTML
可以插入DOM节点,如果这个DOM节点不是空的,innerHTML
会直接替换点原来的所有子节点 -
appendChild
插入一个子节点到父节点 - insertBefore
parentElemnt.insertBefore(newElement,referenceElement);
子节点会插入到referenceElement
之前 -
insertBefore
重点是要拿到一个参考子节点
的引用,很多时候,需要循环一个父节点的所有子节点,可以通过迭达children
属性实现
-
- 删除DOM
- 删除一个DOM比插入要容易的多
- 要删除一个节点,首先要获得该节点本身以及它的父节点,然后调用
removeChild
把自己删除
// 拿到待删除节点: var self = document.getElementById('to-be-removed'); // 拿到父节点: var parent = self.parentElement; // 删除: var removed = parent.removeChild(self); removed === self; // true
- 删除的节点虽不在文档树中,但它还在内存中,
children
属性是一个只读属性,并且它在子节点变化时会实时更新 - 在删除多个节点时,要注意
children
属性时刻都在变化
三、操作表单
- 表单
- 用JavaScript操作表单和操作DOM类似,表单是特殊的DOM
- 常见的表单:
- 文本框,对应的
<input type="text">
,用于输入文本 - 口令框,对应的
<input type="password">
,用于口令 - 单选框,对应的
<input type="radio">
,用于选择一项 - 复选框,对应的
<input type="checkbox">
,用于选择多项 - 下拉框,对应的
<select>
,用于选择一项 - 隐藏文本框,对应的
<input type="hidden">
,用户不可见,提交表单时可以把隐藏文本发送到服务器
- 文本框,对应的
-
input
节点的引用,可以直接调用value
获得对应的用户输入值 - 对于
radio
和checkbox
的value
属性返回的永远是HTML的预设值 - 更新值,直接改
value
,而checkbox
需要设置checked
为true
或fasle
- HTML5控件
- 新增大量标准控件,常用的包括
date
,datetime
,datetime-local
,color
等 - 不支持HTML5的浏览器无法识别新的控件,会被当做
type="text"
来显示 - 支持HTML5的浏览器可以获得格式的字符串
- 新增大量标准控件,常用的包括
- 提交表单
- 方式一:
<form>
元素的submit()
方法提交表单 - 方式二: 响应
<form>
本身的onsubmit
事件,在提交form时作修改 - 安全起见,提交表单时一般不传输明文口令
- 方式一:
四、操作文件
- 上传控件
- HTML表单中,可以上传文件的唯一控件就是
<input type='file'>
- 当一个表单包含
<input type='file'>
时,表单enctype
必须指定为multipart/form-data
,method
必须指定为post
,浏览器才能正确编码并以mutipart/form-data
格式发送表单的数据 - 出于安全考虑,浏览器只允许用户点击
<input type='file'>
来选择本地文件,用JavaScript对其value
赋值是没有效果的
- HTML表单中,可以上传文件的唯一控件就是
- File API
- HTML5的API提供了
File
和FileReader
两个主要对象,可以获得文件信息并读取文件
- HTML5的API提供了
- 单线程执行模式
- 在JavaScript中,浏览器的JavaScript执行引擎在执行JavaScript代码时,总是以单线程模式执行
- JavaScript处理多任务,采用的是异步调用,由于是异步调用,无法知道什么时候操作结束,所以需要先设置一个回调函数,但函数调用完毕时,JavaScript引擎将自动调用我们设置的回调函数
五、Ajax
- Ajax定义
- Asynchronous JavaScript and XML 用JavaScript执行异步网络请求
- Web的运作原理就是:一个Http请求对应一个页面
- 现代浏览器写Ajax主要依靠
XMLHttpRequest
对象,对于低版本的IE,需要换一个ActiveXObject
对象 - 创建
XMLHttpRequest
对象后,要先设置onreadystatechange
的回调函数,在回调函数中,通常只需通过readyState===4
判断请求是否完成,如果已完成,再根据status===200
判断是否是一成功的响应 -
XMLHttpRequest
对象的open()
方法有3个参数,第一个参数指定是Get
还是POST
方式,第二参数指定URL地址,第三个参数指定是否使用异步,默认为true
(该参数不要只用为false
,否则浏览器将停止响应,直到Ajax请求完成) -
send()
方法才真正发送请求,Get
请求不需要参数,POST
请求不需要参数,POST
请求需要把body部分以字符串或者FormData
对象传进去
- 安全限制
- 默认情况下,JavaScript在发送Ajax请求时,URL的域名必须和当前页面完全一致(即域名要相同,协议要相同,端口要相同)
- 用JavaScript请求外域,可以使用Flash插件,或在同源域名下架设一个代理服务器来转发,JavaScript负责把请求发送到代理服务器,或使用JSONP方式(必须为GET请求,并要求返回JavaScript)
-
CORS
是HTML5新的跨域策略,全称Cross-Orign Resource Sharing
,是HTML5规范定义的如何跨域访问资源 -
Access-Control-Allow-Origin
在返回的Access-Control-Allow-Origin
包含本域,b本次请求就可以成功 - 是否跨域成功,取决于对方服务器是否愿意你设置一个正确的
Access-Control-Allow-Orign
,决定权始终在对方手中 -
简单请求
包括GET
、HEAD
和POST
(Post的Content-Type类型,仅限application/x-www-form-urlencoded
,multipart/form-data
和text/plain
,并且不能出现任何自定义头) - 对于
PUT
、DELETE
以及其他类型如application/json
的POST请求,在发送Ajax请求之前,浏览器会先发送一个OPTIONS
请求(成为preflighted
请求)到这个URL上,询问目标服务器是否接受,服务器必须明确指出允许的Method,如:Access-Control-Allow-Methods:POST,GET,PUT,OPTIONS
- 由于以
POST
、PUT
方式传送JSON格式的数据在REST中很常见,所以要跨域正确处理POST
和PUT
请求,服务器必须正确响应OPTIONS
请求
六、Promise
- 定义
-
Promise
有各种开源实现,在ES6中被统一规范,由浏览器统一支持
`use strict`; function test(resolve, reject) { var timeOut = Math.random() * 2; console.log('set timeout to: ' + timeOut + ' seconds.'); setTimeout(function () { if (timeOut<1) { console.log('call resolve()...'); resolve('200 OK'); } else { console.log('call reject()...'); reject('timeout in ' + timeOut + ' seconds.'); } }, timeOut * 1000); } new Promise(test).then(function(result){ console.log('Success'+result); }).catch(function(result){ console.log('failure'+result); })
- 成功执行
then
,失败执行catch
-
Promise
的最大好处是在异步执行的流程中,把执行代码和处理结果的代码清晰地分离 - 并行执行任务:
Promise.all()
- 多个异步任务是为了容错:
Promise.race()
var p1 = new Promise(function (resolve, reject) { setTimeout(resolve, 500, 'P1'); }); var p2 = new Promise(function (resolve, reject) { setTimeout(resolve, 600, 'P2'); }); Promise.race([p1, p2]).then(function (result) { console.log(result); // 'P1' }); //由于p1执行较快,Promise()`then`将先获得结果`p1`,`p2`仍在执行,但执行结果将被抛弃 * 组合使用Promise,可以将很多异步任务以并行和串行的方式组合起来执行
-
七、Canvas
- Canvas用法
- HTML5新增的组件,类似一块幕布,可以在JavaScript在上面绘制各种图表、动画等
- 一个Canvas定义了一个指定尺寸的矩形框,在这个框内可以随意绘制
<canvas id="test-canvas" width="300" height="200"></canvas>
-
canvas.getContext
来测试浏览器是否支持Canvas -
getContext('2d')
方法让我们拿到一个CanvasRenderingContext2D对象,所有绘图操作都需要通过这个对象完成 - `getContext('webgl')方法 是可以使用WebGL规范,允许在Canvas中绘制3D图形
- 基本绘制
- Canvas的坐标系统: Canvas的坐标以左上角为原点,水平向右为x轴,垂直向下为Y轴,以像素为单位,所以每个点都是非负数
-
CanvasRenderingContext2D
对象有若干方法来绘制图形 - Canvas可以绘制基本的形状和文本,还可以实现动画、缩放、各种滤镜和像素转换等高级操作
- 实现复杂操作,可以考虑以下优化方案
- 通过创建一个不可见的Canvas来绘图,然后将最终绘制结果复制到页面的可见Canvas中
- 尽量使用整数坐标而不是浮点数
- 可以创建多个重叠的Canvas绘制不同的层,而不是在一个Canvas中绘制非常复杂的图
- 背景图片如果不变可以直接用
<img>
标签并放到最底层