前面的一句话:
DOM内容太多, 只能言简意赅, 深究可以到tcp协议,浏览器内核,计算机图形学等等知识, 慢慢来,让我们螺旋式的方式提高自己吧
开胃菜:
大家知道 contentEditable 是干嘛的吗?
一点思考:
有些牛人在特定时间点钻研DOM和特性, 若干年后, 兼容ie6,7,8成为古文, 一些特别的用法逐渐规范, xxxx研究好多天的问题,对于h5是小菜一碟, 不是我们不行,是DOM的局限性决定的, 着眼于未来.
抬头看看世界,h5来了
语义化标签
绘制: canvas/svg/
http://www.craftymind.com/blowing-up-html5-video-and-mapping-it-into-3d-space/ 看完后我大小便失禁了
音视频: audio/video
地理信息:Geolocation API
跨文档通信: postMessage API , XMLHttpRequest2
套字节: WebSocket API
优化的表单: Forms API
工作流: Web Workers API 支持多线程,让web应用程序具备后台处理能力,不会阻塞DOM渲染
http://www.w3ctech.com/topic/866 我最欣赏的月影前辈所翻译
离线存储: Web Storage API
3D: webGL
http://www.pper.com.cn/ 我又一次失禁了
http://threejs.org/ 止不住的失禁
一些属性和变量
contentEditable ? //文本编辑器
contextmenu ? //添加右击菜单
draggable dropzone ? //天然支持的拖拽
prefetch ? //预先加载 <link rel="prefetch" href="http://www.example.com" >
正文
BOM browser object model
DOM Document Object Model
浏览器监听对象
XMLHttpRequest对象
提问: BOM和DOM的到底是什么?
DOM的API接口
提问: DOM节点类型有哪几种? 是一个标签一个节点吗?
提问: 你如果是DOM设计师, 你会如何设计DOM的API ???
属性 下面的例子打开当前页面console控制台跑, dom引用当前页面
dom.childNodes; 返回该节点的所有子节点伪数组(NodeList), 注意: 会返回各种类型的节点 dom.childNodes.length; dom.childNodes[1];
dom.firstChild; 返回第一个子节点 === dom.childNodes[0], //document.childNodes[1].childNodes[2].childNodes[20].childNodes[0] === document.childNodes[1].childNodes[2].childNodes[20].firstChild //true
dom.lastChild; 返回最后一个子节点 === dom.childNodes[ dom.childNodes.length-1 ];
dom.nextSibling; 返回下一个兄弟节点, dom.nextSibling.nextSibling 这样玩也可以
dom.previousSibling; 返回上一个兄弟节点,
dom.attributes; 返回该节点的属性数组
dom.nodeName; 返回该节点的节点名称string
dom.nodeValue; 返回该节点的节点值string
dom.textContent; 返回该节点的文本内容, 注意: ie不支持可以用 dom.innerText
dom.innerHTML; 返回该节点的所有HTML代码
dom.id; 返回该节点的id(string) 没有返回""
dom.className; 返回该节点的所有class串; 例:document.childNodes[1].childNodes[2].className //"theme-default aui-layout aui-theme-default contenteditor edit no-tools-pin-toolbar"
dom.style; 返回该节点的样式, 打印 document.getElementById(‘editor-preload-container‘).style;
dom.value; 返回该节点的(form元素)的值, 例: document.getElementById(‘editor-preload-container‘).value //undefined
方法
dom.hasChildNodes(); 该节点是否存在子节点.
dom.hasAttributes(); 该节点是否存在属性
dom.appendChild(dom); 添加一个子节点,在子节点队尾.
dom.cloneNode(false/true); 克隆节点, false不复制子节点,true复制子节点
dom.insertBefore(新子节点,被插队的节点); 插入子节点,可以控制位置
dom.removeChild(被删节点); 删除子节点,返回被删除节点
dom.replaceChild(被删节点,替换节点); 替换子节点, 返回被删节点
快捷方式和优化
document.childNodes[1].childNodes[2].childNodes[20]; //<div id="editor-preload-container" style></div>
document.childNodes[1].childNodes[2].childNodes[20] instanceof Element; //true
document.getElementById(‘editor-preload-container‘) instanceof Element //true
document.getElementsByTagName(‘div‘) instanceof HTMLCollection // true
document.createElement();
document.createTextNode();
document.getElementById();
document.getElementsByTagName();
document.getElementsByClassName();
document.images //跑一跑
document.links
document.forms
document.write(‘html");
document.cookie
document.title
document.referrer
document.domain
事件监听, 跑起来啥都看清楚了
<!doctype html>
<html>
<head>
<meta charset="utf-8">
</head>
<body id="body">
<div style="height:400px;width:400px;background:blue;"></div>
<script type="text/javascript">
var body = document.getElementById(‘body‘);
body.addEventListener(‘click‘,function(e){
console.log(e instanceof window.MouseEvent );
},false);
</script>
</body>
</html>
addEventListenter(事件类型,处理函数,是否捕获); ---> attachEvent
removeEventListener(事件类型,处理函数); ---> detachEvent
事件冒泡
从下往上冒泡传递,依次触发监听.
e.stopPropagation(); //阻止冒泡 ---> cancelBubble = true;
e.preventDefault(); //阻止默认行为 --> returnValue = false;
事件类型:
document. 跑一下
XMLHttpRequest 对象
var xhr = new XMLHttpRequest();
xhr.open(请求类型区分大小写, 请求地址, 是否异步,false===同步);
xhr.onreadystatechange = function(无参){
if( xhr.readState === 4 ){ 请求状态, 0未初始/1载入请求/2载入完成/3请求交互/4请求完成
if( xhr.status === 200 ){ http请求的状态码
xhr.responseText 返回内容
}
}
}
xhr.senRequestHeader(key:value); //设置请求头信息,可以设置多个 //setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xhr.send(发送的数据);
XMLHttpRequest2
* 上传下载2进制数据,例如图片
* 自动解码数据类型: ArrayBuffer / Blob / Document / JSON / Text
* 监听上传,下载的进度
javascript性能优化-repaint和reflow
原文地址: http://www.cnblogs.com/jiajiaobj/archive/2012/06/11/2545291.html
repaint(重绘) ,repaint发生更改时,元素的外观被改变,且在没有改变布局的情况下发生,如改变outline,visibility,background color,不会影响到dom结构渲染。
reflow(渲染),与repaint区别就是他会影响到dom的结构渲染,同时他会触发repaint,他会改变他本身与所有父辈元素(祖先),这种开销是非常昂贵的,导致性能下降是必然的,页面元素越多效果越明显。
何时发生:
1. DOM元素的添加、修改(内容)、删除( Reflow + Repaint)
2. 仅修改DOM元素的字体颜色(只有Repaint,因为不需要调整布局)
3. 应用新的样式或者修改任何影响元素外观的属性
4. Resize浏览器窗口、滚动页面
5. 读取元素的某些属性(offsetLeft、offsetTop、offsetHeight、offsetWidth、 scrollTop/Left/Width/Height、clientTop/Left/Width/Height、 getComputedStyle()、currentStyle(in IE))
var fragment = document.createDocumentFragment();
fragment.appendChild(document.createTextNode(‘keenboy test 111‘));
fragment.appendChild(document.createElement(‘br‘));
fragment.appendChild(document.createTextNode(‘keenboy test 222‘));
document.body.appendChild(fragment);
4. 集中修改样式
4.1尽可能少的修改元素style上的属性
4.2尽量通过修改className来修改样式
4.3通过cssText属性来设置样式值
element.style.width=”80px”; //reflow
element.style.height=”90px”; //reflow
element.style.border=”solid 1px red”; //reflow
以上就产生多次reflow,调用的越多产生就越多
element.style.cssText=”width:80px;height:80px;border:solid 1px red;”; //reflow
4.4缓存Layout属性值
var left=elem.offsetLeft; 多次使用left也就产生一次reflow
4.5设置元素的position为absolute或fixed
元素脱离标准流,也从DOM树结构中脱离出来,在需要reflow时只需要reflow自身与下级元素
4.6尽量不要用table布局
table元素一旦触发reflow就会导致table里所有的其它元素 reflow。在适合用table的场合,可以设置table-layout为auto或fixed,这样可以让table一行一行的渲染,这种做法也是为了限制reflow的影响范围
4.7避免使用expression,他会每次调用都会重新计算一遍(包括加载页面)