zoukankan      html  css  js  c++  java
  • 《精通javascript》5,6章小结(一)

      最近看《精通javascript》,作者是jquery之父,相信很多学习javascript的园友也看过这本书,值得研习。看完第五章(the document object model)和第六章(events)感觉还是很受益的,虽然之前对dom和event也算了解,但这次应该说理解更深入了些。

         在遍历Dom中,有个要注意的问题就是,dom中节点的指针(如elem.parentNode, elem.firstChild, elem.nextSibling等)可以指向元素节点,也可以指向文本节点,这里就会造成一定的混乱,比如:

    1     <div id="content">
    2        <p>This is main content area</p>
    3     </div>

    你会怎么定位div中的p元素,可能会想当然的document.getElementById("content").firstChild,遗憾的是得到的是个"\n"(一个文本类型的节点nodeType为3),

    你要用document.getElementById("content").firstChild.nextSibling才行,这样是不是很麻烦,而且不够简洁和利于阅读。书中封装了一些简单的遍历dom的方法。

     1     function prev(elem) {
     2       do {
     3         elem = elem.previousSibling;
     4       } while(elem && elem.nodeType != 1); // nodeType为1表明节点为元素如:<p>,<a>
     5           
     6         return elem;
     7     }
     8 
     9     function next(elem) {
    10       do {
    11         elem = elem.nextSibling;
    12       } while( elem && elem.nodeType != 1);
    13         
    14         return elem;
    15     }
    16 
    17     function first(elem) {
    18         elem = elem.firstChild;
    19         
    20         return elem && elem.nodeType != 1 ?
    21             next(elem) : elem;
    22     }
    23 
    24     function last(elem) {
    25       elem = elem.lastChild;
    26         
    27         return elem && elem.nodeType != 1 ?
    28             prev(elem) : elem;
    29     }
    30 
    31     function parent(elem, num) {
    32         //如果num不提供的话,就默认1, 指元素嵌套层数
    33       num = num || 1; 
    34         
    35         for(var i = 0; i < num; i++) {
    36             if(elem != null ) elem = elem.parentNode;
    37       }
    38 
    39         return elem;
    40     }

    通过这些简单的函数,我们可以像这样遍历dom:first(document.getElementById("content"));这似乎好多了,但是如果让函数的调用换成这种形式应该更符合习惯:document.body.first().next(),我们可以通过扩展HTMLElement达到这样的效果(可惜该死的IE中不能直接访问HTMLElement对象)。

    1     HTMLElement.prototype.next = function() {
    2         var elem = this;
    3         
    4         do {
    5             elem = elem.nextSibling;
    6         } while(elem && elem.nodeType != 1);
    7         
    8         return elem;
    9     }

    书中也提到了很常用的getElementByID和getElementsByTagName方法,并提供了简单的封装

    1     function tag(name, elem) {
    2         //如果elem没提供,那么默认document
    3       return (elem || document).getElementsByTagName(name);
    4     }
    5 
    6     function id(elemId) {
    7       return document.getElementById(elemId);
    8     }

    接下来的一个重点是waiting for the  HTML DOM to load这点很重要,作者也特别说明了下网页加载的顺序:

      1.HTML被浏览器解析

          2.外部的js和css被载入

          3.当在文档中js被解析时,js被执行

          4.HTML DOM构造完成

          5.图片和外部内容被载入

          6.页面加载完成

    很显然这里就有个问题,较文档靠前的js或是外部载入的js,如果没等HTML DOM全部构造完,那么这些js对DOM的访问当然会出现问题,作者就此问题给出了几个解决方案。

    1.利用window.onload事件,这里为了说明我改了原文中的那addEvent方法(那个复杂些Dean Edwards写的

     1     function addEvent(obj, event, eventHandler) {
     2       if(obj.addEventListener) { 
     3             //非IE浏览器 W3C标准
     4         obj.addEventListener(event, eventHandler, false);  
     5       } else if (obj.attachEvent) { 
     6             //写到这里,我就觉得IE该死。。。
     7         event = "on" + event;
     8             obj.attachEvent(event, eventHandler);
     9       }
    10     }

    然后我们可以这样:

    1     addEvent(window, "load", function() {
    2         first(id("content")).style.background = 'blue';
    3     });

    这个方法很常用,觉得不错。

    2.就是把js的执行代码放到DOM的最后位置

    1       <h1>Testing DOM loading</h1>
    2         <!-- lots of HTML goes here -->
    3         <script type="text/javascript">
    4             init();//这里的init方法已写在<head>中 
    5         </script>

    3.这个方法是作者自己写的一个确认dom load结束的一个函数,主要是用来实时监控dom文档的状态,代码如下:

     1     function isDOMReady() {
     2     //如果我们已经确认页面加载结束,那么忽略
     3         if(domReady.done) return false;
     4 
     5         //看看是否一些函数和元素能够被访问
     6         if(document && document.getElementsByTagName && document.getElementById && document.body) {
     7             //如果一切就绪,我们停止检查
     8             clearInterval(domReady.timer);
     9 
    10             domReady.timer = null;
    11 
    12             //执行列队中所有的函数
    13             for(var i = 0; i < domReady.ready.length; i++) {
    14                 domReady.ready[i]();
    15             }
    16 
    17             //记住我们现在搞定了
    18             domReady.ready = null;
    19             domReady.done = true;
    20     }
    21     }
    22 
    23     function domReady(f) {
    24       //如果DOM已经加载结束,那么马上执行该函数
    25           if(domReady.done) return f();
    26 
    27           //如果我们已经添加了一个函数
    28           if(domReady.timer) {
    29         //将它加入到执行列表中
    30         domReady.ready.push(f);
    31       } else {
    32         //为页面加载完毕附加一个事件
    33             addEvent(window, 'load', isDOMReady);
    34 
    35             //初始化执行函数列表
    36             domReady.ready = [f];
    37 
    38             //尽快检查DOM是否加载完毕
    39             domReady.timer = setInterval(isDOMReady, 13);
    40       }
    41     }

    作者介绍了些找元素的方法,有个Finding Elements by Class Name,实现如下:

     1     function hasClass(name, type) {
     2         var r = [];
     3 
     4         //定位class name(允许多个class)
     5         var re = new RegExp("(^|\\s)" + name + "(\\s|$)");
     6         var e = document.getElementsByTagName(type || "*");
     7 
     8         for(var j = 0; j < e.length; j++) {
     9             //如果该元素有该class,那么加入到结果集
    10             if( re.test(e[j].className) )  r.push(e[j]);
    11         }
    12 
    13         return r;
    14     }

    今天就先到这,明天继续复习.......

  • 相关阅读:
    不孤独的程序猿是可耻的
    mjpg-streamer摄像头远程传输UVC
    Making Your ActionBar Not Boring
    fortran 函数的调用标准
    《从0到1》:硅谷创业明星沉思录,五星推荐。
    《创业维艰》:五星推荐。硅谷扫地僧武功秘籍。
    《大江东去》:五星推荐。改革开放前20年的典型商业冒险故事,个体户、集体企业、国企厂长、官二代的命运起伏(严重剧透)
    《经与史》:比较深刻地总结中国历史背后的规律的一本奇书,基本观点之一是:中国历史是蛮族与吏治社会的互动与转化。五星推荐
    《清明上河图密码2》北宋首都的扰乱大宗商品交易秩序的大案。精妙的推理过程与大量细致的当时商业与生活细节同时出现在书中,五星推荐
    《重新定义公司:谷歌是如何运营的》比较全面的谷歌公司的管理技巧,五星推荐
  • 原文地址:https://www.cnblogs.com/AndyWithPassion/p/professional_js_1.html
Copyright © 2011-2022 走看看