DOM
Document Object Model
- DOM Core
- DOM HTML
- DOM Style
- DOM Event
节点相关
获取节点
修改节点
- textContent
- innerText ( 有兼容问题 )
element.textContent 节点及其后代节点的文本内容
users.textContent;
user_last.textContent; //Kash
user_last.textContent = " Tom "; //设置
ie9以下不支持
element.innerText 节点及其后代节点的文本内容
与 textContent 用法一样。但,innerText 不规范,ff不支持
兼容方案
if( !('innerText' in document.body) ){
HTMLElement.prototype.__defineGetter__("innerText",function(){
return this.textContent;
})
HTMLElement.prototype.__defineSetter__("innerText",function(s){
return this.textContent = s;
})
}
插入节点
- appendChild
- insertBefore
删除节点 element.removeChild(child)
element.innerHTML
建议仅用于新的节点
- 内存泄露
- 安全问题
HTML attribute -> DOM property
每个html属性对应相应的DOM对象属性
- property accessor
- getAttribute/setAttribute
- dataset
- HTMLElement.dataset HTML元素列表上的一个属性
- data-*属性集
- 元素上保存数据
CSS -> DOM
window.getComputedStyle() 获取元素的实际样式
var style = window.getComputedStyle(element [, pseudoElt] );
<input type="text" style="color: red;">
window.getComputedStyle(element).color; // " rgb(255,0,0) "
ie9 - 使用element.currentStyle
DOM事件
- 事件流
- 事件注册
- 事件对象
- 事件分类
- 事件代理
什么是DOM事件
- 点击一个DOM元素
- 键盘按下一个键
- 输入框输入内容
- 页面加载完成
DOM 事件流
- capture phase 事件捕获
- target phase 事件触发
- bubble phase 事件冒泡(某些事件是没有冒泡的,比较页面的load)
事件注册与触发
- 事件注册
- 取消事件注册
- 事件触发
事件注册
eventTarget.addEventListener(type, listener [, useCapture])
最后一个参数 默认是false, 表示获取冒泡过程; true,为获取捕获过程
取消事件注册
eventTarget.removeEventListener( type,listener[,useCapture] )
事件触发
eventTarget.dispatchEvent(type)
elem.dispatchEvent('click')
浏览器兼容(IE6、7、8)
- 事件注册与取消
- attchEvent/detachEvent
- 事件触发
- fireEvent(e)
- no capture (没有捕获阶段)
兼容代码:
事件对象
- 属性
- type
- target(srcElement)
- currentTarget
- 方法
- stopPropagation 阻止冒泡
- preventDefault 阻止默认
- stopImmediatePropagation 也是阻止冒泡,与第一个有区别
阻止事件传播
- event.stopPropagation() (w3c)
- event.cancelBubble = true (IE)
- event.stopImmediatePropagation() ( w3c )
- 做了第一件事: event.stopPropagation() 阻止事件传播到父节点
- 第二件事:阻止当前节点的后续事件(一个元素注册多个事件的时候)
默认行为
- event.preventDefault() ( w3c )
- event.returnValue = false ( IE )
事件分类
** Event **
window
- load 页面加载完成
- unload 例如点击链接跳转新页面。当前页面会先卸载触发unload事件
- error 浏览器出现异常时
- abort 出现取消时
Image
- load
- error
- abort
常用做法:图片加载错误时,加载默认图片
<image alt='photo' src="./image/a.png" onerror="this.src = 'http://www.163.com/default.jpg' "/>
UIEvent
- resize
- scroll
MouseEvent
MouseEvent对象
- 属性
- clientX, clientY 鼠标的位置到页面的最左端,最上端
- screenX , screenY 鼠标到屏幕的最左端,最上端
- ctrlKey, shiftKey, altKey, metaKey true/false
- buttom(0,1,2) 鼠标 左键、中间键、右键
MouseEvent顺序
-
从元素A上方移过
- mousemove -> mouseover(A) -> mouseenter (A) -> mousemove (A) -> mouseout (A) -> mouseleave (A)
-
点击元素
- mousedown -> [mousemove] -> mouseup -> click
例子 - 拖拽div
- HTML
<div id="div1"></div> - CSS
- JS
wheelEvent 滚轮事件
FocusEvent 获得、失去焦点
FocusEvent
- 属性
- relatedTarget 一个元素失去焦点,另外一个元素获得焦点(relatedTarget)
InputEvent
- beforeinput
- input
例如:
在输入框输入内容,当输入页面还没显示内容时(触发beforeinput)
在输入框显示自己输入的内容时,触发input,不断地输入内容,不断地触发input事件。
onpropertychange(IE)
keyboardEvent 键盘事件
- 属性
- key
- code
- ctrlKey、shiftKey、altKey 、metaKey
- repeat
用的少: - keyCode
- charCode
- which
事件代理
-
优点
- 需要管理的handler更少
- 内存分配更少
- 增加/删除节点可以不处理事件
-
缺点
- 事件管理的逻辑更复杂
HTTP
HTTP事务
请求报文格式
常用HTTP方法
URL 构成
常见HTTP状态码
Ajax
ajax调用示例
var xhr = new XMLHttpRequest(); //创建XHR对象
//返回处理数据
xhr.onreadystatechange = function(callback){
if(xhr.readyState == 4){
if( (xhr.status >= 200 && xhr.status < 300) || shr.status == 304){
callback( xhr.responseText )
} else {
alert('Request was unsuccessful' + xhr.status)
}
}
}
xhr.open('get','example.json',true);
xhr.setRequestHeader('myHeader','myValue');//发送请求
xhr.send(null);
open
最后一个参数 默认为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('&');
}
同源策略
两个页面拥有相同的协议(protocol),端口(port), 和主机(host), 那么这两个页面就属于同一个源(origin)
其他跨域技术
- frame代理
- JSONP
- Comet
- Web Sockets
- ......
Frame代理
JSONP
- JSON with padding (填充式json)
- <script>可以跨域
- 请求一段js代码
function handleResponse(response){
alert('my name is ' + response.name);
}
var script = document.createElement('script');
script.src = 'http:127.0.0.1/json?callback=handleResponse'
document.body.insertBefore( script,document.body.firstChild )
cookie
作用路径
设置/修改
删除cookie
function removeCookie( name, path, domain ){
document.cookie = name + '='
+ '; path=' + path
+ '; domain=' + domain
+ '; max-age = 0';
}
cookie 的缺陷
- 流量代价
- 安全性问题
- 大小限制 (4kb大小左右)
Storage
- localStorage
- 有效期:默认为永久(前提:用户不删除)
- sessionStorage
- 有效期:浏览器的会话时间
大小在5MB 左右
作用域也不同;
js对象
- 读取
- localStorage.name
- 添加/修改
- localStorage.name = "NetEase" (string)
- 删除
- delete localStorage.name
API
-
获取键值对数量
- localStorage.length
-
读取
- localStorage.getItem(" name "), localStorage.key(i)
-
添加/修改
- localStorage.setItem( 'name', 'hello world')
-
删除对应键值
- localStorage.removeItem( 'name' )
-
删除所有数据
- localStorage.clear()
JS动画
动画实现方式
- gif
- flash
- css3
- JS
js动画三要素
setInterval
var intervalID = setInterva( func, delay [, param1,param2.....])
clearInterval(intervalID)
setITimeout
requestAnimationFrame
var requestID = requestAnimationFram(Func)
cancelAnimationFrame( requestID )
进度条 实例 setInterval:
/**
* [process description]
* @param {[type]} prcsswrap [对象的父元素]
* @param {[type]} drtn [进度条的时间]
* @param {[type]} intrvl [定时器时间间隔]
* @param {Function} callback [回调函数]
*/
var process = function(prcsswrap,drtn,intrvl,callback){
var width = prcsswrap.clientWidth; //clientWidth: 获取对象可见内容的宽度,不包括滚动条,不包括边框;
//获取对象
var prcss = prcsswrap.getElementsByClassName('prcss')[0];
var count = drtn/intrvl; //分成的份数?
var offset = Math.floor(width/count)
var tmpCurrent = CURRENT;
//修改属性值
var step = function(){
if(tmpCurrent != CURRENT ){
prcss.style.width = '0px';
return;
}
var des = getNum( prcss.style.width ) + offset;
if(des < width){
prcss.style.width = getNum( prcss.style.width ) + offset
}else if(des = width ){
clearInterval(intervalId);
prcss.style.width = '0px';
PREV = CURRENT;
CURRENT = NEXT;
NEXT++;
NEXT = NEXT % NUMBER;
if(callback){
callback();
}
}else{
prcss.style.width = width + 'px';
}
};
var intervalId = setInterval(step,intrvl); //触发定时器
}
进度条 requestAnimationFrame 实例:
左右移动
多媒体编程
基本用法
<audio src="music.mp3"></audio>
<video src="movie.mov" width="320" height="320"></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 兼容用法
多媒体格式兼容
HTML属性
控制多媒体播放
- load() 加载媒体内容
- play() 开始播放
- pause() 暂停播放
- playbackRate 播放速度
- currentTime 播放进度
- volume 音量
- muted 静音
- paused 暂停
- seeking 跳转
- ended 播放完成
- duration 媒体时长
- initialTime 媒体开始时间
多媒体相关事件
- loadstart 开始请求媒体内容
- loadmetadata 媒体元数据已经加载完成
- canplay 加载了一些内容,可以开始播放
- play 调用play() 或设置了autoplay
- waiting 缓冲数据不够,播放暂停
- playing 正在播放
事件列表:
web Audio API
canvas
渲染上下文
var canvas = document.getElementById('tutorial');
var ctx = canvas.getContext('2d');
globalCompositeOperation 全局组合操作
ctx.globalCompositeOperation = 'destination-over'
基本绘图的步骤
实例
var sun = new Image();
var moon = new Image();
var earth = new Image();
function init(){
sun.src = 'sun.png' //new Image的优点是:在给image src赋值那么加载完后会保存在内存中,后面的地方用到就会直接从内存中读取,而不是从网络获取。
moon.src = 'moon.png'
earth.src = 'earth.png'
window.requestAnimationFrame(draw);
}
function draw(){
....
}
init();
BOM
代表浏览器窗口的一组api
属性
- navigator 浏览器信息
- location 浏览器定位和导航
- history 窗口浏览器历史
- screen 屏幕信息
navigator.userAgent
-
chrome
- "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5)
AppleWebKit/537.36
(KHTML, like Gecko) Chrome/44.0.2403.155 Safari/537.36"
- "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5)
-
firefox
- "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:37.0)
Gecko/20100101
Firefox/37.0"
- "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:37.0)
-
IE
- Mozilla/5.0 (Windows NT 6.1; WOW64;
Trident/7.0
; SLCC2; .NET CLR 2.0.50727;.NET CLR 3.5.....)
- Mozilla/5.0 (Windows NT 6.1; WOW64;
location 浏览器定位和导航
- assign(url) 载入新的url,记录浏览历史
- replace(url) 载入新的url,不记录浏览历史
- reload() 冲在当前页面
history 浏览历史
- back()
- forward()
- go()
screen 屏幕信息
方法
alert(), confirm(), prompt() 三种对话框
setTimeout(), setInterval() 计时器
-
open(), close() 新开窗口,关闭窗口
var w = window.open(" subwin.html", "subwin", "width:400,height=350,status=yes,resizable=yes;")
事件
- load 文档和图片加载完毕时
- unload 离开当前文档时
- beforeunload 和unload类似,但它提供询问用户是否确定离开的机会
- resize 拖动改变浏览器窗口大小时
- scroll 拖动滚动浏览器时
Form 表单提交
form 属性
-
autocomplete 自动补全(历史下拉记录)on/off
- elements 动态节点集合
该表单 子孙表单控件( 除图片按钮 input type="image" )
表单控件:button , fieldset, input, keygen, object , output, select , textarea.归属于该表单的表单控件( 除图片按钮 )
- length elements.length包含节点数的长度
form[name]
- 返回id或name为指定名称的表单控件(除图片按钮外)
- 如果结果为空,则返回id为指定名称的img元素
- 如果有多个同名元素,则返回这些元素的动态节点集合
- 一旦用指定名称取过该元素,则不管该元素的id或name怎么变化,只要节点还在页面上均可使用原名称获取该元素。
form 方法
-
reset()
- 可重置的元素: input, keygen, output, select, textarea
- 触发表单reset事件,阻止该事件的默认行为可取消重置
submit()
checkValidity()
label
- htmlFor
- 关联表单控件激活行为
- 可关联元素: buttn, input(除hidden外) ,keygen, meter, output, progress, select, textarea
input
- 本地图片预览
- onchange
- accept
- image/*
- video/*
- audio/*
- multiple
- files
<input type="file" accept="image/*" multiple />
file.addEventListener('change',function(event) {
var files = Array.prototype.slice.call( event.target.files,0 )
files.forEach(function(item){
file2dataurl(item,function(){
var image = new Image();
parent.appendChild(image);
image.src = url;
});
});
});
select
创建选项
- document.createElement
- new Option( [ text [, value [,defaultSelected [, selected] ] ] ] );
添加选项
- insertAdjacentElement
- select.add
删除选项
- removeChild
- select.remove
级联下拉选择器
- onchange
- remove
- add
二级联动实例
HTML代码:
<form action="" name="course">
<select name="chapter" id="chapter">
<option>选择章目录</option>
</select>
<select name="section" id="">
<option>选择节目录</option>
</select>
</form>
JS代码:
var chapters = [
{ text : '1. DOM基础', value : '1' },
{ text : '2. 事件模型', value : '2' }
];
var sections = {
1 : [
{ text : '1.1 文档树', value : '1.1' },
{ text : '1.2 节点操作', value : '1.2' },
{ text : '1.3 元素遍历', value : '1.3' },
{ text : '1.4 样式操作', value : '1.4' },
{ text : '1.5 属性操作', value : '1.5' },
{ text : '1.6 表单操作', value : '1.6' }
],
2 : [
{ text : '2.1 事件类型', value : '2.1' },
{ text : '2.2 事件模型', value : '2.2' },
{ text : '2.3 事件应用', value : '2.3' }
]
};
var forms = document.forms['course'];
var chapterSelect = forms.elements['chapter']
var selectionSelect = forms.elements['section']
//填充select下面的选项
function fillSelect(select,list){
// console.log(select.length)
//i > 0 表示不会把第一项删掉
for (var i = select.length - 1; i > 0; i--) {
select.remove(i);
};
list.forEach(function(data){
//new Option( [ text [, value [,defaultSelected [, selected] ] ] ] );
var option = new Option(data.text, data.value);
select.add(option);
})
}
fillSelect(chapterSelect,chapters); //初始化章节option
//给章节select添加change事件
chapterSelect.addEventListener('change',function(event){
var value = event.target.value,
list = sections[value] || []
fillSelect(selectionSelect,list);
})
textarea
textarea
selectionEnd 可以设置光标到文本最后的位置
selection
- selectionDirection 主要是 用键盘的shift + 方向建来选择的内容时的行为
值有:forward控制的是selecitonEnd的位置 , backward 控制selectionStart的位置
@输入提示实例 textarea
- oninput
- selectionStart
- setRangeText
textarea.addEventListener('input',function(event){
var target = event.target,
cursor = target.selectionStart;
if( target.value.charAt(cursor - 1) === '@' ){
doShowAtList(function(name){
var end = cursor + name.length;
target.setRangeText( name, cursor,end,'end');
})
}
});
验证
element.
- willValidate
- checkValidity()
- validity
- validationMessage
- setCustomValidity(message)
validity
自定义异常
- oninvalid
- setCustomValidity
HTML代码:
<form action="./api" name="valid" method="post">
<p><label for=""> <input name="username" required type="text"></label></p>
<p><button>submit</button></p>
</form>
JS 代码:
var input = document.forms['valid'].elements['username']
input.addEventListener('invalid',function(event){
var target = event.target
if( target.validity.valueMissing ){
target.setCustomValidity('请输入姓名!')
}
})
禁止验证
<form action="./api" name="valid" novalidate method="post">
<!-- 选择type=number 目的是在手机上可以唤起数字键盘 -->
<p> <input type="number" name="tel"></p>
<p><button>submit</button></p>
</form>
novalidate 禁止表单提交的时候做验证
隐式提交
- 如: 聚焦在输入框时按回车提交表单
- 满足一下任一条件:
- 表单有非禁用的提交按钮;
- 没有提交按钮时,不超过一个类型为:text, search, url, email, password, date,time, number的input元素
** 表单提交过程**
- 根据表单 enctype 指定的值构建要提交的数据结构
- 使用 method 指定的方式发送数据岛action指定的目标
** 编码方式(enctype)**
- application/x-www-form-urlencoded [默认]
- multipart/form-data
- text/plain
特殊案例
- name = "isindex" && type="text"
- 编码方式为 application/x-www-form-urlencoded
- 作为表单的第一个提交元素
- 提交时只发送value值,不包含name
- name = "charset" && type="hidden"
- 如果没有设置value值
- 提交时value自动用当前提交的字符集填充
submit()
- 提交表单
form.submit() - onsubmit
- 表单提交事件
- 提交之前的数据验证
- 阻止事件的默认行为可取消
无刷新表单提交
- form
- target
- iframe
代码:
<iframe name="targetFrame" class="f-hidden"></iframe>
<form action="./api" name="fom" method="post" target="targetFrame">
<input name="a"/>
<input name="b"/>
<input name="c"/>
<button>submit</button>
</form>
iframe 处理服务端返回的结果代码:
var form = document.forms.fom;
var frame = document.getElementById('result');
frame.addEventListener('load',function(){
try{
var result = JSON.parse( frame.contentWindow.document.body.textContent );
//还原登录按钮状态
disableSubmit(false); // 自定义方法
//识别登录结果
console.log(result)
if( result.code === 200 ){
showMessage('j-suc','登录成功'); // 自定义方法,提示信息
form.reset();
}
}catch(ex){
console.log(ex);
}
})
function disableSubmit(bool){
//修改按钮状态
}
function showMessage(cls,msg){
//提示信息显示
}