<<JavaScript DOM 编程艺术>&

作者: McRay | 来源:发表于2017-01-15 21:23 被阅读19次

    第一章 JavaScript 简史


    主要讲了JavaScript的起源和发展.

    第二章 JavaScript语法


    2.1 准备工作

    2.2 语法


    2.2.1 语句

    如果你想把多条语句放在同一行上,就必须用分号来分隔开它们。

    2.2.2 注释
    • //自我提醒:有注释是好事
    • /*自我提醒:
      有注释是好事
    2.2.3 变量
    • javascript允许程序员直接对变量赋值而无需事先声明
    • 不允许变量名中包含空格或标点符号(美元符号”$"例外)
    • 一般使用驼峰格式来起变量的名字
    2.2.4 数据类型

    1.字符串
    2.数值
    3.布尔值

    2.2.5 数组
    2.2.6对象

    2.3 操作


    • 算术操作符

    加号(+)是一个比较特殊的操作符,它即可以用于数值,也可以用于字符串

    2.4 条件语句


    • 比较操作符
    • 逻辑操作符

    2.5 循环语句


    • while循环
    • for循环

    2.6 函数


    变量的作用域

    如果在某个函数中使用了var,那个变量就将被视为一个局部变量,它只存在于这个函数的上下文中;反之,如果没有使用var,那个变量就将被视为一个全局变量。

    2.7 对象


    • 内建对象

    包括Array对象,Math对象和Date对象

    • 宿主对象

    由浏览器提供的预定义对象被称为宿主对象,包括Form、Image和Element等。

    第三章 DOM


    3.1 文档:DOM中的"D"

    3.2 对象:DOM中的"O"

    3.3 模型:DOM中的"M"

    3.4 节点


    • 元素节点
    • 文本节点
    • 属性节点
    • 获取元素

    1.getElementById

    • 返回一个与那个有着给定id属性值的元素节点对应的对象
    • 它是document对象特有的函数
    • 可以通过typeof操作符在确定操作数是一个字符串、数组、函数、布尔值还是对象。

    2.getElementsByTagName

    • 返回一个对象数组,每个对象分别对应着文档里有着给定标签的一个元素。
    • 运行把一个通配符"*"作为它的参数。

    3.getElementsByClassName

    • 返回一个与那个有着给定class属性值的元素节点对应的对象

    3.5 获取和设置属性


    1.getAttribute(attribute)
    2.setAttribute(attribute,value)

    第三章 JavaScript图片库

    第五章 最佳实践

    第六章 图片库的改进版


    第四章将html,css与javascript运用到了JavaScript图片库上

    • 为了减少对站点的请求次数(提高性能),应该把这些.js文件合并到一个文件中;
    • 事件处理函数:在特定事件发生时,调用特定的JavaScriptd代码;
    • nodeValue属性:用来得到和设置一个节点的值;
    • 包含在<p>元素里的文本是另一个节点,它是<p>元素的第一个子节点;
    • firstChild和lastChild属性,子节点的第一个和最后一个元素;
    • childNodes属性:可以用来获取任何一个元素的所有子元素,是一个包含这个元素全部子元素的数组;
    • onload事件处理函数:函数在页面加载时执行;
    • nodeType属性:返回节点的类型;
    事件处理函数的工作机制:

    以onclick为例:我们给某个链接添加一个onclick事件处理函数,并让这个处理函数所触发的js代码返回布尔值true或false,这样一来,当这个链接被点击时,如果那段js代码返回的值是true,onclick事件处理函数就认为被点击了;反之,则没有被点击。
    节点的类型总共有12种可取值,有3种具有实用价值:

    • 元素节点的nodeType属性值是1
    • 属性节点的nodeType属性值是2
    • 文本节点的nodeType属性值是3
    第五章介绍了最佳实践

    在本章作者提出了一些好的网站应该满足的要求:
    1、在使用任何一句javascript代码时,都应该想想,对这个网页是否有用;
    2、平稳退化:如果正确使用了javascript脚本,可以让访问者在他们的浏览器不支持javascript的情况下仍能顺利地浏览你网站。虽然某些功能无法使用,但是最基本的操作仍能顺利完成;
    3、渐进增强:用额外的信息层区包裹原始数据;使CSS代码负责提供关于表示的信息,javascript代码负责提供关于行为的信息;
    4、分离javascript:在HTML文档中使用诸如onclick之类的属性也是一种没有效率又容易引发问题的做法。如果利用像CSS中的class和id属性那样,把javascript代码调用行为与HTML文档内容和结构分离,网页也会健壮不少。
    5、向后兼容:对象检测:检测浏览器对javascript的支持程度。用一个if语句的条件表达式看求值结果是true还是false来采取不同的行动。如在代码前加上if(!getElementById) return false;
    6、性能考虑:尽量少访问DOM和尽量减少标记
    不管什么时候只要是查询DOM中的某些元素,浏览器就会搜索整个DOM树,从中查到可能匹配的元素。
    在多个函数都会取得类似元素的情况下,可以考虑重新构建代码,把搜索结果保存在一个全局变量里,或者把一组元素以参数形式传递给函数。
    减少标记数量的目的在于,过多的不必要的元素只会增加DOM树的规模;
    7、合并和放置脚本:减少请求数量是在性能优化时首先要考虑的;把所有<script>标签都放在文档的末尾,</body>标记之前,可以让页面变得更快。
    8、压缩脚本:指的是把脚本文件中的不必要的字节,如空格和注释,都删除调,从而达到“压缩”文件的目的;多数情况下应该有两个版本,一个是工作副本,可以修改代码并添加注释,另一个是精简副本,用于放在站点上,通常在精简副本的文件名上加上min字样;
    一些新的概念:
    1、“javascript"伪协议:真协议让我们在因特网上的计算机之间传输数据包,伪协议是一种非标准化的协议,让我们通过一个链接调用javascript函数;
    2、浏览器嗅探技术:通过浏览器供应商提供的信息来解决向后兼容的问题。
    3、document对象是window对象的一个属性,当window对象触发onload事件时,document对象已经存在,文档树就会被创建成功;

    第六章对图片库进行了优化

    以下是本章的一些其他要点:
    1、结构化程序设计要求函数只有一个入口和出口。但只要出口集中出现在函数的开头部分就是可以接受的。
    2、每个事件处理函数只能绑定一条指令。
    3、nodeName属性总是返回一个大写字母的值,即时元素在HTML文档中是小写字母。
    4、键盘访问:最好不要使用onkeypresss事件处理函数,onclick事件处理函数已经能满足需要,它对键盘的访问相当完美

    html代码:

    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>javascript dom图片库</title>
        <script src="javascript图片库.js"></script>
            <style>
           *{
            margin:0;
            padding:0;
           }
           body{
            background-color:#ccc;
            margin: 1em 10%;
           }
           h1 {
            color:#333;
            background-color:transparent;
           }
           li{
            float:left;
            padding: 1em;
            list-style:none;
           }
           img,p{
            display:block;
            clear:both;
           }
           #imagegallery li{
            display:inline;
           }
           #imagegallery li a img{
            border:0;
            width:100px;
            height:100px;
           }
        </style>
    </head>
    <body>
        <h1>Snapshots</h1>
        <ul id="imagegallery">
          <li>
            <a href="images/1.jpg" title="a 1 display" class="showPic">
                ![](images/1.jpg)
            </a>
          </li>
          <li>
            <a href="http://www.baidu.com/" class="popup" title="a 2 display" onclick="popUP(this.getAttribute("href"));return false;">平稳退化</a>
          </li>
          <li>
            <a href="images/2.jpg" class="showPic" title="a 2 display">
                ![](images/2.jpg)
            </a>
          </li>
          <li>   
            <a href="images/3.jpg" class="showPic" title="a 3 display">
                ![](images/3.jpg)
            </a>
          </li>
          <li>
            <a href="images/4.jpg" class="showPic" title="a 4 display">
                ![](images/4.jpg)
            </a>
          </li>
        </ul>
    </body>
    </html>
    

    js代码:

     function addLoadEvent(func){
            //把现在的window.onload事件处理函数的值存入变量oldload
            var oldonload = window.onload;
            if(typeof window.onload != "function"){
                //如果在这个处理函数上还没有绑定任何函数,就按平时那样把新函数添加给它。
                window.onload = func;
            } else{
                window.onload = function(){
                    //如果在这个处理函数上已经绑定了函数,就把新函数添加到现有指令的末尾。
                    oldonload();
                    func();
                }
            }
           }
           addLoadEvent(preparePlaceholder); 
           addLoadEvent(prepareLinks);
           //把占位符替换成想要的图片
           function showPic(whichpic){
             //进行对象检测,向后兼容,利用结构化程序设计中的“一个函数应该只有一个入口和一个出口”
             if(!document.getElementById){
                if(!document.getElementsByTagName){
                    return false;
                }
             }
             var source = whichpic.getAttribute("href");
             var placeholder = document.getElementById("placeholder");
             var gallery = document.getElementById("imagegallery");
             gallery.parentNode.insertBefore(placeholder,gallery);
             placeholder.setAttribute("src",source);
             if(document.getElementById("description")){//不要做太多假设,当description存在才执行下面的代码,如果不存在就忽略
             var text = whichpic.getAttribute("title");
             var description = document.getElementById("description");
             description.firstChild.nodeValue = text;
             //firstChild返回元素的第一个子元素
           }
           }
           function popUP(winURL){
            window.open(winURL,"popup","width:400,height:400");
           }
           //实现了javascript与html的分离
           function prepareLinks(){
            //尽量减少访问DOM和尽量减少标记,例如下面把document.getElementsByTagName("a")存放在变量links中,使得getElementsByTagName("a")只执行了一次,后面只需要调用links;
            if(!document.getElementsByTagName){
                return false;
            }
            var links = document.getElementsByTagName("a");
            if(links.length>0){
            for(var i=0;i<links.length;i++){
                if(links[i].getAttribute("class") == "showPic"){
                    links[i].onclick=function(){
                        //只有showPic函数执行成功才返回true
                        showPic(this);
                        console.log(showPic(this));//输出undefined
                        return false;
                        //想要阻止链接被点击后的默认行为,可以给点击事件里面的javascript代码返回一个布尔类型的值,true就代表被点击了,false就代表没有被点击
                    }
                }
            }
           }
           }
    
           function preparePlaceholder(){
             var gallery = document.getElementById("imagegallery");
             var placeholder = document.createElement("img");
             placeholder.setAttribute("id","placeholder");
             placeholder.setAttribute("alt","my image gallery");
             var description = document.createElement("p");
             description.setAttribute("id","description");
             var desctext = document.createTextNode("Choose an image");
             description.appendChild(desctext);
             insertAfter(placeholder,gallery);
             insertAfter(description,placeholder);
           }
           //在现有元素后插入一个新元素
           function insertAfter(newElement,targetElement){
            var parent = targetElement.parentNode;
            //检查targetElement是不是parent的最后一个子元素
            if(parent.lastChild == targetElement){
                //如果是就追加到parent元素上
                parent.appendChild(newElement);
            } else{
                //如果不是,把新元素插入到目标元素和目标元素的下一个兄弟元素之间。其中目标元素的下一个兄弟元素即目标元素的nextSibling属性。
                parent.insertBefore(newElement,targetElement.nextSibling);
            }
           } 
    

    第七章 动态创建标记

    本章首先回顾了创建标记的方法:
    一些传统的方法:
    1、document.write:
    违背了“行为应该与表现分离”的原则。
    2、innerHTML:
    并不是W3C DOM标准的组成部分,但是现在已经包含到HTML5规范里面中了。
    就本属性看来,标记下只有一个字符串,其无细节可言,会永久改变原来的文档。比document.write()方法值得推荐,也是HTML专属属性,不能用于其他标记语言文档。

    DOM方法:

    1、只要用正确的方法,就可以获取DOM节点树上任何一个节点的细节。
    2、改变显示内容,但不会改变物理内容。
    3、在浏览器看来,DOM节点才是文档
    4、createElement方法:
    创建元素节点,只创建会出现一个文档碎片,它是游荡在javascript世界里的一个孤儿。但是它已经有nodeType和nodeName属性
    appendChild方法
    createTextNode方法:创建文本节点
    以上三种结合使用来扩展文档树
    parentElement.insertBefore(newElement,targetElement)
    targetElement元素的parentNode属性值就是parentElement;
    属性节点和文本节点的子元素不允许是元素节点
    5、Ajax
    使用Ajax可以做到只更新页面中的一小部分,其他内容不用重新加载,Ajax的主要优势是对页面的请求以异步方式发送到服务器。
    XMLHttpRequest对象
    浏览器脚本与服务器之间的中间人的角色。javascript可以通过这个对象自己发送请求,同时自己处理响应。
    问题在于不同浏览器实现XMLHttpRequest对象的方式不太一样。

    该对象最有用的是open方法:用来指定服务器上将要访问的文件,指定请求类型:GET、POST或SEND。
    访问服务器发送回来的数据要通过两个属性完成,一个是responseText属性,这个属性用于保存文本字符串形式的数据,另一个属性是responseXML属性,用于保存Content-Type头部中指定为text/xml的数据。
    使用Ajax需要注意同源策略:使用XMLHttpRequest对象发送的请求只能访问与其所在的HTML处于同一个域中的数据,不能像其他域发送请求,有些浏览器会限制Ajax请求使用的协议。
    异步性:脚本在发送XMLHttpRequest请求之后,仍然会继续执行,不会等待响应返回。

    本书推荐的三个自己构建的函数:insertAfter函数:

    function insertAfter(newElement,targetElement){ 
    var parent=targetElement.parentNode;
     if (parent.lastChild==targetElement){ 
    parent.appendChild(newElement);
     }else{ parent.insertBefore(newElement,targetElement.nextSibling); 
      }
    }
    

    加载函数:

    addLoadEvent(func){ 
    var oldonload=window.onload; 
    if(typeof window.onload !=‘function’){ 
    window.onload = func; 
    }else{ 
    window.onload = function(){ 
    oldonload(); func(); } }
    }
    

    添加类名:

    function addClass(element,value){ 
    if (!element.className) { 
    element.className=value;
     }else{
     newClassName =element.className; newClassName+=""; newClassName+=value; element.className=newClassName; 
    }
    }
    

    相关文章

      网友评论

        本文标题:<<JavaScript DOM 编程艺术>&

        本文链接:https://www.haomeiwen.com/subject/rpmybttx.html