DOM 编程就是使用 W3C 定义的 API (Application Program Interface)
来操作 HTML 文档 (此处不局限于 HTML,亦可操作 XHTML、XML 等),
使用户可以与进行页面交互。 你需要了解节点、属性、样式等基本 DOM 操作,
DOM 事件模型,数据存储 (Cookie、Storage) 与数据通信 (Ajax) ,
JavaScript 动画,音频、视频、Canvas 等 HTML5 特性,表单、列表操作。

DOM(Document Object Model)为文档对象模型,使用对象的表示方法来表示对应的
文档结构及其中的内容

<p id="target">Hello World!</p>
包含的属性:

p#target
accessKey: ""
align: ""
attributes: Named
NodeMapbaseURI: ""
childElementCount: 0
childNodes: NodeList[1]
children: HTMLCollection[0]
classList: DOMTokenList[0]
className: ""
clientHeight: 0
clientLeft: 0
clientTop: 0
clientWidth: 0
contentEditable: "inherit"
dataset: DOM
StringMapdir: ""
draggable: false
firstChild: text
firstElementChild: null
hidden: false
id: "target"
innerHTML: "Hello, World!"
innerText: "Hello, World!"
isContentEditable: false
lang: ""
lastChild: text
lastElementChild: null
localName: "p"
namespaceURI: "http://www.w3.org/1999/xhtml"
nextElementSibling: null
nextSibling: null
nodeName: "P"
nodeType: 1
nodeValue: null
offsetHeight: 0
offsetLeft: 0
offsetParent: null
offsetTop: 0
offsetWidth: 0
onabort: null
onautocomplete: null
onautocompleteerror: null
onbeforecopy: null
onbeforecut: null
onbeforepaste: null
onblur: null
oncancel: null
oncanplay: null
oncanplaythrough: null
onchange: null
onclick: null
onclose: null
oncontextmenu: null
oncopy: null
oncuechange: null
oncut: null
ondblclick: null
ondrag: null
ondragend: null
ondragenter: null
ondragleave: null
ondragover: null
ondragstart: null
ondrop: null
ondurationchange: null
onemptied: null
onended: null
onerror: null
onfocus: null
oninput: null
oninvalid: null
onkeydown: null
onkeypress: null
onkeyup: null
onload: null
onloadeddata: null
onloadedmetadata: null
onloadstart: null
onmousedown: null
onmouseenter: null
onmouseleave: null
onmousemove: null
onmouseout: null
onmouseover: null
onmouseup: null
onmousewheel: null
onpaste: null
onpause: null
onplay: null
onplaying: null
onprogress: null
onratechange: null
onreset: null
onresize: null
onscroll: null
onsearch: null
onseeked: null
onseeking: null
onselect: null
onselectstart: null
onshow: null
onstalled: null
onsubmit: null
onsuspend: null
ontimeupdate: null
ontoggle: null
onvolumechange: null
onwaiting: null
onwebkitfullscreenchange: null
onwebkitfullscreenerror: null
onwheel: null
outerHTML: "<p id="target">Hello, World!</p>"
outerText: "Hello, World!"
ownerDocument: document
parentElement: null
parentNode: null
prefix: null
previousElementSibling: null
previousSibling: null
scrollHeight: 0
scrollLeft: 0
scrollTop: 0
scrollWidth: 0
shadowRoot: null
spellcheck: true
style: CSSStyle
DeclarationtabIndex: -1
tagName: "P"
textContent: "Hello, World!"
title: ""
translate: true
webkitdropzone: ""
__proto__: HTMLParagraphElement


通过使用 DOM 提供的 API (Application Program Interface)
可以动态的修改节点(node),也就是对 DOM 树的直接操作。
浏览器中通过使用 JavaScript 来实现对于 DOM 树的改动。


DOM 包含
DOM Core
DOM HTML
DOM Style
DOM Event


节点遍历

在元素节点中提取自己所需的节点,并予以操作。
// Document.getElementsByTagName()
// 更具标签名找到目标节点的集合,此例中为 <h1>My header</h1>
var node = document.getElementsByTagName('h1')[0];

// Node.parentNode;
// 获得目标节点的父节点,此例中为 body 元素
node.parentNode;

// Node.firstChild
// 获得目标节点的第一个子节点,此例中为 "My header"
node.firstChild;

// Node.lastChild
// 获得目标节点的最后一个子节点,此例中为 "My header"
node.lastChild;

// Node.previousSibling;
// 获得目标节点的前一个相邻节点
node.previousSibling;

// Node.nextSibling;
// 获得目标节点的下一个相邻节点
node.nextSibling;

节点类型

常用节点类型
ELEMENT_NODE 可使用 Document.createElement('elementName'); 创建
TEXT_NODE 可使用 Document.createTextNode('Text Value'); 创建
不常用节点类型
COMMENT_NODE
DOCUMENT_TYPE_NODE
不同节点对应的NodeType类型

需要清楚节点和元素的区别。我们平常说的元素 其实指的是节点中得元素节点,
所以说节点包含元素,节点还包括文本节点、实体节点等。


元素遍历:
元素节点符合 HTML DOM 树规则,所以它与 DOM 中存在的节点相似。

<p>
Hello,
<em>Xinyang</em>!
回到
<a href="http://li-xinyang.com">
主页
</a>

</p>

// 在选取元素节点后

p.firstElementChild; // <em>Xinyang</em>
p.lastElementChild; // <a href="http://li-xinyang.com">主页</a>

em.nextElementSibling; // <a href="http://li-xinyang.com">主页</a>
em.previousElementSibling; // "Hello,"




节点操作:通过 JavaScript 来获取、创建、修改、或删除节点。

获取节点

父子关系

element.parentNode
element.firstChild/element.lastChild
element.childNodes/element.children
兄弟关系

element.previousSibling/element.nextSibling
element.previousElementSibling/element.nextElementSibling
通过节点直接的关系获取节点会导致代码维护性大大降低
(节点之间的关系变化会直接影响到获取节点),
而通过接口则可以有效的解决此问题。

<ul id="ul">
<li>First</li>
<li>Second</li>
<li>Third</li>
<li>Fourth</li>
</ul>
<p>Hello</p>
<script type="text/javascript">
var ulNode = document.getElementsByTagName("ul")[0];
console.log(ulNode.parentNode); //<body></body>
console.log(ulNode.previousElementSibling); //null
console.log(ulNode.nextElementSibling); //<p>Hello</p>
console.log(ulNode.firstElementChild); //<li>First</li>
console.log(ulNode.lastElementChild); //<li>Fourth</li>
</script>

在节点遍历的例子中,body、ul、li、p节点之间是没有空格的,
因为如果有空格,那么空格就会被当做一个TEXT节点,从而用ulNode.previousSibling获取到得就是一个空的文本节点,而不是 <li>First</li> 节点了。即节点遍历的几个属性会得到所有的节点类型,而元素遍历只会得到相对应的元素节点。一般情况下,用得比较多得还是元素节点的遍历属性。
实现浏览器兼容版的element.children
有一些低版本的浏览器并不支持 element.children 方法,
但我们可以用下面的方式来实现兼容。

<body id="body">
<div id="item">
<div>123</div>
<p>ppp</p>
<h1>h1</h1>
</div>
<script type="text/javascript">
function getElementChildren(e){
if(e.children){
return e.children;
}else{
/* compatible other browse */
var i, len, children = [];
var child = element.firstChild;
if(child != element.lastChild){
while(child != null){
if(child.nodeType == 1){
children.push(child);
}
child = child.nextSibling;
}
}else{
children.push(child);
}
return children;
}
}
/* Test method getElementChildren(e) */
var item = document.getElementById("item");
var children = getElementChildren(item);
for(var i =0; i < children.length; i++){
alert(children[i]);
}
</script>
</body>

4.12

1.属性操作

HTML属性与DOM属性的对应:每个HTML属性都会对应相应的DOM对象属性
下面的代码:
input.id == "username"
input.type == "text"
input.className == "text"
label.htmlFor == "username"

<div>
<label for="username">UserName:</label>
<input type="input" name="username" id="username" class="text" value="">
</div>


出现操作方式:
1.方式一
1.读取属性
input.className;//text
input[id]

2.写入属性
input.value="new value"
input.[id]="new_id"

2.方式二
读:var attr = element.getAttribute("attributeName")
写:element.setAttribute("attributeName",value)


dataset:自定义属性

为 HTMLElement 上的属性也是 data-* 的属性集。
主要用于在元素上保存数据。获取的均为属性字符串。
数据通常使用 AJAX 获取并存储在节点之上。
<div id='user' data-id='1234' data-username='x' data-email='mail@gmail.com'></div>
div.dataset.id; // '1234'
div.dataset.username; // 'x'
div.dataset.email; // 'mail@gmail.com'

dataset 在低版本 IE 不可使用,但可通过 getAttribute 与 setAttribute 来做兼容。




2.样式操作

通过JS动态修改页面的样式

<link rel="stylesheet" type="text/css" href="sample.css">
// var element = document.querySelector('link');
// 对应于 element.sheet

<style type="text/css" media="screen">
body {
margin: 30px
}
</style>
// var element = document.querySelector('style');
// 对应于 element.sheet

// 整个页面的全部样式(不包括行内样式)
document.styleSheets

<p style="color:red">Text Color</p>
// var element = document.querySelector('p');
// 对应于 element.style


1.内部样式表
<style>
body{margin:30;}
p{color: #aaa; line-height:20px}
</style>

// 1.对应所有样式的列表
// body{margin:30;}
// p{color: #aaa; line-height:20px}
element.sheet.cssRules;

// 2.对应相应的 CSS 选择器
// p
element.sheet.cssRules[1].selectorText;

// 3.对应一个样式
// p{color: #aaa; line-height:20px}
element.sheet.cssRules[1]

// 4.对应所有样式的键值对
// color: #aaa; line-height:20px
element.sheet.cssRules[1].style;

// 5.对应的属性值
// #aaa
element.sheet.cssRules[1].stlye.color;
element.sheet.cssRules[1].lineHeight;


2.行内样式表

其对应于 CSSStyleDeclaration 的对象。
element.style.color;
// 获取行内样式的键值对

3.更新样式表

1.
element.style.color = 'red';
element.style.background = 'black';

//result
<div style="color: red; background: black;"></div>

缺点

每个属性的更新都需要一个命令
命名异常(以驼峰命名法命名属性)
element.style.cssText

一次同时设置多个行内样式,其结果同 element.style 单独设置相同。
element.style.cssText = 'color: red; background: black';
增加样式后得到的结果
<div style="color: red; background: black;"></div>
上面的样式会把自身混合到逻辑中

2.更新class
首先需要创建对应样式的 CSS 样式。
.angry {
color: red;
background: black;
}
然后再在 JavaScript 中,在对应的事件中给元素添加需要的类即可。
element.className += ' angry';
增加样式后得到的结果
<div class="angry"></div>

统一更新多个元素样式

以上方法均不适合同时更新多个样式,通过更换样式表的方式则可同时更改多个页面中的样式。将需要的大量样式也在一个皮肤样式表中,通过 JavaScript 来直接更换样式表来进行样式改变。(此方法也可用于批量删除样式)
<link rel="stylesheet" type="text/css" href="base.css">
<link rel="stylesheet" type="text/css" href="style1.css">
element.setAttribute('href', 'style2.css');

获取样式

element.style

其对应的为元素的行内样式表而不是实际样式表。
<input type="checkbox" name="" value="">
element.style.color; // ""
line-height: 200px
window.getComputedStyle()

将需要取出样式的目标元素传入 window.getComputedStyle() 函数中,即可得到对应元素的实际样式。
注意的是这里获取到的样式值为只读属性不可修改!
NOTE:获取的实际为 CSSStyleDeclaration 的实例对象。 NOTE+:此方法不支持 IE9 以下版本,
IE9 中需使用 element.currentStyle 来做兼容。
var style = window.getComputedStyle(element[, pseudoEle]);
<input type="checkbox" name="" value="">
window.getComputedStyle(element).color; // 'rgb(0,0,0)'




4.13
DOM事件
JavaScript 有能力对 HTML 事件做出反应:键盘事件,鼠标事件


事件流
一个 DOM 事件可以分为捕获过程、触发过程、冒泡过程。
DOM 事件流为 DOM 事件的处理及执行的过程

1.事件捕获过程:当 DOM 事件发生时,
它会从window节点一路跑下去直到触发事件元素的父节点为止,去捕获触发事件的元素。
2.Target Phase(事件触发过程):当事件被捕获之后就开始执行事件绑定的代码
3.冒泡过程:当事件代码执行完毕后,
浏览器会从触发事件元素的父节点开始一直冒泡到window元素
(即元素的祖先元素也会触发这个元素所触发的事件)

// 添加Capture阶段事件
docuemnt.addEventListener('click',function(){
alert('capture:'+1);
},true);
tableNode.addEventListener('click',function(){
alert('capture:'+2);
},true);
tdNode.addEventListener('click',function(){
alert('capture:'+3);
},true);

// 添加Bubbling阶段事件
docuemnt.addEventListener('click',function(){
alert('bubble:'+1);
});
tableNode.addEventListener('click',function(){
alert('bubble:'+2);
});
tdNode.addEventListener('click',function(){
alert('bubble:'+3);
});
输出结果为:
capture:1
capture:2
capture:3
bubble:3
bubble:2
bubble:1


事件注册

事件注册,取消以及触发其作用对象均为一个 DOM 元素。

注册事件

eventTarget.addEventListener(type, listener[,useCapture])
evenTarget 表示要绑定事件的DOM元素
type 表示要绑定的事件,如:"click"
listener 表示要绑定的函数
useCapture 可选参数,表示是否捕获过程
useCapture 为设定是否为捕获过程,默认事件均为冒泡过程,只有 useCapture 为 true 时才会启用捕获过程。

// 获取元素
var elem = document.getElemenyById('id');

// 事件处理函数
var clickHandler = function(event) {
// statements
};

// 注册事件
elem.addEventListener('click', clickHandler, false);

// 第二种方式,不建议使用
elem.onclick = clickHandler;
// 或者来弥补只可触发一个处理函数的缺陷
elem.onclick = function(){
clickHandler();
func();
// 其他处理函数
};



取消事件

eventTarget.removeEventListener(type, listener[,useCapture]);
evenTarget 表示要绑定事件的DOM元素
type 表示要绑定的事件,如:"click"
listener 表示要绑定的函数
useCapture 可选参数,表示是否捕获过程
// 获取元素
var elem = document.getElemenyById('id');

// 取消事件
elem.removeEventListener('click', clickHandler, false);

// 第二种方式。不建议使用
elem.onclick = null;


主动触发事件

点击元素,按下按键均会触发 DOM 事件,当然也可以以通过代码来触发事件。
eventTarget.dispatchEvent(type);

// 获取元素
var elem = document.getElemenyById('id');

// 触发事件
elem.dispatchEvent('click');


浏览器兼容型

以上均为 W3C定义的标准定义,但早期浏览器 IE8 及其以下版本,均没有采用标准的实现方式。不过这些低版本浏览器也提供了对于 DOM 事件的注册、取消以及触发的实现。
事件注册与取消,attchEvent/detachEvent。事件触发,fireEvent(e),其也不存在捕获阶段(Capture Phase)。
兼容低版本代码实现

注册事件

var addEvent = document.addEventListener ?
function(elem, type, listener, useCapture) {
elem.addEventListener(type, listener, useCapture);
} :
function(elem, type, listener, useCapture) {
elem.attachEvent('on' + type, listener);
}
取消事件

var addEvent = document.removeElementListener ?
function(elem, type, listener, useCapture) {
elem.removeElementListener(type, listener, useCapture);
} :
function(elem, type, listener, useCapture) {
elem.detachEvent('on' + type, listener);
}
事件对象

调用事件处理函数时传入的信息对象,这个对象中含有关于这个事件的详细状态和信息,它就是事件对象 event。其中可能包含鼠标的位置,键盘信息等。
// 获取元素
var elem = document.getElemenyById('id');

// 事件处理函数
var clickHandler = function(event) {
// statements
};

// 注册事件
elem.addEventListener('click', clickHandler, false);
NOTE:在低版本 IE 中事件对象是被注册在 window 之上而非目标对象上。使用下面的兼容代码既可解决。
var elem = document.getElemenyById('id');

// 事件处理函数
var clickHandler = function(event) {
event = event || window.event;
// statements
};

属性和方法

通用属性和方法

属性

type 事件类型
target(srcElement IE 低版本) 事件触发节点
currentTarget 处理事件的节点
方法

stopPropagation 阻止事件冒泡传播
preventDefault 阻止默认行为
stopImmediatePropagation 阻止冒泡传播
阻止事件传播

event.stopPropagation()(W3C规范方法),如果在当前节点已经处理了事件,则可以阻止事件被冒泡传播至 DOM 树最顶端即 window 对象。
event.stopImmediatePropagation() 此方法同上面的方法类似,除了阻止将事件冒泡传播值最高的 DOM 元素外,还会阻止在此事件后的事件的触发。
event.cancelBubble=true 为 IE 低版本中中对于阻止冒泡传播的实现。
阻止默认行为

默认行为是指浏览器定义的默认行为(点击一个链接的时候,链接默认就会打开。当我们双击文字的时候,文字就会被选中),比如单击链接可以打开新窗口。
Event.preventDefault() 为 W3C 规范方法,在 IE 中的实现方法为 Event.returnValue=false。


常见的事件:

1.window
load 页面全部加载完毕
unload离开本页面前的卸载
error页面异常
abort取消加载

2.image
load图片加载完毕
error图片加载失败
abort取消图片加载
<img src="http://sample.com/img.png" onerror="this.src='http://sample.com/default.png'">

3.UIEvent
resize,scroll
resize 为改变浏览器或iframe的窗体大小时会触发事件,scroll 则会在滑动内容时触发,
作用于 Document 则不会冒泡,作用于内部元素则会冒泡。

4.MouseEvent
click,dbclick,mousedown,mousemove,mouseout,mouseover,mouseup,mouseenter,mouseleave
mouseenter 与 mouseover 的区别为前者在鼠标在子元素直接移动不会触发事件,而后者会触发。 mouseleave 与 mouseout 同上相似。

属性:

clientX, clientX
screenX, screenY
ctrlKey, shiftKey, altKey, metaKey 如果被按下则为真(true)
鼠标的键位:0左边,1中间滚轮,2右边

MouseEvent 顺序

鼠标的移动过程中会产生很多事件。事件的监察频率又浏览器决定。
例子:从元素 A 上方移动过
mousemove -> mouseover(A) -> mouseenter(A) -> mousemove(A) -> mouseout(A) -> mouseleave(A)
例子:点击元素
mousedown -> [mousemove] -> mouseup -> click


5.滚轮事件
wheel
属性:deltaMode滚轮偏移量的单位
deltaY,deltaX,deltaZ

6.FocusEvent:用于处理元素获得或失去焦点的事件
blur,focus,focusin,focusout
blur 失去焦点时,focus 获得焦点时,focusin 即将获得焦点,focusout即将失去焦点。

一个元素失去,即另一个元素获得焦点。这里的 relatedTarget 则为相对的那个元素。
relatedTarget



6.inputEvent

beforeInput,input
beforeInput 为在按键按下后即将将输入字符显示之前生成的事件。
IE 并没有 InputEvent 则需使用 onpropertychange(IE) 来代替。

7.keyboardEvent:键盘事件

keydown,keyup

属性:
key 按下的键字符串
code
ctrlKey, shiftKey, altKey, metaKey
repeat 代表按键不松开为 true
keyCode
charCode
which


8.事件代理
事件代理是指在父节点上(可为元素最近的父节点也可为上层的其他节点)处理子元素上触发的事件,
其原理是通过事件流机制而完成的。可以通过事件对象中获取到触发事件的对象(如下所示)。
var elem = document.getElemenyById('id');
elem.addEventListener('click', function(event) {
var e = event || window.event;
var target = e.target || e.srcElement;
// statements
});
优点

需要管理的事件处理函数更少
内存分配更少,更高效
增加与删除子节点可以不额外处理事件
缺点

事件管理的逻辑变的复杂(因为冒泡机制)





4.15

1.多媒体和图形编程

基本用法
// 音频
// 指定资源类型可以帮助浏览器更快的定位解码
<audio autobuffer autoloop loop controls>
<source src="/media/audio.mp3" type="audio/mpeg">
<source src="/media/audio.oga">
<source src="/media/audio.wav">
<object type="audio/x-wav" data="/media/audio.wav" width="290" height="45">
<param name="src" value="/media/audio.wav">
<param name="autoplay" value="false">
<param name="autoStart" value="0">
<p><a href="/media/audio.wav">Download this audio file.</a></p>
</object>
</audio>

// 视频
<video autobuffer autoloop loop controls width=320 height=240>
<source src="/media/video.oga">
<source src="/media/video.m4v">
<object type="video/ogg" data="/media/video.oga" width="320" height="240">
<param name="src" value="/media/video.oga">
<param name="autoplay" value="false">
<param name="autoStart" value="0">
<p><a href="/media/video.oga">Download this video file.</a></p>
</object>
</video>


测试音频兼容性。
var a = new Audio();
// 检测媒体类型返回
// 支持 - 'maybe' 或 'probably'
// 不支持 - ''
a.canPlayType('audio/nav');



常见的属性:

src:URL地址或者文件地址
controls:是否显示自带的控件(音量,时间轴...)
autoplay:就绪后是否自动播放
preload:(none|metadata|auto),音频在页面加载是否进行加载,并预备播放.使用autoplay会忽略改属性
loop:是否循环



控制多媒体:

方法:load()加载资源,play()播放,pause()暂停播放
属性:playbackRate 1为正常播放,大于1为快速,最大20

currentTime:调整播放时间,单位秒.
volume:取值范围是0--1
muted
paused:暂停值
seeking:是否跳转
ended:是否播放完成
duration:时长
initialTime:媒体开始时间


多媒体相关事件:
loadstart 开始请求媒体内容
loadmetadata:元数据加载完成(时长,编码格式等)
canplay:调用play或者autoplay
waiting缓存数据不够,暂停播放
playing:正在播放
多媒体事件:https://www.w3.org/wiki/HTML/Elements/audio#Media_Events




2.canvas

canvas默认宽高度300和150,可以使用CSS设置,但是因为CSS与JS渲染速度的差异,不建议使用CSS来设置
<canvas id="canvasId" width="300" height="150">
</canvas>

渲染图形上下文:context


var canvas = document.getElementById('canvasId');
var ctx = canvas.getContext('2d');


// 绘画 canvas 的属性
ctx.globalCompositeOperation = 'destination-over';

globalCompositeOperation 为对于 canvas 绘画时的渲染属性设置
包含:source-over,source-in,source-out,source-atop,destination-over,
destination-in,destination-out,destination-atop,lighter,darker,copy,xor

使用context绘图过程

清除画布---绘制图形--保存渲染状态--绘制图形--恢复上下文状态---绘图---

var sun = new Image();
var moon = new Image();
var earth = new Image();

function init() {
sun.src = 'Canvas_sun.png';
moon.src = 'Canvas_moon.png';
earth.src = 'Canvas_earth.png';
window.requestAnimationFrame(draw);
}

function draw(){
var ctx = document.getElementById('canvas').getContext('2d');

ctx.globalCompositeOperation = 'destination-over';
// 清空画布内容
ctx.clearRect(0, 0, 300, 300);

ctx.fillStyle = 'rgba(0, 0, 0, 0.4)';
ctx.strokeStyle = 'rgba(0, 153, 255, 0.4)';

// 保存画布状态
ctx.save();
ctx.translate(150, 150);

// 开始绘制图形

// 地球
var time = new Date();
ctx.rotate(((2*Math.PI)/60)* time.getSeconds() + ((2*Math.PI)/60000)*time.getMilliseconds());
ctx.translate(105, 0);
// 阴影
ctx.fillRect(0, -12, 50, 24);
ctx.drawImage(earth, -12, -12);

// 月亮
ctx.rotate(((2*Math.PI)/6)*time.getSeconds() + ((2*Math.PI)/6000)*time.getMilliseconds());
ctx.translate(0, 28.5);
ctx.drawInmage(moon, -3.5, -3.5);

// 恢复画布状态
ctx.restore();

ctx.beginPath();
ctx.arc(150, 150, 105, 0, Math.PI*2, false);

ctx.stroke();

ctx.drawImage(sun, 0, 0, 300, 300);

window.requestAnimationFrame(draw);
}

init();


4.16

BOM:Browser Object Module

属性:navigator,location,history,screen(屏幕信息)

1.navigator:
navigator.userAgent
Chrome, Mozilla/5.0(Windows NT 6.1; WOW64) Apple WebKit/37.36 (KHTML, like Gecko)
Chrome/40.0.2214.115 Safari/537.36
Firefox, Mozilla/5.0(Windows NT 6.1; WOW64; rv:36.0) Gecko/20100101 Firefox/36.0
IE, Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR 2.0.50727;
.NET CLR 3.5.30729; .NET CLR 3.0.30729;
Media Center PC 6.0; .NET4.0C; .NET4.0E; InfoPath.3; rv:11.0) like Gecko

通过userAgent判断浏览器类型


2.location:
代表浏览器的定位和导航。可以使用 location 来操作 URL 中的各个部分。最常用的有 href 属性,
当前访问资源的完整路径。

方法:assign(url) 载入新的 url,记录浏览记录
replace(url) 载入新的 url 不记录浏览记录
reload() 重新载入当前页


3.history

浏览器当前窗口的浏览历史。

方法
back(int) 后退
forward(int) 前进
go(int) 正数向前,负数向后
screen

其中包含屏幕信息。其中 avil- 开头的属性为可用属性,其余则为显示器设备属性。


4.window方法
alert(),confirm()返回真假,prompt()返回用户输入值
(对话框会堵塞主线程)
setTimeout(),setInterval(),open(),clos()
var w = window.open('subwindow.html', 'subwin', 'width=300, height=300, status=yes, resizable=yes');

// 既可关闭窗口
w.close();


事件:
load:文档和所有的图片加载完毕
unload:离开当前文档
beforeunload:和 unload 类似,但是它提供询问用户是否确认离开的机会
resize:拖动改变浏览器窗口的大小
scroll:拖动浏览器时



二.网络数据通信

HTTP:HyperTextTransferProtocol,超文本传输协议
客户端发起请求并创建端口,服务器在端口监听客户端的请求,server在接收到请求后返回状态和请求的内容

HTTP网页浏览的过程:
网页浏览全过程 (粗浅流程)
一.域名解析
1.搜索浏览器自身 DNS 缓存
2.搜索操作系统自身 DNS 缓存(如上一级未找到或已失效)
3.读取本地 HOST 文件 (如上一级未找到或已失效,/etc/hosts)
4.浏览器发起 DNS 系统调用请求
ISP 服务器查找自身缓存
ISP 服务器发起迭代(逐域寻找需要的地址)请求
二.得到请求资源的 IP 地址
三.发起 HTTP “三次握手”(下面为一个超级简化版)
1.建立连接,等待服务器确认
2.服务器接受请求,回复客户
3.客户端与服务器连接成功(TCP/IP 连接成功)
四.客户端根据协议发送请求
五.服务器根据请求返回客户需求资源
六.客户获得资源



常用的HTTP方法:
GET,POST,PUT,DELETE,HEAD,TRACE,OPTIONS

URL的组成:
http://www.github.com:8080/index.html?user=li-xinyang&lang=zh-CN#home
| | | | | |
protocol hostName port pathname search hash


HTTP 版本

HTTP/0.9 1991年 HTTP 原型,存在设计缺陷
HTTP/1.0 第一个广泛应用版本
HTTP/1.0+ 添加持久的 keep-alive 链接,虚拟主机支持,代理连接支持,成为非官方的事实版本
HTTP/1.1 校正结构性缺陷,明确语义,引入重要的新能优化措施,删除不好的特性(当前使用版本)


AJAX

AJAX(Asynchronous JavaScript and HTML)异步获取数据的概念,由 Jesse James Garrett 在2005年提出。

AJAX 调用

三部完成 AJAX 调用
1.创建 XHR 对象
2.处理返回数据及错误处理
3.发送请求
var xhr = new XMLHttpRequest();

xhr.onreadystatechange = function(callback) {
if (xhr.readyState === 4) {
if ((xhr.status >== 200 && xhr.status < 300) || xhr.status === 304) {
callback(xhr.responseText);
} else {
console.error('Request was unsuccessful: ' + xhr.status);
}
}
}

xhr.open('get', 'exmaple.json', true);
xhr.setRequestHeader('myHeader', 'myValue');
xhr.send(null);


open

xhr.open(method, url[, async = true]);
method 为上面说过的 HTTP 方法(例如,GET、POST)
url 为资源地址
async 默认为真,用于设置异步请求

setRequestHeader

xhr.setRequestHeader('myHeader', 'myValue');

xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
用于设置头部的键值对。
send

xhr.send([data=null]);

xhr.send()
数据可包含字符串或表单数控,但需要提前为 RequestHeader 做设置。

请求参数序列化

将查询参数使用字符串,跟入资源地址中。
xhr.open('get', 'example.json?' + 'name=value&age=value', true);
对象转换字符串的函数实现
function serialize(data) {
if (!data) return '';
var pairs = [];
for (var name in data) {
if (!data.hasOwnProperty(name)) continue;
if (typeof data[name] === 'function') continue;
var value = data[name].toString();
name = encodeURIComponent(name);
value = encodeURIComponent(value);
pairs.push(name + '=' + value);
}
return pairs.join('&');
}
GET 请求
var url = 'example.json?' + serialize(formData);
xhr.open('get', url, true);
xhr.send(null);
POST 请求
查询参数需要作为 send() 的存数传入。
xhr.open('get', 'example.json', true);
xhr.send(serialize(formData));

JSONP
全程为 JSON with Padding(填充式 JSON),它利用 <script> 可以跨域的原理。请求一段 JavaScript 代码,然后执行 JavaScript 代码来实现跨域。
function handleResponse(response) {
alert(response.name);
}

var script = document.createElement('script');
script.src = 'http://localhost:3000/json?callback=handleResponse';
document.body.insertBefore(script, document.body.firstChild);



4.21

一.数据存储


Cookie:小型文本,4kb左右,又键值对构成,分号隔开,多数是在服务器端对Cookie进行设置
在头文件中set-Cookie来对Cookie进行设置,页面可以访问当前页面的Cookie,
也可以访问父域的Cookie

属性:
Name:名称必填
Value:值,必填
Domain:当前文档域,作用域
Path:当前文档路径,作用路径
Expires(时间戳)/Max-Age(毫秒数值)
Secure:https协议时生效


读取Cookie:并转换为JS对象

function getCookie(){
var cookie = {};
var all = document.cookie;
if (all === '') return cookie;

var list = all.split(';');

for(var i = 0,len = list.length;i<len;i++){
var item = list[i];
var p = item.indexOf('=');
var name = item.substring(0,p);
name = decodeURIComponent(name);

var value = item.substring(p+1);

value = decodeURIComponent(value);
cookie[name] = value;


}

return cookie;

}

设置与修改
document.cookie = 'name=value';

下面为设置Cookie值的封装函数:

function setCookie(name,value,expires,path,domain,secure){
var cookie = encodeURIComponent(name) + '=' +encodeURIComponent(value)
if (expires){
cookie += ';expires=' + expires.toGMTString();

}

if (path){
cookie += ';path=' + path;
}

if (domain){
cookie += ';domain=' +domain;
}

if (secure) {
cookie += '; secure=' + secure;
document.cookie = cookie;

}




}

删除Cookie值的函数

function removeCookie(name,path,domain){
document.cookie = 'name=' + name +';path=' + path + ';domain=' + domain + ';max-age=0';

}


Cookie缺陷
流量代价,安全性,大小限制



二.Storage

作用域不同分为LocalStorage和SessionStorage,前者在用户不清理的情况下时间
默认为永久,后者默认为浏览器的会话时间(浏览器不同窗口直接不共享 Session Storage)

不同浏览器对其实现的不同导致支持大小也不太,通常在 5MB 作用。
对象

读取

localStorage.name
添加或修改
localStorage.name = 'Value';
浏览器只支持字符串在 Storage 中的存储。
删除

delete localStorage.name
API

使用 API 操作 Storage 可以进行向下兼容的功能,在不支持的情况下可以用 Cookie 来代替。
localStorage.length 获取键值对数量
localStorage.getItem('name') 获取对应值
localStorage.key(i) 对应值的索引获取
localStorage.setItem('name', 'value') 设置键值对
localStorage.removeItem('name') 删除一个值
localStorage.clear() 删除所有数据
posted on 2016-04-27 18:41  农场的小伙  阅读(484)  评论(0编辑  收藏  举报