<<JavaScript DOM 编程艺术>>学习笔记

第一章 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; 
}
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341

推荐阅读更多精彩内容