zoukankan      html  css  js  c++  java
  • Javascript 高级程序设计--总结【四】

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

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

    选择符API:

             document.querySelector('.img');

             document.querySelector('#test');

             document.querySelectorAll('a');

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

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

    元素遍历:

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

             //因为使用 childNodesfirstChildlastChild 不同的浏览器效果不一样

             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;//loadingcomplete

                       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 获取自定义属性

                       FirefoxchromeIE11+ 支持

                                <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 之后的同辈节点

                       内存与性能问题:

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

             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. 客户区大小

                                clientWidthclientHeight

                               

                                var ele = document.getElementById("");

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

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

                                //获取视口的大小

                                function getViewport() {

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

                                                   return {

                                                            document.body.clientWidth,

                                                            height: document.body.clientHeight

                                                   };

                                         } else {

                                                   return {

                                                            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事件:

                       loadunloadaborterrorselect esizescroll

                       img 也可以使用 load 事件

             焦点事件:

                       blur(不支持冒泡)DOMFocusInDOMFocusOutfocus(不支持冒泡)focusin(支持冒泡)focusout

             鼠标与滚轮事件:

                       clickdbclickmousedownmouseenter(不冒泡)mouseleave(不冒泡)mousemovemosueoutmouseovermouseup                  

                       mousewheel

                       clientXclientY:相对视口的位置

                       pageXpageY:相对页面的位置

                       screenXscreenY:相对屏幕的位置

                       event.shiftKeyevent.ctrlKeyevent.altKeyevent.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,而是使用keychar

                                location|keyLocation

                                getModifierState('Shift')

                       textInput事件:IE9+

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

                                event.data 返回实际字符;

                                event.inputMethod 返回输入模式

                      

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

                       compositionstartcompositionupdatecompositionend

                      

             变动事件:

                       删除节点:

                                DOMNodeRemovedDOMSubtreeModifiedDOMNodeRemovedDOMNodeRemovedFromDocument

                       插入节点:

                                DOMNodeinsertedDOMSubtreeModifiedDOMNodeInsertedDocument

                      

             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.rotateevent.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()lur():

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

    文本框脚本:

             选择文本:

            select():

                     //选中输入框文本

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

            selectionStartselectionEnd:

                     //获取文本选中位置     

                     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();

                }

            }

                 操作剪贴板:

                          copcutpaste

                          //获取剪贴板内容

                          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

                       dragleavedrop

                       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(" ");//必须要以 空行结尾

            }

        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  *********************               

        

  • 相关阅读:
    敏捷实践-学习实践资料汇总
    从数据仓库到数据湖—浅谈数据架构演进
    JVM知识点汇总备忘
    Protobuf的使用和原理
    kafka数据定时导入hive便于后续做数据清洗
    Mybatis Mapper接口动态代理实现原理及二次开发
    软考论文-写作大纲-备考思路总结
    css3另一个属性写法
    css3动画效果
    jquery点击鼠标后关闭图片
  • 原文地址:https://www.cnblogs.com/yougmi/p/8980128.html
Copyright © 2011-2022 走看看