*******************************  Chapter 11 DOM扩展  *******************************

主要的扩展是 选择符API 和 HTML5

选择符API:

document.querySelector('.img');

document.querySelector('#test');

document.querySelectorAll('a');

//这个方式浏览器支持很少,返回是否可以查询得到的结果

document.matchesSelector('a.test');//true/false

元素遍历:

//这种方式就不会考虑后台元素的 空白文本节点了,

//因为使用 childNodes\firstChild\lastChild 不同的浏览器效果不一样

function eleAll(ele){

var child=ele.firstElementChild;

while(child!=ele.lastElementChild){

//do

child=ele.nextElementSibling;

}

}

HTML5:

与类相关的扩充:

//IE9+

document.getElementsByClassName('p');//返回NodeList

//获取元素的 class ,返回字符串

div.className;//'cls '

//类的数组  Firefox 和Chrome 支持classList

div.classList;//['cls']

div.classList.remove('cls');

div.classList.add('newcls');

div.classList.toggle('cls');

div.classList.contains('cls');

焦点管理:

document.activeElement;//返回获取到焦点的元素

ele.hasFocus();//是否获取到焦点

HTMLDocument 的变化:

readyState:

document.readyState;//loading\complete

compatMode:

兼容模式:CSS1Compat(标准模式)、BackCompat(混杂模式)

document.compatMode;//CSS1Compat

head: Chrome 和 Safari 5

var head = document.head || document.getElementsByTagName('head')[0];

字符集属性:

document.charset;//"UTF-8"

document.defaultCharset;//默认操作系统设置,一般少有浏览器支持

自定义数据属性:

使用前缀 data-

dataset 获取自定义属性

Firefox\chrome\IE11+ 支持

<div id='divtest' data-appid='test'></div>

var div = document.getElementById('divtest');

console.log(div.dataset.appid);

//自定义设置 data-test

div.dataset.test='hah';

console.log(div.dataset.test);

插入标记:

//大多数浏览器不支持的写法,IE8以及之前可以执行,但是脚本<script> 之前必须有 ‘作用域元素’

div.innerHTML='_<script>alert(1);<\/script>';

IE8的支持 window.toStaticHTML():

var text = '<a href="#" onclick="alert(1);">test</a>';

text = window.toStatocHTML(text);

console.log(text);//<a href="#">test</a>

//使用新的html 元素替换掉div 元素

div.outerHTML='<p>1232323</p>';

insertAdjacentHTML():

div.insertAdjacentHTML('beforebegin','<p>1111</p>');// div之前同辈元素

div.insertAdjacentHTML('afterbegin','<p>2222</p>');// div 子元素第一个

div.insertAdjacentHTML('beforeend','<p>3333</p>');//  div 子元素最后一个

div.insertAdjacentHTML('afterend','<p>4444</p>');//  div 之后的同辈节点

内存与性能问题:

使用innerHTML\outerHTML\insertAdjacentHTML 删除元素时候,元素之前绑定的事件关系并没有删除,会占用内存

scrollIntoView:

div.scrollIntoView();

专有扩展:

文档模式:

<meta http-equiv="X-UA-Compatible" content="IE=Edge" />

<meta http-equiv="X-UA-Compatible" content="IE=7" />

<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />

alert(document.documentMode);//返回IE 文档模式版本号  5、6、7、8、9、11

children:

ele.children;//只包含元素节点,排除文本节点

contains():

document.documentElement.contains(d);

compareDocumentPosition:

1: 无关

2:居前

4:居后

8:包含

16:被包含

document.documentElement.compareDocumentPosition(document.body);//20 = 16+4

//兼容性的 contains

function contains(refNode, otherNode) {

if (typeof refNode.contains == 'function' && (!client.engin.webkit || client.engin.webkit >= 522)){

return refNode.contains(otherNode);

} else if (typeof refNode.compareDocumentPosition == 'function') {

return !!(refNode.compareDocumentPosition(otherNode));

} else {

var node = otherNode.parentNode;

do {

if (refNode == node) {

return true;

} else {

node = node.parentNode;

}

} while (node != null);

}

}

插入文本:

//这种方式可以过滤掉 所有的 html 标签,只剩下文本

var div = document.getElementById('div1');

div.innerText = div.innerText;

//firefox 不支持 innerText, 但是可以使用 textContent

function getInnerText(ele) {

return typeof ele.textContent == 'string' ? ele.textContent : ele.innerText;

}

function setInnerText(ele, txt) {

if (typeof ele.textContent == 'string') {

ele.textContent = txt;

} else {

ele.innerText = txt;

}

}

outerText:

div.outerText='test';//文本替换div元素

滚动:

//以下方法不常用,支持度不好

div.scrollIntoViewIfNeeded(true);//当前元素在视口不可见时滚动,设置为true,元素尽量显示在视口中部

div.scrollByLines(2);

div.scrollByPage(1)

*******************  Chapter 12 DOM2和DOM3 *****************

DOM变化:

document.implementation.hasFeature('COe','1');//不管怎样都是返回true

针对XML命名空间的变化:

其他方面的变化:

DocumentType类型的变化:

document.doctype.publicId;

document.doctype.systemId;

document.internalSubset;//几乎不会用到

//类似cloneNode()

var newNode = document.importNode(oldNode,true);

document.body.appendChild(newNode);

//IE 使用 parentWindow

document.defaultView||document.parentWindow;

document.body.isSupported('HTML','2.0')

var div = document.createElement("div");

div.setUserData('name', 'test', function (operation, key, value, src, dest) {

//operation: 1.复制  2.导入  3.删除  4.重命名

})

var iframe = document.getElementById('myFrame');

//IE8之前 contentWindow

var doc = ifame.contentDocument || iframe.contentWindow.document;

样式:

访问元素的样式:

DOM样式属性和方法:

var ele = document.getElementById('div1');

var prop, val;

for (var i = 0; i < ele.style.length; i++) {

prop = ele.style[i];

val = ele.style.getPropertyCSSValue(prop);

}

计算的样式:

//null 表示不需要伪元素

var comStyle = document.defaultView.getComputedStyle(ele, null);

console.log(comStyle.color);//获取最终实际的值,有效果的值

//IE

var IDComStyle = ele.currentStyle;

console.log(comStyle.color);//获取最终实际的值,有效果的值

操作样式表:

document.styleSheets

var link = document.getElementsByTagName("link")[0];

var sheet = link.sheet || link.styleSheet;//IE 使用styleSheet

//以上的等价表示

document.styleSheets;

//stylesheets

var sheet = document.stylesheets[0];

var rules = sheet.cssRules || sheet.rules;

var rule = rules[0];

rule.style.backgroundColor = 'red';

//deleteRule

function deleteRule(sheet, index) {

if (sheet.deleteRule) {

sheet.deleteRule(index);

} else if (sheet.removeRule) {//IE

sheet.removeRule(index);

}

}

元素大小:

1. 偏移量

offsetTop: 元素上边框与包含元素在内的上内边框的距离

offsetLeft: 元素左边框与包含元素在内的左内边框的距离

offsetWidth:  元素垂直方向上占用的空间大小。包括滚动条

offsetHeight: 元素水平方向上占用的空间大小。包括滚动条

以上都是只读属性,尽量避免重复访问这些属性,因为每次都会重复计算,影响性能

function getEleLeft(ele) {

var left = ele.offsetLeft;

var curEle = ele.offsetParent;

while (curEle != null) {

left += curEle.offsetLeft;

curEle = ele.offsetParent;

}

return left;

}

function getEleTop(ele) {

var top = ele.offsetTop;

var curEle = ele.offsetParent;

while (curEle != null) {

top += curEle.offsetTop;

curEle = ele.offsetParent;

}

return top;

}

2. 客户区大小

clientWidth\clientHeight

var ele = document.getElementById("");

ele.clientWidth;//内容宽度+内边距

ele.clientHeight;//内容高度+内边距

//获取视口的大小

function getViewport() {

if (document.compatMode == 'BackCompat') {

return {

width: document.body.clientWidth,

height: document.body.clientHeight

};

} else {

return {

width: document.documentElement.clientWidth,

height: document.documentElement.clientHeight

};

}

}

3. 滚动大小

ele.scrollHeight;//没有滚动条的情况,元素内容实际的总高度

ele.scrollWidth;//没有滚动条的情况,元素内容实际的总宽度

ele.scrollTop;//被隐藏在内容区域上方的高度

ele.scrollLeft;//被隐藏在内容区域左侧的宽度

//使元素滚动到顶部

function scrollToTop(ele) {

if (ele.scrollTop != 0) {

ele.scrollTop = 0;

}

}

4. 确定元素的大小

function getBoundingClientRect(ele) {

var scrollTop = document.documentElement.scrollTop;

var scrollLeft = document.documentElement.scrollLeft;

if (typeof arguments.callee.offset != 'number') {

var temp = document.createElement("div");

temp.style.cssTex = "position:absolute;left:0;top:0;";

document.body.appendChild(temp);

arguments.callee.offset = -temp.getBoundingClientRect().top - scrollTop;

document.body.removeChild(temp);

temp = null;

}

var rect = ele.getBoundingClientRect();

var offset = arguments.callee.offset;

return {

left: rect.left + offset,

right: rect.right + offset,

top: rect.top + offset,

bottom: rect.bottom + offset

};

//console.log(arguments.callee.offset);

}

遍历:

IE不支持DOM遍历

NodeIterator:

//获取所有的元素

var itor = document.createNodeIterator(document, NodeFilter.SHOW_ALL, null, false);

var node = itor.nextNode();

while (node) {

console.log(node.tagName);

node = itor.nextNode();

}

//获取div下面的 p 元素, 自定义过滤器

var div = document.getElementById("div");

var filter = function (node) {

return node.tagName.toLowerCase() == 'p' ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;

};

var iter = document.createNodeIterator(div, NodeFilter.SHOW_ELEMENT, filter, false);

TreeWalker:

更自由,更灵活的方式;

var div = document.getElementById("div");

var filter = function (node) {

return node.tagname.tolowercase() == 'p' ? nodefilter.filter_accept : nodefilter.filter_skip;

};

var walker = document.createTreeWalker(div, filter, NodeFilter.SHOW_ELEMENT, false);

walker.firstChild();

walker.nextSibling();

var node = walker.firstChild();

while (node) {

console.log(node.tagName);

node = walker.nextSibling();

}

范围:

DOM中的范围:

Range实例

var range1 = document.createRange(),

range2 = document.createRange();

var p = document.getElementById('testP');

range1.selectNode(p);//包括 p 元素

range2.selectNodeContents(p);//只是包括 p 元素的子节点

基本操作

var startNode = p.firstChild.firstChild;

var endNode = p.lastChild;

range1.setStart(startNode, 2);

range1.setEnd(endNode, 3);

var fragment = range1.extractContents();

p.parentNode.appendChild(fragment);

fragment = range1.cloneContents();

range1.deleteContents();

var span = document.createElement("span");

range1.insertNode(span);

range1.surroundContents(span);//将先执行 extractContents(), 将获取的片段插入 span 中

range1.collapse(true);//true 表示折叠到起点  false 折叠到终点

range1.collapsed;//查询是否折叠

range1.compareBoundaryPoints(Range.START_TO_START, range2);//-1:没有任何关系 0:相等  1:包含关系

//复制范围

var newRange = range1.cloneRange();

//清理范围

range1.detach();

range1 = null;

IE8及更早版本中的范围

var ieRange = document.body.createTextRange();

var canFound = ieRange.findText("hello");//true/false

console.log(ieRange.text);

var canFound = ieRange.findText("hello", 1);//true/false  1:向前搜索  -1: 向后搜索

ieRange.moveToElementText(p);

ieRange.htmlText;

ieRange.moveStart('word', 2);

ieRange.moveEnd('character', 2);

ieRange.expand('hello');

ieRange.pasteHTML('<p>test</p>');

ieRange.collapse(true);

var isCollapsed = (ieRange.boundingWidth == 0);//是否折叠

ieRange.compareEndpoints("StartToStart", range2);

ieRange.isEqual(range2);

ieRange.inRange(range2);

var newRange = ieRange.duplicate();//复制

*********************    Chapter 13 事件     *********************

事件流:

事件冒泡:IE

IE9、Firefox、Chrome、Safari 事件一直冒泡到 window 对象

事件捕获:

因为老版本浏览器不支持,所以很少使用事件捕获,建议都使用事件冒泡

DOM事件流:

捕获阶段-->处于目标阶段-->冒泡阶段

事件处理程序:

HTML事件处理程序:

<!--<input type="button" name="name" value="btn" onclick="alert(this.value)" />-->

<!--动态扩展性-->

<input type="button" name="name" value="btn" onclick="alert(value)" />

<!--表单的扩展性-->

<form action="/" method="post">

<input type="text" name="userName" value="admin" />

<input type="button" name="name" value="btnGo" onclick="alert(userName.value)" />

</form>

<!--普通方式-->

<!--<input type="button" name="name" value="btn" onclick="show(this)" />-->

<!--这种是保险的方式,防止方法还没加载处理,就执行了点击事件,也是缺点之一 -->

<input type="button" name="name" value="btn" onclick="try {show(this);} catch (e) { }" />

DOM0级事件处理程序:

var btn = document.getElementById('btn');

btn.onclick = function () {

console.log(this.id);//this 指向的是当前的元素

}

DOM2级事件处理程序:

//addEventListener可以同时绑定多个事件

var btn = document.getElementById('btn');

btn.addEventListener('click', function () {

console.log(this, id);

}, false);//true:表示捕获节点触发  false:表示冒泡阶段触发

btn.addEventListener('click', function () {

console.log(this.name);

}, false);//true:表示捕获节点触发  false:表示冒泡阶段触发

//removeEventListenerc 操作的时候只能使用命名的方式

var handler = function () {

console.log(this.id);

}

btn.addEventListener('click', handler, false);

btn.removeEventListenerc('click', handler,false);

IE事件处理程序:

var handler = function () {

console.log(this == window);//attachEvent 时候,this 是全局作用域 window

};

btn.attachEvent('onclick', handler);//attachEvent 如果同时绑定多个方法,就会倒序执行

btn.detachEvent('onclick');

跨浏览器的事件处理程序:

var EventUtil = {

addHandler: function (ele, type, handler) {

if (ele.addEventListener) {

ele.addEventListener(type, handler, false);

} else if (ele.attachEvent) {

ele.attachEvent('on' + type, handler);

} else {

ele['on' + type] = handler;

}

},

removeHandler: function (ele, type, handler) {

if (ele.removeEventListener) {

ele.removeEventListener(type, handler, false);

} else if (ele.detachEvent) {

ele.detachEvent('on' + type, handler);

} else {

ele['on' + type] = null;//DOM0 级方式

}

}

}

事件对象:

DOM中的事件对象:

var btn = document.getElementById('btn');

btn.onclick = function () {

//event.preventDefault();//阻止默认事件,这个只有在 cancellable =true 的时候有用

//event.stopPropagation();//阻止事件冒泡

alert(event.eventPhase);//click  2 处于目标阶段

//alert(event.type);//click

//console.log(this.id);//this 指向的是当前的元素

}

document.body.addEventListener('click', function () {

alert(event.eventPhase);//1

}, true);//捕获阶段

document.body.onclick = function () {

alert(event.eventPhase);//3  冒泡阶段

}

IE中的事件对象:

btn.onclick = function () {

var e = window.event;

e.cancelable = true;//IE 取消冒泡事件

e.returnValue = false;//IE取消默认行为

}

跨浏览器的事件对象:

var EventUtil = {

getClipboardText: function (event) {

var clipData = (event.clipboarData || window.clipboardData);

return clipData.getData('text');

},

setClipboardText: function (event,value) {

if (event.clipboarData) {

return event.clipboarData.setData("text/plain", value);

} else if (window.clipboardData) {

return window.clipboardData.setData("text", value);

}

},

getWheelDelta: function (event) {

if (event.wheelDelta) {

return client.engine.opera && client.engine.opera < 9.5 ? -event.wheelDelta : event.wheelDelta;

} else {

return -event.detail * 40;//Firefox

}

},

getButton: function () {

if (document.implementation.hasFeature('MouseEvents', '2.0')) {

return event.button;

} else {

//IE

switch (event.button) {

case 0:

case 1:

case 3:

case 5:

case 7:

return 0;

case 2:

case 6:

return 2;

case 4:

return 1;

}

}

},

//对于鼠标事件的 mouseout和mouseover

getRelatedTarget: function (event) {

if (event.getRelatedTarget) {

return RelatedTarget;

} else if (event.toElement) {

return event.toElement;//IE mouseout

} else if (event.fromElement) {

return event.fromElement;//IE mouseover

} else {

return null;

}

},

getEvent: function (event) {

return event ? event : window.event;

},

getTarget: function (event) {

return event.target || event.srcElement;

},

preventDefault: function (event) {

if (event.preventDefault) {

event.preventDefault();

} else {

event.returnValue = false;

}

},

stopPropagation: function (event) {

if (event.stopPropagation) {

event.stopPropagation();

} else {

event.cancelBubble = true;

}

},

addHandler: function (ele, type, handler) {

if (ele.addEventListener) {

ele.addEventListener(type, handler, false);

} else if (ele.attachEvent) {

ele.attachEvent('on' + type, handler);

} else {

ele['on' + type] = handler;

}

},

removeHandler: function (ele, type, handler) {

if (ele.removeEventListener) {

ele.removeEventListener(type, handler, false);

} else if (ele.detachEvent) {

ele.detachEvent('on' + type, handler);

} else {

ele['on' + type] = null;//DOM0 级方式

}

}

}

事件类型:

UI事件:

load\unload\abort\error\select\resize\scroll\

img 也可以使用 load 事件

焦点事件:

blur(不支持冒泡)\DOMFocusIn\DOMFocusOut\focus(不支持冒泡)\focusin(支持冒泡)\focusout

鼠标与滚轮事件:

click\dbclick\mousedown\mouseenter(不冒泡)\mouseleave(不冒泡)\mousemove\mosueout\mouseover\mouseup

mousewheel

clientX\clientY:相对视口的位置

pageX\pageY:相对页面的位置

screenX\screenY:相对屏幕的位置

event.shiftKey\event.ctrlKey\event.altKey\event.metaKey(IE8不支持)

鼠标按钮:

event.button: 0:左键 1:中间滚轮 2:右键

mousewheel:

event.wheelDelta:120倍数表示向前滚动,-120倍数表示向后滚动,Opera 是相反的

Firefox使用的DOMMouseScroll事件:-3表示向前滚动,3表示想后滚动

触摸设备:

不支持dbclick

无障碍性问题:

屏幕阅读器无法触发mousedown事件;

不要使用mouseover;

不要使用dbclick

键盘与文本事件:

keydown(任意键)\keypress(字符键)\keyup\

event.keyCode

keypress事件:event.charCode

DOM3级变化:不推荐

不在包含charCode,而是使用key\char

location|keyLocation

getModifierState('Shift')

textInput事件:IE9+

对于可编辑区域输入实际字符才会触发,

event.data 返回实际字符;

event.inputMethod 返回输入模式

复合事件:IE9+唯一支持,不推荐

compositionstart\compositionupdate\compositionend

变动事件:

删除节点:

DOMNodeRemoved\DOMSubtreeModified\DOMNodeRemoved\DOMNodeRemovedFromDocument

插入节点:

DOMNodeinserted\DOMSubtreeModified\DOMNodeInsertedDocument

HTML5事件:

contextmenu 右键菜单事件

var div = document.getElementById("div");

//右键菜单点击事件

div.addEventListener('contextmenu',function(event){

event = event||window.event;

//取消右键菜单默认事件

event.preventDefault();

var menu = document.getElementById("menu");

menu.style.left=event.clientX+'px';

menu.style.top=event.clientY+'px';

menu.style.visibility='visible';

},false);

var menu = document.getElementById("menu");

// menu.onclick=function(){

//     event.stopPropagation();

// }

menu.addEventListener('click',function(){

event.stopPropagation();

},false)

document.onclick=function(){

var menu = document.getElementById("menu");

menu.style.visibility='hidden';

}

beforeunload事件

//离开页面之前的提示

window.addEventListener('beforeunload',function(){

var msg ="are you sure to go ...";

event.returnValue=msg;

return msg;

},false);

DOMContentLoaded 事件

DOM树形成之后立即调用,并且会在load之前

document.addEventListener('DOMContentLoaded',function(){

alert('ok');

},false);

//对于不支持DOMContentLoaded 的可以使用如下方式替代

setTimeout(function(){},0);

readystatechange 事件

document.addEventListener('readystatechange',function(event){

if(document.readyState=='interactive' || document.readyState=='complete'){

alert('loaded...');

}

},false);

//动态添加 script 元素

var script = document.createElement('script');

script.addEventListener('readystatechange', function (event) {

if (script.readyState == 'loaded' || event.script == 'complete') {

script.removeEventListener('readystatechange', arguments.callee, false);

}

}, false)

script.src = 'test.js';

document.body.appendChild(script);

pageshow和pagehide事件:

bfcache 用来缓存页面,当时用了浏览器 ‘前进’、‘后退’的时候

无论页面是否来自缓存,都会执行pageshow 事件,都是在load事件之后执行

event.persisted 表示是否来自bfcache缓存

pagehide 在页面卸载之前触发

指定了onunload事件的页面会被自动排除在 bfcache 之外

//注意这两个事件都是绑定到 window 对象上,实际目标是document

window.addEventListener('pageshow', function () {

console.log(event.persisted);

}, false);

hashchange事件:

//url 改变的时候触发

window.addEventListener('hashchange', function (event) {

console.log(event.oldURL);

console.log(event.newURL);

console.log(location.hash);//考虑兼容性,推荐使用

}, false);

设备事件:

orientationchange 事件:

window.addEventListener('orientationchange', function (event) {

console.log(window.orientation);

}, false);

触摸与手势事件:

触摸事件:

touchstart

touchmove

touchend

touchcancel

手势事件:

gesturestart

gesturechange

gestureend

event.rotate\event.scale

内存和性能:

事件委托:

通过事件冒泡,只为上层元素添加事件,通过判断元素目标执行事件

也可以直接为 document 对象添加事件处理程序

移除事件处理程序:

var btn = document.getElementById('btn');

btn.onclick = function () {

//移除处理事件

btn.onclick = null;

//...替换btn操作

}

模拟事件:

DOM中的事件模拟:

模拟鼠标事件:

var btn = document.getElementById('btn');

var event = document.createEvent("MouseEvents");

event.initMouseEvent("click", true, true, document.defaultView, 0, 0, 0, 0, 0, false, false, false, false, 0, null);

//触发事件

btn.dispatchEvent(event);

IE中的事件模拟:

var btn = document.getElementById('btn');

var event = document.createEventObject();

event.screenX = 100;

event.screenY = 0;

event.clientX = 0;

event.clientY = 0;

event.ctrlkey = false;

event.altKey = false;

event.shiftKey = false;

event.button = 0;

btn.fireEvent('onclick', event);

*********************    Chapter 14 表单脚本     *********************

表单的基础知识:

document.forms[0];

document.forms['form2'];

提交表单:

var form1 = document.getElementById("form1");

form1.submit();//这种方式不会触发 submit 事件

document.forms[0].addEventListener("submit", function (event) {

alert('1');

//组织表单提交的默认事件

event.preventDefault();

}, false);

重置表单:

reset

表单字段:

form.elements[0]

form.elements['txtName']

//修改元素类型

form1.elements["t"].type = 'checkbox';

focus()\blur():

<input type="text" name="t" value="1" autofocus />

文本框脚本:

选择文本:

select():

//选中输入框文本

form1.elements["t"].select();

selectionStart\selectionEnd:

//获取文本选中位置

alert(form1.elements["t"].selectionStart +","+ form1.elements["t"].selectionEnd);

//IE的方式

document.selection.createRange().text

setSelectionRange():

//设置选择区域

form1.elements["t"].setSelectionRange(1, 2);

//通用方式

function setSelection(txt, start, end) {

if (txt.setSelectionRange) {

txt.setSelectionRange(start, end);

} else if (txt.createTextRange) {//IE8及以下

var range = txt.createTextRange();

range.collapse(true);

range.moveStart("character", start);

range.moveEnd("character", end - start);

range.select();

}

txt.focus();

}

过滤输入:

var txt = document.getElementById('txt');

txt.onkeypress = function (event) {

//除了 Ctrl 键和 其他字符输入键,都屏蔽掉

if (!/\d/.test(String.fromCharCode(event.charCode)) && event.charCode > 9 && !event.ctrlKey) {

event.preventDefault();

}

}

操作剪贴板:

cop\cut\paste

//获取剪贴板内容

var EventUtil = {

getClipboardText: function (event) {

var clipData = (event.clipboarData || window.clipboardData);

return clipData.getData('text');

},

setClipboardText: function (event,value) {

if (event.clipboarData) {

return event.clipboarData.setData("text/plain", value);

} else if (window.clipboardData) {

return window.clipboardData.setData("text", value);

}

}

}

自动切换焦点:

(function () {

function tab(event) {

var target = window.event.srcElement;

if (target.value.length == target.maxLength) {

var form = target.form;

for (var i = 0,len = form.elements.length; i < len ; i++) {

if (form.elements[i] == target) {

if (form.elements[i+1]) {

form.elements[i+1].focus();

}

return;

}

}

}

}

var a = document.getElementById("a");

var b = document.getElementById("b");

var c = document.getElementById("c");

a.addEventListener("keyup", tab, false);

b.addEventListener("keyup", tab, false);

c.addEventListener("keyup", tab, false);

})();

HTML5约束验证API:

表单和按钮都可以设置是否进行默认API的验证

<form action="/" method="post" novalidate>

<input type="submit" name="btn" value="go" formnovalidate/>

</form>

选择框脚本:

//添加项

var newOpt = new Option('text', 'value');

sel.add(newOpt,undefined);//推荐

sel.appendChild(newOpt);//IE8及之前bug

//直接移动一项到另一个selection

var sel = document.getElementById("sel");

var sel2 = document.getElementById("sel2");

sel2.appendChild(sel.options[0]);

//向后移动一项

var opt = sel.options[1];

sel.insertBefore(opt, sel.options[opt.index + 2]);

表单序列化:

function serialize(form) {

var parts = [],

field = null,

optLen,

opt,

optVal;

for (var i = 0, len = form.elements.length; i < len; i++) {

field = form.elements[i];

switch (field.type) {

case "select-one":

case "select-multiple":

if (field.name.length) {

for (var j = 0, optLen = field.options.length; j < optLen; j++) {

opt = field.options[j];

if (opt.selected) {

optVal = "";

if (opt.hasAttribute) {

optVal = (opt.hasAttribute("values") ? opt.value : opt.text);

} else {

optVal = (opt.attributes["value"].specified ? opt.value : opt.text);

}

parts.push(encodeURIComponent(field.name) + "="+

encodeURIComponent(optVal));

}

}

}

break;

case undefined:

case "file":

case 'submit':

case 'reset':

case 'button':

break;

case 'radio':

case 'checkbox':

if (!field.checked) {

break;

}

default:

if (field.name.length) {

parts.push(encodeURIComponent(field.name) + "=" +

encodeURIComponent(field.value));

}

}

}

return parts.join("&");

}

富文本编辑:

designMode:

window.onload = function () {

window.frames['ifm'].document.designMode = 'on';

}

使用 contentEditable 属性:

var div = document.getElementById("div");

div.contentEditable = 'true';

操作富文本:

window.onload = function () {

window.frames['ifm'].document.designMode = 'on';

//指定富文本指定命令

window.frames['ifm'].document.execCommand("bold",false,null)

//查询是否可用指定的命令

var res = window.frames['ifm'].document.queryCommandEnabled("bold")

//查询富文本是否应用了该命令

var res = window.frames['ifm'].document.queryCommandState("bold")

}

富文本选区:

//获取选区

var selection = window.frames['ifm'].getSelection();

//选区文本

var txt = selection.toString();

//选区范围

var range = selection.getRangeAt(0);

var span = document.createElement("span");

span.style.backgroundColor = 'yellow';

range.surroundContents(span);

//修改选区的样式

var range = frames['ifm'].document.selection.createRange();

range.pasteHTML("<span style='color:red;'>" + range.htmlText + "</span>");

表单与富文本:

var form = document.getElementById('form1');

form.addEventListener("submit", function (event) {

var target = event.srcElement;

//提交的时候通过 隐藏域来获取到 富文本的值后,可以提交

target.elements['bak'].value = frames['ifm'].document.body.innerHTML;

}, false);

*********************    Chapter 15 使用Canvas 绘图      *********************

基本用法:

<canvas id="canvas" width="200" height="200">该浏览器不支持Canvas</canvas>

<hr />

<button onclick="save()">Save</button>

var canvas = document.getElementById("canvas");

if (canvas.getContext) {

var context = canvas.getContext("2d");

context.fillStyle = '#FF0000';

context.fillRect(0, 0, 150, 75);

}

//toDataURL

function save() {

var img = canvas.toDataURL('image/png');

var image = document.createElement("img");

image.src = img;

document.body.appendChild(image);

}

2D上下文:

*********************    Chapter 16 HTML5 脚本编程         *********************

跨文档消息传递:XDM

//主页面负责发送消息

var ifm = document.getElementById("ifm").contentWindow;

ifm.postMessage("msg from here", "http://www.123.com");//来源当前地址文档

//子页面 iframe 处理消息

window.onmessage = function (event) {

//确认来自的域

if (event.origin == "http://www.123.com") {

//处理数据

proceeMsg(event.data);

//回发数据  event.source 获取到的是window 的代理对象

event.source.postMessage("Received", "http://test.123.com");

}

}

原生拖放:

拖放事件:

dragstart

drag

dragend

dragenter

dragover

dragleave\drop

var div = document.getElementById("target");

//目标元素,取消浏览器的默认行为,防止自动打开页面搜索url

div.addEventListener("dragover", function (event) {

event = event || window.event;

event.preventDefault();

}, false);

div.addEventListener("drop", function (event) {

event = event || window.event;

//获取 设置的 url ,兼容性(Firefox)

//var url = event.dataTransfer.getData("url") || event.dataTransfer.getData('text/uri-list');

//使用 大写Text 来获取,兼容性(Firefox)

var id = event.dataTransfer.getData('Text');

var target = event.srcElement;

target.appendChild(document.getElementById(id));

event.preventDefault();

}, false);

//dataTransfer 的使用

var p = document.getElementById("p");

p.addEventListener("dragstart", function (event) {

event = event || window.event;

event.dataTransfer.setData('text', 'p');//IE中只能设置 'text' 或者 'url'

}, false);

effectAllowed/dropEffect:

event.dataTransfer.effectAllowed = 'move';

event.dataTransfer.dropEffect = 'move';

draggable 可拖动属性:

<p id="p" draggable="true">to drag div</p>

媒体元素:

历史状态管理:

history.pushState({name:"test"},'','test_04.html')

*********************    Chapter 17 错误处理与调试         *********************

try{

}catch(e){

alert(e.message);

}

//结果: 返回2

function test() {

try {

return 0;

} catch (e) {

return 1;

} finally {

return 2;

}

}

错误类型:

Error

EvalError

RangeError

ReferenceError

SyntaxError

TypeError

URIError

throw:

function test1() {

try {

//throw 1;

throw "test error...";

} catch (e) {

console.log(e);//1  test error...

}

}

错误事件error:

window.onerror = function (message,url,line) {

alert(message);

}

var a = 1 / 0 + c;//没有捕捉的错误都会触发 onerror 事件

//图片也可以使用 error 事件

var img = new Image();

img.onerror = function (event) {

}

img.src = 'fd.jpg';//

常见错误类型:

function foo(str1, str2) {

//不要使用 if(str2), 因为 传入0 结果也是 false

if (typeof str2 =="String" ) {

}

}

基本类型使用 typeof 检测, 对象则使用 instanceof 检测

记录日志到服务端:(高大上)

function logError(sev, msg) {

var img = new Image();

//使用Image 的方式提交错误优势:

//1. 避免跨域的问题

//2. 兼容性,所有浏览器都支持 Image

//3. 相对于Ajax,出问题的概率更低

img.src = "log.ashx?sev=" + sev + "&msg=" + msg;

}

常见的IE错误:

document.onclick = function (event) {

event = event || window.event;

setTimeout(function () {

event.returnValue = false;//IE8 会出现找不到成员

}, 1000);

}

IE对JavaScript 请求资源的 URL 最长不能超过2083个字符限制,URL路径限制2048

*********************    Chapter 18 JavaScript 与 XML       *********************

ECMAScript for XML

浏览器对XML DOM 的支持

//一般不需要指定 命名空间 和 文档类型

var xmlDom = document.implementation.createDocument('', 'root', null);

var child = xmlDom.createElement("child");

xmlDom.documentElement.appendChild(child);

DOMParser:

//解析xml

var parser = new DOMParser();

try {

var xml = parser.parseFromString("<root><child/></root>", 'text/xml');

var errors = xml.getElementsByTagName("parsererror");//获取是否有错误节点,错误节点名称 parsererror

if (errors.length > 0) {

throw new Error("parsing error!");

}

console.log(xml.documentElement.tagName);//root

console.log(xml.documentElement.firstChild.tagName);//child

var child = xml.createElement("child");

xml.documentElement.appendChild(child);

var children = xml.getElementsByTagName("child");

console.log(children.length);//2

} catch (e) {

}

XMLSerializer:

var serializer = new XMLSerializer();

var xml = serializer.serializeToString(xmlDom);

console.log(xml);

IE8及之前版本中的XML:

function createDom() {

if (typeof arguments.callee.activeXString != "string") {

var versions = ["MSXML2.DOMDocument.6.0",

"MSXML2.DOMDocument.3.0",

"MSXML2.DOMDocument"];

for (var i = 0, len = versions.length; i < len; i++) {

try{

new ActiveXObject(versions[i]);

arguments.callee.activeXString = versions[i];

break;

}catch(e){

//继续执行

}

}

}

return new ActiveXObject(arguments.callee.activeXString);

}

var xmlDom = createDom();

xmlDom.loadXML("<root><child/></root>");

if (xmlDom.parseError != 0) {

console.log(xmlDom.parseError.errorCode);

console.log(xmlDom.parseError.line);

console.log(xmlDom.parseError.linepos);

console.log(xmlDom.parseError.reason);

}

console.log(xmlDom.documentElement.tagName);

//添加子节点

xmlDom.documentElement.appendChild(xmlDom.createElement("child"));

序列化获取xml字符串

var xml = xmlDom.xml;

加载xml文件

var xmlDom = createDom();

xmlDom.async = false;//同步

xmlDom.load("example.xml");

//.....

异步加载和事件绑定

var xmlDom = createDom();

xmlDom.async = true;//异步

xmlDom.onreadystatechange = function () {

if (xmlDom.readyState == 4) {

//.......

}

}

//必须在事件绑定之后 load

xmlDom.load("example.xml");

跨浏览器处理XML:

function parseXML(xml) {

var xmlDom = null;

if (typeof DOMParser != 'undefined') {

xmlDom = new DOMParser();

xmlDom.parseFromString(xml, 'text/xml');

var errors = xmlDom.getElementsBytagName("parseerror");

if (errors.length > 0) {

throw new Error("parsing error:"+errors[0].textContent);

}

} else if (typeof ActiveXObject != 'undefined') {

xmlDom = createDom();

xmlDom.loadXML(xml);

if (xmlDom.parseError != 0) {

throw new Error("parsing error:" + xmlDom.parseError.reason);

}

} else {

throw new Error("No Xml parser available");

}

return xmlDom;

}

//解析xmlDom

function serializerXml(xmlDom) {

if (typeof XMLSerializer != 'undefined') {

return (new XMLSerializer()).serializeToString(xmlDom);

} else if (typeof xmlDom.xml != "undefind") {

return xmlDom.xml;

} else {

throw new Error("could'n serialize xmlDom");

}

}

*********************    Chapter 19 E4X        *********************

*********************    Chapter 20 JSON      *********************

JavaScript Object Notation

对象的属性名称必须使用双引号

{"name":"kk"}

全局对象JSON:

stringfy():

值为undefined 的值会被忽略

var book = { "title": "Time", "edtion": '2010', 'price': 20 };

//正常的序列化

console.log(JSON.stringify(book));

//使用缩进的方式

//{

//    --"title": "Time",

//    --"edtion": "2010",

//    --"price": 20

//}

console.log(JSON.stringify(book,null,'--'));

//过滤字段的方式

console.log(JSON.stringify(book, ['title']));// {"title":"Time"} 返回数组中的字段

//使用方法进行过滤

console.log(JSON.stringify(book, function (key, val) {

switch (key) {

case 'price':

return "$" + val + ".00";

case "title":

return undefined;//去掉title

default:

return val;

}

}));//{"edtion":"2010","price":"$20.00"}

toJSON:

var book = {

"title": "Time",

"edtion": '2010',

'price': 20,

toJSON: function () {

return this.title;

}

};

//1. 如果存在 toJSON ,则直接调用 toJSON

//2. 如果存在第二个参数,则应用函数过滤器,传入的值是第一步返回的值

//3. 对第二步的值进行序列化

//4. 如果提供了第三个参数,执行相应的格式化

console.log(JSON.stringify(book));//"Time"

parse()

//使用第二个参数进行还原操作

JSON.parse(txt, function (key,val) {

if (key == "time") {

return new Date(val);

}

else {

return val;

}

})

*********************    Chapter 21 Ajax 与 Comet    *********************

XMLHttpRequest 对象:

响应属性:

responseText:

responseXML:

status:

statusText:

同步请求:

var xhr = new XMLHttpRequest();

//同步请求的方式

xhr.open("get", "test.ashx", false);

xhr.send(null);

if ((xhr.status >= 200 && xhr.status < 300)  || xhr.status == 304) {

console.log(xhr.responseText);

} else {

console.log("error: " + xhr.status);

}

异步请求:

readyState:

0:未初始化

1:启动

2:发送

3:接收

4:完成

var xhr = new XMLHttpRequest();

xhr.onreadystatechange = function () {

if (xhr.readyState == 4) {

if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {

console.log(xhr.responseText);

} else {

console.log("error: " + xhr.status);

}

}

}

xhr.open("get", "test.ashx", true);

xhr.send();

//可以设置终止请求

xhr.abort();

xhr = null;

HTTP头部信息:

Accept

Accept-Charset

Accept-Encoding

Accept-Language

Conenction

Cookie

Host

Referer

User-Agent

GET

var url = "Test.ashx";

addUrlParams(url, "name", "kk");

//get 请求的参数的查询字符串需要进行 encodeURIComponent编码

xhr.open("get", url, true);

//设置自定义的请求头,必须在 open()之后,send()之前

xhr.setRequestHeader("MyHeader", "haha");

xhr.send();

POST

xhr.open("post", "Test.ashx", true);

xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

var form = document.getElementById("f1");

xhr.send(serialize(form));

XMLHttpRequest 2级:

FormData:

var xhr = new XMLHttpRequest();

xhr.onreadystatechange = function () {

if (xhr.readyState == 4) {

if (xhr.status == 200) {

//...

}

}

}

xhr.open('post', 'Tst.ashx', true);

xhr.send(new FormData(document.getElementById('f1')));

超时设定:

xhr.open('post', 'Tst.ashx', true);

xhr.timeout = 1000;//超时设置为 1s

xhr.ontimeout = function () {

console.log('request over time');

}

xhr.send(new FormData(document.getElementById('f1')));

overrideMimeType() 方法:

xhr.open('post', 'Tst.ashx', true);

//强制响应对象作为 XML 处理

xhr.overrideMimeType("text/xml");

xhr.send(new FormData(document.getElementById('f1')));

进度事件:

load:

//不需要去检查 readyState=4

xhr.onload = function () {

if ((xhr.status >= 200 && xhr.status < 300)||xhr.status == 304){

console.log(xhr.responseText);

} else {

//

}

}

progress:

//接收数据期间周期性的触发

xhr.onprogress = function (event) {

var divStatus = document.getElementById("status");

if (event.lengthComputable) {

divStatus.innerHTML = "Received: " + event.position + ", total:" + event.totalSize + " bytes";

}

}

跨源资源共享:CORS

IE对CORS的实现:

var xdr = new XDomainRequest();

xdr.onload = function () {

console.log(xhr.responseText);

}

xdr.onerror = function () {

console.log("error");

}

xdr.timeout = 1000;

xdr.ontimeout = function () {

console.log("...");

}

//get

xdr.open("get", "http://.......");

xdr.send(null);

//post

xdr.open("post", "http://......");

xdr.contentType = "application/x-www-form-urlencoded";

xdr.send("name=test&age=18");

其他浏览器对CORS的实现:

直接使用 XMLHttpRequest 方式,传入绝对URL

不能使用 setRequestHeader() 设置自定义头部

不能发送和接收cookie

调用getAllResponseHeader()方法总会返回空字符

Preflighted Requests:

IE10及之前不支持

带凭据的请求:

IE10及之前不支持

Access-Control-Allow-Credentials:true

跨浏览器的CORS:

function createCROSRequest(method, url) {

var xhr = new XMLHttpRequest();

if ("withCredentials" in xhr) {

xhr.open(method, url, true);

} else if (typeof XDomainRequest != 'undefined') {

xhr = new XDomainRequest();

xhr.open(method, url);

} else {

xhr = null;

}

return xhr;

}

var request = createCROSRequest("get", "http://...");

if (request) {

request.onload = function () {

//处理responseText

};

request.send();

}

其他跨域技术:

图像Ping

只能应用于get请求

不能处理响应数据

var img = new Image();

img.onload = img.onerror = function () {

console.log('OK');

}

img.src = "http://www.xx.com?name=test";

JSONP:

JSON with padding

安全性问题得不到保证

function handler(response) {

console.log(response.data);

}

var script = document.createElement("script");

script.src = 'http://www.xx.com?callback=handler';

document.body.insertBefore(script, document.body.firstChild);

Comet:

短轮询和长轮询

HTTP流

//IE不兼容

function createStreamClient(url,process,finish) {

var received = 0;

var xhr = new XMLHttpRequest();

xhr.open('get', url, true);

xhr.onreadystatechange = function () {

//不断从服务端接收数据,readyState 周期性变为3

if (xhr.readyState == 3) {

var res = xhr.responseText.substring(received);

received += res.length;

process(res);

} else if (xhr.readyState == 4) {

finish(xhr.responseText);

}

}

xhr.send();

return xhr;

}

var client = createStreamClient("http://", function (data) { }, function (data) { })

服务器发送事件:

SSE: Server-Sent Events

IE不兼容

var es = new EventSource("Test.ashx");

//open mesasge error

es.onmessage = function (event) {

var data = event.data;

console.log(es.readyState);//0:正在连接  1:打开了连接   2:关闭了连接

console.log(data);

}

//es.close();

//服务端

public void ProcessRequest(HttpContext context)

{

//var header = context.Request.Headers["MyHeader"];

//context.Response.Headers["MyHeader"] = header;

context.Response.ContentType = "text/event-stream";

context.Response.Write("data:test" );//需要使用data: 前缀

context.Response.Write("\n\n");//必须要以 空行结尾

}

Web Sockets:

socket 状态:

WebSocket.OPENING(0)

WebSocket.OPEN(1)

WebSocket.CLOSING(2)

WebSocket.CLOSE(3)

var socket = new WebSocket("http://www.xx.com");

socket.onopen = function () {

}

socket.onerror = function () {

}

socket.onclose = function (event) {

console.log(event.wasClean);

console.log(event.code);

console.log(event.reason);

}

socket.send("haha");

socket.close();

*********************    Chapter 22 高级技巧     *********************

高级函数:

安全的类型检测:

function isArray(val) {

return Object.prototype.toString.call(val) == '[object Array]';

}

作用域安全的构造函数:

function Person(name, age) {

if (this instanceof Person) {

//这里检测了this , 也就是如果没有 使用 new 关键字,也不会绑定到window 对象上

this.name = name;

this.age = age;

} else {

return new Person(name, age);

}

}

//没有使用 new

var p = Person("test", 20);

console.log(p.name);

//继承的实现

function Person(name, age) {

if (this instanceof Person) {

//这里检测了this , 也就是如果没有 使用 new 关键字,也不会绑定到window 对象上

this.name = name;

this.age = age;

} else {

return new Person(name, age);

}

}

function Man(name, age) {

Person.call(this, name, age);

this.gender = 1;

}

//this instanceof Person  == true

Man.prototype = new Person();//这样子使用之后 ,this 就可以是Person

var m = new Man('man', 30);

console.log(m.name);

惰性载入函数:

function createXHR() {

if (typeof XMLHttpRequest != 'undefined') {

createXHR = function () {

return new XMLHttpRequest();

}

} else if (typeof ActiveXObject != 'undefined') {

createXHR = function () {

var versions = ["MSXML2.XMLHttp6.0", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp"];

for (var i = 0, len = versions.length; i < len; i++) {

try {

new ActiveXObject(versions[i]);

arguments.callee.activeString = versions[i];

break;

} catch (e) {

//next

}

}

return new ActiveXObject(arguments.callee.activeString);

}

} else {

createXHR = function () {

throw new Error("No XHR...");

}

}

}

函数绑定:

var handler = {

mesasge: "hello handler",

handlerClick: function () {

alert(this.mesasge);

}

};

var btn = document.getElementById("btn");

//btn.addEventListener("click", handler.handlerClick);//undefined

//自定义bind() 函数绑定方法,指定 this

btn.addEventListener("click", bind(handler.handlerClick, handler));//hello handler

//ES5 原生bind() 方法

//btn.addEventListener("click", handler.handlerClick.bind(handler));//hello handler

function bind(fn,context) {

return function () {

fn.apply(context, arguments);

}

}

函数柯里化:

function curry(fn) {

var args = Array.prototype.slice.call(arguments, 1);

return function () {

console.log(Array.isArray(arguments));//false

var innerArgs = Array.prototype.slice.call(arguments);// arguments 类型变为 Array

console.log(Array.isArray(innerArgs));//true

var finnalArgs = args.concat(innerArgs);

return fn.apply(null, finnalArgs);

};

}

function add(num1, num2) {

return num1 + num2;

}

var curAdd = curry(add,10);

var res = curAdd(3);

console.log(res);//13

//柯里化与bind的使用

function bind(fn, context) {

var args = Array.prototype.slice.call(arguments, 2);

return function () {

var innerArgs = Array.prototype.slice.call(arguments);

var finArgs = args.concat(innerArgs);

return fn.apply(context, finArgs);

};

}

var handler = {

mesasge: "hello handler",

handlerClick: function (name,event) {

alert(this.mesasge + ", Name: " + name);

}

};

var btn = document.getElementById("btn");

btn.addEventListener("click", bind(handler.handlerClick, handler, 'btn'));//

//ES5

btn.addEventListener("click", handler.handlerClick.bind(handler,"btn");//

防篡改对象:

不可扩展对象:

var person = { 'name': "jk" };

console.log(Object.isExtensible(person));//true

//禁止扩展对象

Object.preventExtensions(person);

console.log(Object.isExtensible(person));//false

person.age = 19;

console.log(person.age);//undefined

密封的对象:

Object.seal(person);

delete person.name;

console.log(person.name);//jk

console.log(Object.isSealed(person));//true

console.log(Object.isExtensible(person));//false

冻结的对象:

Object.freeze(person);//不可扩展,密封的,writable =false

Object.isFrozen(person);

高级定时器:

重复的定时器:

var div = document.getElementById("div");

setTimeout(function () {

var left = parseInt(div.style.left) + 5;

console.log(left);

div.style.left = left + "px";

if (left < 500) {

//重复性

setTimeout(arguments.callee, 25);

}

}, 25)

Yielding Processes:

function trunk(arr,process,context) {

setTimeout(function () {

var item = arr.shift();

process.call(context, item);

if (arr.length > 0) {

setTimeout(arguments.callee, 100);

}

}, 100);

}

函数节流:

function throttle(method,context) {

clearTimeout(method.tId);

method.tId = setTimeout(function () {

method.call(context);

}, 100);

}

function resizeDiv() {

var div = document.getElementById("div");

div.style.height = div.offsetWidth + "px";

}

window.onresize = function () {

throttle(resizeDiv);

}

自定义事件:

function EventTarget() {

this.handlers = {};

}

EventTarget.prototype = {

constructor: EventTarget,

addHandler: function (type, handler) {

if (typeof this.handlers[type] == "undefined") {

this.handlers[type] = [];

}

this.handlers[type].push(handler);

},

fire: function (event) {

if (!event.target) {

event.target = this;

}

if (this.handlers[event.type] instanceof Array) {

var handlers = this.handlers[event.type];

for (var i = 0; i < handlers.length; i++) {

handlers[i](event);

}

}

},

removeHandler: function (type,handler) {

if (this.handlers[type] instanceof Array) {

var handlers = this.handlers[type];

for (var i = 0; i < handlers.length; i++) {

if (handlers[i] == handler) {

break;

}

}

}

handlers.splice(i, 1);

}

}

//Demo

function handleMsg(event) {

console.log("Msg:" + event.message);

}

var target = new EventTarget();

target.addHandler("message", handleMsg);

target.fire({type:"message",message:"this is test!"});

target.removeHandler("message", handleMsg);

target.fire({ type: "message", message: "this is test!" });

拖放:

var dargDrop = function () {

var dragging = null;

function handleEvent(event) {

var target = event.srcElement;

switch (event.type) {

case "mousedown":

if (target.className.indexOf("draggable") > -1) {

dragging = target;

}

break;

case "mousemove":

if (dragging != null) {

dragging.style.left = event.clientX + "px";

dragging.style.top = event.clientY + "px";

}

break;

case "mouseup":

dragging == null;

break;

}

}

return {

enable: function () {

document.addEventListener("mousedown", handleEvent);

document.addEventListener("mousemove", handleEvent);

document.addEventListener("mouseup", handleEvent);

},

disable: function () {

document.removeEventListener("mousedown", handleEvent);

document.removeEventListener("mousemove", handleEvent);

document.removeEventListener("mouseup", handleEvent);

}

};

}();

dargDrop.enable();

*********************    Chapter 23 离线应用与客户端存储     *********************

离线检测:

navigator.onLine;//状态

window.ononline = function () {

}

window.onoffline = function () {

}

应用缓存:

缓存文件关联:

<html manifest="/offline.manifest">

applicationCache的status:

0:无缓存

1:闲置

2:检查中

3:下载中

4:更新完成

5:废弃

applicationCache.update();

数据存储:

Cookie:

IE用户数据:

Web存储机制:

Storage:

sessionStorage:

浏览器关闭后消失

for (var i = 0; i < sessionStorage.length; i++) {

var key = sessionStorage.key(i);

var val = sessionStorage.getItem(key);

}

for (var key in sessionStorage) {

var val = sessionStorage.getItem(key);

}

localStorage:

localStorage.name = 'test';

console.log(localStorage.getItem('name'));

localStorage.removeItem('name');

storage事件:

event属性:

domain

key

newValue

oldValue

*********************    Chapter 24 最佳实践     *********************

可维护性:

什么是可维护的代码

代码约定

松散耦合

编程实践

尊重对象的所有权:

不要为实例或原型添加属性

不要为实例或原型添加方法

不要重定义已存在的方法

避免全局量

命名空间的使用方式:

var MyTool = {}

MyTool.EventUtil={}

MyTool.CookieUtil={}

避免与null进行比较:

使用常量:

重复值

用户界面字符串

URLs

任意可能会更改的值

性能:

注意作用域:

避免全局查找

避免with语句

选择正确的方法:

避免不必要的属性查找

减少算法复杂度

O(1)

O(n)

优化循环

减值迭代:从最大值开始到0的循环

简化终止条件:

简化循环体:

使用后测试循环:do-while

展开循环:

避免双重解释:

eval()或者Function构造函数或者setTimeout()传入字符串

性能的其他注意事项:

原生方法较快

Switch语句较快

位运算符较快

最小化语句数:

多个变量声明:

var i=0,name="jk",arr=[]

插入迭代值:

var val = values[i];

i++;

优化:

var val= values[i++];

使用数组和对象字面量:

var person={};

var arr=[1,2,3];

优化DOM交互:

最小化现场更新:

var list = document.getElementById("myList"),

fragement = document.createDocumentFragment(),

item, i;

for (i = 0; i < 10; i++) {

item = document.createElement("li");

fragement.appendChild(item);

item.appendChild(document.createTextNode("Item" + i));

}

list.appendChild(fragement);

使用innerHTML

使用事件代理

使用的是事件冒泡的原理

注意HTMLCollection:

var imgs = document.getElementsByTagName("img"),img;

for (var i = 0, len = imgs.length; i < len; i++) {

img = imgs[i];

//处理

}

部署:

构建过程:

知识产权问题

文件大小

代码组织

Ant构建工具

验证:

JSLint

压缩:

文件压缩:

删除额外的空白

删除所有注释

缩短变量名

HTTP压缩:

*********************    Chapter 25 新兴的API  *********************

Javascript 高级程序设计--总结【四】的更多相关文章

  1. JavaScript高级程序设计学习(四)之引用类型

    在javascript中也是有引用类型的,java同样如此. javascript常见也比较常用的引用类型就熟Object和Array. 一个对象和一个数组,这个在前后端分离开发中也用的最多.比如aj ...

  2. JavaScript高级程序设计学习(四)之引用类型(续)

    一.Date类型 其实引用类型和相关的操作方法,远远不止昨天的所说的那些,还有一部分今天继续补充. 在java中日期Date,它所属的包有sql包,也有util包.我个人比较喜欢用util包的.理由, ...

  3. javascript高级程序设计第四章 变量、作用域和内存问题

    变量包含两种,,基本类型和引用类型 基本类型是指一些简单的字段: 引用类型是☞由多个值构成的对象  引用类型的值是保存在内存中的对象,在javascript中是不允许直接访问内存中的位置; 函数的参数 ...

  4. 读书时间《JavaScript高级程序设计》四:BOM,客户端检测

    隔了一段时间,现在开始看第8章. 第8章:BOM BOM提供了很多对象,用于访问浏览器的功能.BOM的核心对象是window,它表示浏览器的一个实例. window对象是通过javascript访问浏 ...

  5. JavaScript高级程序设计(第4版)知识点总结

    介绍 JavaScript高级程序设计 第四版,在第三版的基础上添加了ES6相关的内容.如let.const关键字,Fetch API.工作者线程.模块.Promise 等.适合具有一定编程经验的 W ...

  6. 《Javascript高级程序设计》阅读记录(四):第五章 下

    这个系列,我会把阅读<Javascript高级程序设计>之后,感觉讲的比较深入,而且实际使用价值较大的内容记录下来,并且注释上我的一些想法.做这个一方面是提升了我的阅读效果以及方便我以后阅 ...

  7. 《Javascript高级程序设计》阅读记录(二):第四章

    这个系列之前文字地址:http://www.cnblogs.com/qixinbo/p/6984374.html 这个系列,我会把阅读<Javascript高级程序设计>之后,感觉讲的比较 ...

  8. 《JavaScript高级程序设计(第3版)》阅读总结记录第一章之JavaScript简介

    前言: 为什么会想到把<JavaScript 高级程序设计(第 3 版)>总结记录呢,之前写过一篇博客,研究的轮播效果,后来又去看了<JavaScript 高级程序设计(第3版)&g ...

  9. 《JavaScript高级程序设计》学习笔记(5)——面向对象编程

    欢迎关注本人的微信公众号"前端小填填",专注前端技术的基础和项目开发的学习. 本节内容对应<JavaScript高级程序设计>的第六章内容. 1.面向对象(Object ...

  10. 《JavaScript高级程序设计》学习笔记(4)——引用类型

    欢迎关注本人的微信公众号"前端小填填",专注前端技术的基础和项目开发的学习. 本节内容对应<JavaScript高级程序设计>的第五章内容. 在ECMAScript中, ...

随机推荐

  1. 配置babel

    配置babel ECMAScript的版本,每年都会定期举行会议,发布各种标准,当前版本到了2019,但大部分人使用的浏览器,都可以支持es2015,也就是es6,要等到大部分浏览器都支持到最新版本, ...

  2. leetcode — combination-sum

    import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * Source : https://o ...

  3. 使用minukube部署kubernetes admission webhook实现etcd pod安全删除

    本需求来自于一道面试题

  4. vim之添加多行和删除多行

    1.复制单行和多行. 1)单行复制 在命令模式下,将光标移到将要复制的行处,按“yy”进行复制,按“p”进行粘贴. 2)多行复制 在命令模式下,将光标移到将要复制的行处,按“nyy”进行复制(n代表行 ...

  5. 分布式系统监视zabbix讲解二之邮件报警通知--技术流ken

    概述 在上一篇博客<分布式系统监视zabbix讲解一技术流ken>中已经详细讲解了如何安装zabbix,本篇博客将详细讲解如何使用zabbix监控另外一台主机,并实现email报警通知机制 ...

  6. NTP时间服务器实战应用详解-技术流ken

    简介 在搭建集群服务中,要保证各节点时间一致,NTP时间服务器就成为了一个好帮手了. 系统环境 系统版本:centos6.7 服务器IP:10.220..5.166/24 客户端IP:10.220.5 ...

  7. 南大算法设计与分析课程复习笔记(3)L3 - Recursion

    一.递归方程 按照分治的思想,可以将一个递归的复杂度写成递归方程 一.解递归方程--猜然后证明 该方法又称为代入法,步骤如下: 1.猜解的形式 2.数学归纳法证明正确 例子: 我们假设有如下递归式: ...

  8. 【golang-GUI开发】Qt5的安装

    golang一直被认为没有好的GUI库,事实并非如此. 目前有基于gtk+3.0的gotk3:https://github.com/gotk3/gotk3 以及接下来我们要说的qt:https://g ...

  9. 关于div容器在ie6下默认高度不为0(存在默认高度)

    最近做项目的时候遇到一个问题,相信很多人都遇到过,就是在测试兼容性的时候,在ie6下小于12px 的背景的高度不等于原高,或许这样说你可能不是很明白,那就举个例子吧! 如图所示: 锯齿状的背景图本来是 ...

  10. [转]Laravel - Where null and Where not null eloquent query example

    本文转自: https://hdtuto.com/article/laravel-where-null-and-where-not-null-eloquent-query-example- if yo ...