DOM编程艺术

element.chidren和element.childNodes的区别

element.children是Element的属性,所以它其中只包含element类型的节点,而不包含文本类型的元素

element.childNodes是Node的属性,所以它包含所有的子节点,包括元素类型的节点和文本类型的节点

例如

var el=document.createElement("div");
el.textContent="foo"
el.childNodes.length===1;// TextNode is a node child
el.children.length===0;// no Element children


##获取节点
- 父子关系
-ParentNode
-firstChild、lastChild、childNodes
- 兄弟关系
-previousSibling、nextSibling
-previousElementSibling、nextElementSibling
**但是这些访问关系很不稳定,一旦页面结构变化,可能会导致代码不能用**

#### getElementById

element.getElementById(id) //返回一个Node元素

#### getElementsByTagName

collection = element.getElementsByTagName(TagName) //返回一个数组,可以通过下表访问,这个集合是动态的,如果页面中的元素由于其他的操作被删除或者增加,collection指向的内容也会随之变化

#### getElementsByClassName

collection = element.getElementsByClassName(ClassName Classname) // 返回一个数组,其中classname可以有多个,切顺序无所谓,返回同时有这些类名修饰的元素

**IE6、7、8不支持该属性**

####querySelector/All

list = element.querySelector/All(selector)
//例如
var users = document.querySelector('#users') //按照id选择
list = users.querySelectorAll(".user") //类选择器,选择所有类名包含user的
//等同于
list = document.querySelectorAll("#users .user") //但是list是非动态的,所以当其他操作更改了list选中的内容后list的内容是不会修改的


##创建节点
.createElement()

##修改节点
.textContent = "修改后的文本"
.innerText也经常用到,但是不符合W3C标准,且firefox不支持该属性,textContent符合标准,但是ie9以下版本不支持,所以为了兼容性,有时需要用特殊处理

##添加节点

element.appendChild(achild)
var achild = element.insertBefore(achild, referenceChild)


##删除节点

element.removeChild(achild)
.innerHTML = "" //innerHTML包含的是包含标签在内的所有内容,直接将其内容赋值为空串也可以起到删除的作用


![删除大段HTML代码](http://upload-images.jianshu.io/upload_images/3770010-3ffca4613926cdc9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

##属性操作
dom对象实际上是一个{}括起来的字典,所有的属性都可以通过[]和点号来访问。所有用属性访问器访问到的属性都是一个经过转换的实用对象。如下图:获取到的字符串会被转换为String类型,数字会被转换为Number类型,函数会被封装到另一个函数中。

<input class="u-txt" maxlength="10" disabled onclick="showSuggest();">

input.attributeName

| attributeName | value | type | 
|:----------:|:--------:|:-------:|
| className | "u-txt" | String |
| maxLength | 10 | Number |
| disabled | true | Boolean |
| onclick | function onclick(event) {...} | Function |

例如一个输入框对应的dom对象是input。

####通过属性访问器读写
好处是可以访问到一个使用对象,坏处是有些属性的名字会有冲突需要单独记忆
**** 注:由于某些css属性名和js的关键字冲突,某些属性的访问名字需要特殊记忆,如:
类名:input.className
for属性:input.htmlFor
等.......

input.value = "输入的内容" //就可以设置属性
input["disabled"] = true //两种访问方式

####通过attribute读写
通过attribute读写不会存在属性名和关键字冲突的问题,但是通过getAttribute操作得到的属性都是字符串

input.getAttribute("attributeName")


| attributeName | value | type |
|:-------------------:|:-------:|:------:|
| class | "u-txt" | String |
| maxLength | "10" | String |
| disabled | "" | String |
| onclick | "showSuggest(); " | String |

var attribute = element.getAtrribute(String attributeName)
var attribute = element.setAttribute(String name, value)
//例如:
var attribute = input.getAttribute("class")
input.setAttribute("disabled", "") //只要disabled出现过,他就是disabled的,value无所谓,数字,布尔,字符串,都行


####通过dataset访问
在属性名前加data-符号即可,dataset一般是用来做自定义属性的,如下图

![Paste_Image.png](http://upload-images.jianshu.io/upload_images/3770010-5fc3a846eca73ae9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

##样式操作
####样式访问
css样式表中的内容可以通过js进行动态的修改,其中,外部引入的文件以及被<style>标签围绕的样式是通过element.sheet访问的,而标签内部的style属性包围的值对应的js是element.style。
例如

<style>
body{margin: 30}
p{color:#aaa; line-height: 20px;}
</style>

element.sheet.cssRules[1].style //{color: #aaa, line-height: 20px}, 类型是CSSStyleDeclaraiton的类
element.sheet.cssRules[1].selectorText //p
element.sheet.cssRules[1].style.lineHeight //line-height

内部样式访问中

element.style.lineHeight //element.style同样是一个CSSStyleDeclaration

以上的访问方式的缺陷在于,属性名和css中的名字不完全一样,使用上不是很方便,因此,

element.style.cssText = "border-color: red; color: #bbb"; //也是一种访问方式,可以直接修改css内部的文本

好的编程习惯要求尽量不在代码逻辑中修改css,因此如果要对元素的样式进行修改,一般建议事先在css中写好另外一种样式,并在通过修改类的方法来修改样式,如,

element.className += "another_class" //会自动覆盖其他的样式

而如果要对大量元素进行替换,如要修改整个页面的样式和风格,可以直接更改应用于本页面的css文件,如

<link id = "skin" rel="stylesheet" href="css/skin1.css">

document.getElementById("skin").href = "css/skin2.css" //对整个页面的css文件进行了替换

####样式获取
即如何获取实际样式,显然element.style是不行的,因为如果元素没有内前样式的话,这种方式是不能获取到实际样式值,本标题指的是如何获取实际样式的值

var style = window.getComputedStyle(element [,pseudoElt]);
//返回的是一个CSSStyleDeclaration的类,但是是一个只读属性,不可以改,但获取到的确实是一个元素的实际属性,pseudoElt属性一般不常用


##事件
事件有一个事件流的概念,控制的时间的发生顺序,事件流分为3个阶段

![事件流](http://upload-images.jianshu.io/upload_images/3770010-43f9b281c762a0a9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

1.capture(捕获阶段)
2.target(目标阶段)
3.upward(回溯阶段)
具体见
([http://www.w3.org/TR/uievents/#dom-event-architecture](http://www.w3.org/TR/uievents/#dom-event-architecture) )
####事件的注册

eventTarget.addEventListener(type, listener[, useCapture])
//第一个是事件类型,如点击,hover等,第二个是监听器,即事件触发后要调用的函数,第三个参数可选,是一个布尔值,当为false时,回调函数在upward阶段触发,当为true时,回调函数在capture阶段触发,默认值为false。useCpature的直观表现就是控制先触发父元素的事件还是先触发子元素的时间
//当事件为点击事件的时候,也可以eventTarge.onclick = listener来注册,但是如此注册则只能有一个监听器,不可以有多个。


####事件取消注册

eventTarget.addEventListener(type, listener[, useCapture])


####事件触发
1. 事件发生触发
2. 代码触发

eventTarget.dispatchEvent(type)


####事件对象
事件对象指的是当一个时间被触发的时候,listener有一个参数为event会被传入,event中包含事件的一些相关信息,如点击事件鼠标的坐标,键盘中shift是否被按下等信息,event被称为事件对象。
*注意:在ie9以下的ie版本中,event不是被传入的,而是保存在window.event中,因此需要如下代码来做兼容*

event = event || window.event

事件对象有些属性和方法
属性:
- 继承了UIEvent的所有属性
- type //事件类型,如点击事件等等

type = event.type

- targets(srcElement)//目标节点,即触发事件的标签 ,ie低版本中属性名为srcElement,其他浏览器为targets
- currentTarget //当前事件位于哪个标签

targets = event.targets || event.srcElement

方法:
- stopPropagation //阻止事件继续传播

event.stopPropagation()

- preventDefault //阻止默认事件,如点击a标签会默认进行页面跳转,如果要阻止默认事件,而仅仅是调用listener,则需要调用这个方法

event.preventDefault()

- stopImmediatePropagation //不仅阻止事件继续传播,也中断了当前节点后续监听器的触发,即如果当前节点注册了多个监听器,则之后的监听器也不再执行

event.stopImmediatePropagation()


####事件分类(type)
![事件分类](http://upload-images.jianshu.io/upload_images/3770010-6bcae3a62817b62a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
其中,WheelEvent继承自鼠标事件,是滚轮事件。这些事件中最常用的就是鼠标事件

######事件
| 事件类型 | 触发场景 | 是否冒泡 | 元素 | 默认事件 | 例子      | 
|:------------:|:------------:|:------------:|:------:|:------------:|:----------:|
| load | 当一个元素加载完成时,如window、image等 | NO | window\document\element | None | window\iframe\image
| unload | 当页面退出时 | NO | window\document\element | None | window |
| error | 报错,如设置了错误的url等| NO | window\document\element | None | window\image |
| select | 内部元素被选中时 | NO | element | None | input\textarea |
| abort | 加载被终止 |  NO | window\document\element | None | window\image |

######UI事件(UIEvent)
| 事件类型 | 触发场景 | 是否冒泡 | 元素 | 默认事件 | 例子      | 
|:------------:|:------------:|:------------:|:------:|:------------:|:----------:|
| resize | 修改窗体大小时 | NO | window\element | None | window\iframe
| scroll | 页面发生滚动 | 当元素scroll时YES,当浏览器滚动时NO | window\element | None | document\div |

######鼠标事件(MouseEvent)
鼠标事件类型:
click:鼠标点击并松开后触发
dbclick:双击后触发
mousedown:鼠标键按下
mouseup:鼠标键松开
mousemove:鼠标移动
mouseenter:当鼠标进入某个元素A时,A会触发该事件,但是当鼠标再次从A进入A的子元素时,不会再次出发
mouseleave:与enter对应,鼠标离开某个元素A时触发,但是当鼠标进入A的子元素时,不会触发,因为想到于此时鼠标仍然处于A的内部
mouseover:功能与mouseenter类似,但是会级联触发,即当一个元素触发mouseover事件时,该元素的所有祖先元素也会触发over。因此,当鼠标从A中移到A的子元素 或 从A的子元素移到A都会触发mouseover
mouseout:与mouseleave类似,但是会级联触发,与mouseover相对应,即当一个元素触发mouseout时,它的所有祖先元素都会触发这个事件。

event.clientX, event.client.Y //鼠标距离浏览器最左、上端的距离
event.screenX, event.screenY//鼠标距离屏幕最左、上端的距离
event.ctrlKey, event.shiftKey, event.altKey, event.metaKey //鼠标事件触发时是否同时有键盘上的一些按键被按下,类型为boolean。其中metaKey在Windows上代表“Win键”,在Mac上代表“command键”
event.button //值为0,1,2分别代表鼠标按下的左、中、右键,4,5代表浏览器的前进和后退键,即部分鼠标拥有的侧面的按键

鼠标事件的触发顺序:
1.当鼠标从A元素上方经过
mousemove(A的某祖先元素) -> mouseover(A) -> mouseenter(A) -> mousemove(A) -> mouseout(A) -> mouseleave(A)
2.当鼠标在A中点击
mousedown -> mouseup -> mouseclick

######焦点事件(FocuseEvent)
| 事件类型 | 是否冒泡 | 元素 | 默认事件 | 元素例子 | 何时触发 |
|:------------:|:------------:|:------:|:------------:|:------------:|:------------:|
| blur | NO | Window\Element | None | window\input | 失去焦点时 |
| focus | NO | Window\Element | None | window\input | 获得焦点时 | 
| focusin | YES | Window\Element | None | window\input | 即将获得焦点时 |
| focusout | YES | Window\Element | None | window\input | 即将失去焦点时 |
*“冒泡”指的是是否会级联触发,即当一个元素触发该事件时,其祖先元素会不会触发该事件*
*后两个主要就是在blur和focus被触发前会率先触发*

事件属性:
- 继承了UIEvent的所有属性
- relatedTarget:当一个元素失去焦点时,会有另外一个获得焦点,反之亦然。此时,获得焦点和失去焦点的这两个元素互为relatedTarget

######输入事件(InputEvent)
事件类型
- beforeInput:指敲击键盘后,输入的内容还没显示出来时触发的事件
- Input:指敲击键盘后,输入的内容已经显示出来时触发的事件

######键盘事件(KeyboardEvent)
事件类型
- keydown
- keyup
属性
- 继承的属性
- key:按下什么键盘,String类型,按键类型,如:数字键,控制键等
- code:按键码,String类型
- ctrlKey、altKey、metaKey、shiftKey:布尔型,这些键是否被按下
- repeat:某个键是否一直按着不放

####事件代理

<ul>
<li></li>
<li></li>
<li></li>
</ul>

例如上述代码,如果所有的li都具有相同的事件和事件处理过程,我们逐个为标签注册监听器,一个方便的方法是只为ul注册监听器而不管li,因为很多的事件都会冒泡,因此同样的事件如果在li上触发了,那么也会在ul上触发。这个方法称为事件代理
- 好处:减少代码,方便修改 
- 坏处:当一个父元素有太多的监听器要处理时,会使得代码难以维护,如理论上所有会冒泡的事件都可以挂在window上,通过代理来触发,但是这显然不是一个好的决定

##数据通信
网页的请求是先由浏览器发送一个请求到服务器(请求报文),然后服务器再返回内容给浏览器,然后浏览器将内容显示出来。
####请求报文格式
1.头行
- 请求方法
- 主体地址
- http版本

2.头部
- Accept:http接受的媒体类型
- Accept-Encoding:媒体类型的编码方式
- Accept-Language:浏览器端可以接受的语言
- Cache-Control:缓存策略
- Cookie:想服务器发送的cookie内容
- User-Agent:浏览器的名词和版本


3.请求体
GET方法请求体为空

####响应报文格式
1.头行
- HTTP版本
- 状态码
- 状态码描述

2.头部
- Server:服务器端的服务器是哪种服务器

3.相应内容
请求获得的内容主题

####请求方法
| 方法 | 描述 | 是否含有主体 |
|:-------:|:-------:|:-----------------:|
| get | 获取一份文档 | NO |
| post | 发送需要处理的数据 | YES |
| put | 将请求的主体部分存储在服务器上 | YES |
| delete | 删除一份文档 | NO |
| TRACE | 对报文进行追踪| NO |
| OPTIONS | 决定可以在服务器上执行哪些方法 | NO |
| HEAD | 只获取文档的头部 | NO |

####URL构成
protocol://host/pathname ? search # hash

例如:
http://www.163.com:8080/index.html?r=admin#news


####HTTP版本
目前广泛使用的是http 1.1版本

####HTTP状态码
| 状态码 | 状态吗描述 | 含义 |
|:---------:|:---------------:|:-----------:|
| 200 | OK | 一般用于响应GET和POST方法 | 
| 301 | Moved Permanently | 请求的资源已经转移,浏览器会自动跳转 |
| 304 | Not Modified | 所请求的数据未修改,浏览器读取缓存 | 
| 400 | Bad Request | 请求语法错误,服务器无法理解 |
| 404 | Not Found | 资源未找到 | 
| 500 | Internal Server Error | 服务器内部错误 | 

####Ajax
通信流程
1. 创建一个XHR对象,包含3个关键属性
 - readyState
 - status
 - responseText
刚创建时,readyState的值为1

var xhr = new XMLHttpRequest()

2. 调用open()方法,此时readyState变为2,调用时会定义请求的方法,请求的内容等等

xhr.open(method, url[ ,async = true]) //method是请求方法,如get、post等,url是请求地址,async表示开启一个异步请求,默认为true
xhr.sendRequestHeader( header, value) //也可以不设置

3. 调用send()方法,此时readyState变为3, 开始像服务器发送请求

xhr.send([data = null]) // 发送一个请求
//当使用post方法时,请求参数就通过data传入,如果是get方法,则请求字符串在open时url中设置

4. 服务器端返回数据,此时readyState变为4,status变为返回的状态码,如200,responsText变为请求得到的内容

> **同源策略**
> 如果两个页面具有相同的协议,主机,端口,那么两个页面则同源。同一个源内的网页在访问时url都是用的是相对地址

> **跨域资源的访问**
> Frame代理,JSONP代理等
> Frame代理资料 [https://github.com/genify/nej/blob/master/doc/AJAX.md](https://github.com/genify/nej/blob/master/doc/AJAX.md)
> CORS:[http://www.w3.org/TR/cors/](http://www.w3.org/TR/cors/)

##数据存储
####cookie
形式:键值对
属性:

| 属性名 | 默认值 | 作用域 | 
|:---------:|:---------:|:---------:|
| name | | 名 | 
| value | | 值 |
| Domain | 当前文档域 | 作用域 |
| Path | 当前文档路径 | 作用路径 |
| Expries/Max-age | 浏览器会话时间 | 失效时间 |
| Secure | false | http协议时生效 | 
作用域和作用路径对应url中的域名和路径名,例如:当域名为163.com时,则访问163.com之下的所有域名都会携带此cookie,路径名也相同,当路径名为/learn时,则访问该路径以及其所有子路径都会携带此cookie

cookie的设置和修改

document.cookie = 'name = value; secure = false';
//或者
function setCookie(name, value, domain, path, expires, secure){
var cookie = encodeURIComponent(name) + '=' + encodeURIComponent(value);
if(expries)
cookie += '; expires = ' + expries.toGMTString();
if(path)
cookie += '; path = ' + path;
if(domain)
cookie += '; domain = ' + domain;
if(secure)
cookie += '; secure = ' + secure;
document.cookie = cookie;
}

cookie的删除
- 指定cookie的max-age属性设置为0即可

Cookie的缺陷
- 明文传递,缺乏安全性
- 不同的网页跳转时可能会携带cookie,会产生巨大的流量
- 大小限制,浏览器对cookie的大小都会有限制,一般为4kb左右,所以传输内容有限

由于以上缺陷,目前很多网页使用Storage来替代cookie

####Storage
分为localStorage和SessionStorage两种。

######localstorage
作用域由协议,主机名,端口三个参数来确定。同一个浏览器内多个窗口可以共享
######sessionStorage
作用域由协议,主机名,端口,窗口来确定,也就是说sessionStorage的作用域由一个窗口独享而不能延伸到同一个浏览器的其他窗口

大小一般为5MB左右,由于要在内存中存放,一般不建议开放过大

######JS接口
读取:localStorage.name
添加修改:localStorage.name = "aaa"
删除:delete localStorage.name
localStorage.length //键值对的数量
localStorage.getItem("name"), localStorage.key(i) //name是键值,i是索引,区间是0~length-1
localStorage.setItem("name", "aaa")
localStorage.removeItem("name")
localStorage.clear() //清空所有内容


##JS动画
JS动画三要素
- 对象:dom对象,即“谁在动”
- 属性:即dom对象的属性,如宽高、背景颜色、透明度等等
- 定时器:如setInterval、setTimeout、requestAnimationFrame等,可以利用定时器不断的改变对象的属性,从而实现动画的效果


1. setInterval

var intervalID = setInterval(func, delay[, para1, para2, ...])//设置动画
//func参数是一个函数,delay规定func执行的时间间隔,后面的参数是传递给func函数的参数
clearInterval(intervalID)//清除动画


2. setTimeout

var timeoutID = setTimeout(func[, delay, para1, para2, ...])
//setTimeout函数只执行一次,delay表示从何时开始执行,默认立即执行


3. requestAnimationFrame

var requestID = requestAnimationFrame(func) //不用设置间隔时间
cancelAnimationFrame(requestID) //清除动画
//这个函数没有间隔时间这个选项,由浏览器自己控制时间,间隔和显示器的刷新一帧的时间相等,显示器每刷新一次,func执行一次,这样的动画效果一般会更加流畅


##音频与视频

![视频音频、图形](http://upload-images.jianshu.io/upload_images/3770010-a44f6428be5e730d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
video和audio标签非常像,但是由于video一般用于视频,所以需要指定宽高,而audio不需要,除此之外,两个标签的属性基本上都一样

<audio>
<source src="music.mp3" type="audio/mpeg">
<source src="music.wav" type="audio/x-wav">
<source src="music.ogg" type="audio/ogg">
</audio>

<video>
<source src="movie.mp4" type="video/mp4; codecs='avc1.42E01E, mp4.a.40.2'">
<source src="movie.webm" type="video/webm; codecs='vp8, vorbis'">
</video>

var a = new Audio();
a.canPlayType('audio/nav')//可以用来检测浏览器是否支持这种audio格式,如果不支持,则返回空串,否则返回“probaly或者maybe”


####<video>和<audio>的属性

| 属性名 | 是否必须 | 默认值 | 音频文件的URL |
|:---------:|:------------:|:-----------:|:-------------------:|
| src | 是 | | 音频文件的URL |
| controls | 否 | false | 是否向用户显示控件 |
| autoplay | 否 | false | 是否自动播放 |
| preload | 否 | none | 可取值为none, metadata, auto。none是不预加载,metadata是只加载源信息,不加载资源,auto是自动加载资源。音频在页面加载时预加载,并准备播放,如果设置了autoplay,则忽略此属性 |
| loop | 否 | false | 音频结束时是否循环播放 | 

####视频音频的JS接口
load() //加载资源
play() //开始播放
pause() //暂停
muted //是否静音
volume //音量,0——1之间的浮点数
playbackRate //播放速度,恒正,正常速度为1
currentTime //当前时间,单位为s
**前三个为方法,后面4个位属性,以上属性都是可以修改值的**

paused //文件是否暂停
seeking //是否正在发生跳转
ended //是否播放完成
duration //媒体总时长
initialTime //默认起始播放时间
**以上属性都是只读属性**

loadstart //开始请求媒体内容
loadmetadata //已经加载完成了源信息
canplay //已经加载了一些内容,可以开始播放了
play //调用了play()方法,或者设置了自动播放并已加载完资源
waiting //缓冲数据不够,播放暂停
playing //正在播放
**以上都是可以监听的事件,一共有12个事件可以监听,以上只是一部分**

####canvas

<canvas id="aCanvas" width="300px" height="150px"></canvas>

var canvas = document.getElementById("aCanvas")
var ctx = canvas.getContent('2d') //获取一个渲染上下文的对象
ctx.globalCompositeOperation = “source-in”
//globalCompositeOperation的的属性值是一个字符串,可选值见下图,表示画布上的多个内容被绘制时的显示内容。下图中,蓝色正方形先画,红色的圆形后话,不同的属性值分别可以确实他们的交叠次序,显示互相的交集补集等


![组合操作](http://upload-images.jianshu.io/upload_images/3770010-d314fb7fa2d835c9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

##BOM(Browser Object Model)
广义上来讲,JS包含三个部分:
ECMAScript:即狭义的JS,也就是JS的语法等内容
DOM(Document Object Model):已经学习过,是前端JS进行文档内容操作的接口,顶层对象为window.document
BOM:BOM包含DOM以及history, location, navigator等一些属性和方法,BOM的顶层对象是window

*分了三个部分,是因为,虽然从所属关系来讲,document属于window,但是W3C对于document的一系列内容都是有标准规定的,而window由于是浏览器相关,并没有统一的标准,所以由浏览器厂商自行决定其接口等内容*

![BOM和DOM的包含关系](http://upload-images.jianshu.io/upload_images/3770010-2f3ae0034edc4f5f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

| 属性名 | 描述 | 
|:---------:|:---------:|
| navigator | 浏览器信息,包含浏览器版本,内核版本,浏览器运行平台等诸多信息 |
| location | 浏览器定位和导航,包括端口,协议,主机地址,路径等诸多地址 |
| history | 窗口浏览器历史,仅记录本窗口中的浏览历史|
| screen | 屏幕信息,包括屏幕宽高、色域等 |

####location的方法

location.replace(url) //跳转到另一个网页,不记录浏览历史
location.assign(url) //跳转到另一个网页,记录浏览历史
location.reload(url) //重载本页面


####history

history.go( Number length) //有一个参数,可正可负,代表将网页前进或者后退几步
history.back() //网页后退一步,没有参数,等同于history.go(-1)
history.forward() //网页前进一步,没有参数,等同于history.go(1)


####window下的一些方法
| 方法名 | 描述 |
|:---------:|:-------:|
| alert(), comfirm(), prompt() | 三种对话框 |
| setInterval(), setTimeout() | 计时器 |
| open(), close() | 打开新窗口,关闭窗口 |
window.open(url, name, String attr) //url是新窗口的地址,name是给新窗口起一个名字,attr是一个字符串,是新建窗口的一些属性,如宽高等

####window下的一些事件
| 事件 | 描述 |
|:-------:|:---------:|
| load | 文档和所有资源加载完毕时触发 |
| unload | 离开文档前 | 
| beforeunload | 和unload类似,但它提供询问用户是否离开的机会 |
| resize | 拖动改变浏览器大小时 |
| scroll | 拖动滚动浏览器时 | 

##表单操作

<form method=“post” action="url" enctype="xxxxx">
<fieldset>
<legend>标题</legend>
<p><label></label><input></p>
<input required>
</fieldset>
</form>



![fieldset](http://upload-images.jianshu.io/upload_images/3770010-9897b108ecd2d43d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

表单中的数据需要传送到服务器以便处理,每一个表单中的数据都是name:value键值对,所以每个被提交的数据都应该有name和value,当然,默认输入框中的内容也就是input标签的value值

form标签是表单的核心,它的可以设置的属性有
name,target,method,autocomplete,accept-charset,action,enctype,novalidate等

####name
var form1 = document.forms.name
即只要写出name就可以直接获取到表单

####autocomplete
值为一个字符串,可以是“on”或者“off”,若是on的话,输入框被点击时被给一些输入提示,提示源有可能是之前的填写历史等

####elements
form标签外的元素如果申明的form属性,则这个标签虽然在空间上独立于form之外,但是在功能上却隶属于form。
form的elements包含的内容就包括form的子元素或者form外部隶属于form的元素(除了所有的图片元素),即<input type="image"/>标签不会被囊括在elements中

<form name = “ff” id="f">
<p><label><input name="a"/></label></p>
</form>
<p name="b" form="f"><label><input/></label></p>

var form1 = document.forms.ff
ff[name]
ff[index]
ff.elements[name]
ff.elements[index]
//以上4个方法都可以访问表单元素的内容


####form[name]

ff['a'] //注意!!此处可以返回id或者name为a的元素,而如果取到的内容为空,则返回name或者id为a的img元素,即优先返回非img元素
//如果有多个同名的元素,则返回的是一个动态集合
//一旦用form[name]取过某个标签,即使这个标签改名了,依然可以用原名字来取,而form.elements[name]却必须使用新的名字来取


####form.reset()
可以被reset的控件有keygen,input,output,select,textarea
reset的时候会触发reset事件,但不会触发change和input事件
如<input type="file">如果选择了错误文件想重新选择,可以使用reset方法来重置,对于一般的input标签,input.value=''和reset方法基本结果一致,但是type为file的input标签不可以通过操作value来重置

####htmlFor

<form>
<input type="file" id="file1" hidden>
</form>
<label for="file1"></label>

当然,for标签关联的必须是可关联元素,可关联元素有button, fieldset, input, keygen, label, object, output, select, textarea

####input type=“file”
当选择为文件时,属性可以有
accept:可以接受的文件类型,类型指定方式
- audio/\*,video/\*,image/\*
- 指定以点号开头的后缀名,如.mp3
- 使用MIME-type
- 多中类型的话需要都好分割
例如<input type="audio/*, .mp3">

multiple:可以选择多个文件

####select

<select>
<option></option>
<optgroup>
<option></option>
<option></option>
</optgroup>
</select>

######select属性
name:选项名称
value:选项的值
multiple:控制是否可以多选
options:所有选项的集合,动态集合
selectedOptions:所有选中的选项集合,动态集合
selectedIndex:第一个选中的选项的索引,没有则返回-1
add(element[, before]):添加一个选项
remove([index]):删除某个选项

######optgroup属性
disabled:表示这个组中的所有选项不可选
label:表示这个组为必选项

######option属性
disabled和label,同optgroup
value:option的值
text:显示的文本
index:option的索引
selected:已经被选中
defaultSelected:默认选中

######创建选项
documen.createElement("option")
new Option([text[, value[, defaultSelected[, selected]]]])

######添加选项
selectNode.add(toAdded, reference) //selectNode是select节点类
select.insertBefore(toAdded, reference) //select.insertBefore是一个接口,select不是节点类

######删除选项
selectNode.removeChildI(optionNode)
select.remove(index)

####表单验证
可验证的表单有button, select, textarea, input
以下情况这些元素也不会验证
- input的标签的类型设置为了reset, button或者hidden
- button标签的类型设置为了reset和button
- input和textarea标签的属性设置了readonly
- 作为datalist的子孙节点
- disabled

######验证涉及到的接口element.
- willValidata:表示这个元素是否会在提交时被验证,布尔型
- checkValidity():验证一个元素,通过验证返回true,否则触发invalid事件
- validity:存储验证的结果
- validationMessage:用于显示验证异常的信息
- setCustomValidity(message):用来自定义验证异常的信息

######隐式提交
即不通过点击提交按钮,而是通过回车键提交,隐式提交的情况有两种
- 表单中有非禁用的提交按钮
- 表单中没有提交按钮,但是表单中不超过一个类型为text, search, url, email, password, data, time, number的input元素

######提交过程
1. 浏览器根据enctype构建指定的数据结构
2. 从form中找出要提交的数据
3. 将数据按照指定数据结构组织并提交

######编码方式enctype
可选值为
application/x-www-form-urlencoded //默认,url方式,形式如:name=value&name2=value2
multipart/form-data //形式如:字符流,文件一般用这种编码方式
text/plain //形式如:name=value name2=value。中间使用回车符分割,一般用于给人阅读

######无刷新表单提交

<iframe name="iframe1">

</iframe>
<form target="iframe1">

</form>

iframe标签用来在其中嵌套另外一个稳定,实现局部的更新,当form的目标指向一个iframe,当表单被提交后,服务器返回的数据会自动返回给iframe,这样在表单提交后就可以不用刷新本页面而实现内容的填充
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,080评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,422评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,630评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,554评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,662评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,856评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,014评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,752评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,212评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,541评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,687评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,347评论 4 331
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,973评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,777评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,006评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,406评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,576评论 2 349

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,633评论 18 139
  • 1.表单元素 编写表单的三个步骤:构建表单,服务器端处理,配置表单 以披萨预定表单为例 构建完表单,需要服务器端提...
    hyt222阅读 518评论 0 0
  • 1.文档树 Document Object Model 文档对象模型 包含: DOM Core DOM HTM...
    hyt222阅读 309评论 0 0
  • 福贵娘还在世的那些日子,常对福贵说:人只要活得高兴,穷也不怕。——《活着》 第一次看余华的文学作品,不得不说,余华...
    走路带风少女阅读 165评论 4 13
  • 成田/羽田机场 - 东京市区 此图为JR山手线,山手线包含了东京市内的大部分主要商圈景点以及交通枢纽,如新宿、银座...
    surmoon阅读 740评论 0 0