Dom是一种使用于多种环境和多种程序设计语言的通用性API。如果想Dom技巧运用在Web服务器以外的应用环境里,严格遵守“第1级Dom”能够让你避免与兼容性有关的任何问题
一些基础知识:
- Dom是一套对文档的内容进行抽象和概念化的方法
- Dom是一种API(应用编程接口),简单地说,API就是一组已经得到有关各方共同认可的基本约定。
- 将.js文件放在HTML文档中最好的位置是把<script></script>标签放到HTML文档的最后,</body>标签之前,这样能使浏览器更快的加载页面,同时在引入.js文件时,可以不用包含传统的type="text/javascript"属性。因为脚本默认是JavaScript,所以没必要指定这个属性。
- 程序设计语言分为解释型和编译型二大类。对于JavaScript语言,在互联网环境下,Web浏览器负责完成有挂的呢解释和执行工作。
- alert("10"+20);得到1020;alert(10+20);得到30;
- 良好的变量声明法则:在命名变量时,用下划线来分隔各个单词;在命名普通函数时,从第二个单词开始把每个单词的第一个字母写成大写形式(驼峰命名法);在命名构造函数时,首字母大写;
- 最好通过构造函数创建对象
function Box(name, age) { //构造函数模式
this.name = name;
this.age = age;
this.run = function () {
return this.name + this.age + '运行中...';
};
}
var box1 = new Box('Lee', 100); //new Box()即可
var box2 = new Box('Jack', 200);
alert(box1.run());
alert(box1 instanceof Box); //很清晰的识别他从属于Box
这个方法看似像一个函数,但又有些不太一样。比如函数名一般都小写。如果学过其他面向对象的语言就会知道,这是类的写法(此处不多分析,非强制,但这么写有助于区分构造函数和
普通函数)。这种方法是构造函数创建对象的写法,通过构造函数创建对象,必须使用new 运算符。
构造函数可以创建对象执行的过程:
1)当使用了构造函数,并且new 构造函数(),那么就后台执行了new Object();
2)将构造函数的作用域给新对象,(即new Object()创建出的对象),而函数体内的this 就
代表new Object()出来的对象。
3)执行构造函数内的代码;
4)返回新对象(后台直接返回)。
注:
1)构造函数和普通函数的唯一区别,就是他们调用的方式不同。只不过,构造函数也是函数,必须用new 运算符来调用,否则就是普通函数。
2)this就是代表当前作用域对象的引用。如果在全局范围this 就代表window 对象,如果在构造函数体内,就代表当前的构造函数所声明的对象。
这种方法解决了函数识别问题,但消耗内存问题没有解决。同时又带来了一个新的问题,全局中的this 在对象调用的时候是Box 本身,而当作普通函数调用的时候,this 又代表window。即this作用域的问题。
第三章
- 文档中的每一个元素都是一个对象,利用Dom提供的方法能得到任何一个对象
- getElementsByTagName方法返回一个对象数组,每个对象分别对应着文档里有着给定标签的一个元素。这个方法只有一个参数的函数,它的参数是标签的名字
可以通过getElementsById和getElementsByTagName结合起来运用。例如:如果想知道id属性值为purchase的元素包含着多少个子元素,必须通过一个更具体的对象去调用这个方法,如下所示---->
var shopping=document.getElementsById("purchase");
var items=shopping.getElemtentsByTagName("*");
getElementsByClassName方法的返回值是一个具有相同类名的元素的数组。使用这个方法还可以查找那些带有多个类名的元素。要制定多个类名,只要在字符串参数中用空格分隔类名即可。例如alert(document.getElementsByClassName(" important sale").length);注意:即使在元素的class属性中,类名的顺序是"sale important"而非参数中指定的"important sale",也照样会匹配该元素。不仅类名的实际顺序不重要,就算元素还带有更多的类名也没有关系。
getAttribute 查看属性
setAttribute 修改属性值
注意:通过setAttribute对文档作出修改后,再通过浏览器的view source( 查看源代码)选项去查看文档的源代码是看到的仍将是改变前的属性值,也就是说,setAttribute做出的修改不会反映在文档本身的源代码里,这种“表里不一”的现象源自Dom的工作模式:先加载文档的静态内容,在动态刷新,动态刷新不影响文档的静态内容。这正是Dom的优势所在:对页面内容进行刷新却不需要在浏览器里刷新页面
第四章
- 事件处理函数--》如果仅仅把事件处理函数放到图片列表的一个链接中,会遇到一个问题:点击这个链接时,不仅函数会被调用,链接被点击的默认行为也会被调用。这意味着用户还是会被带到链接所指的href窗口,如果只是想运行函数,但是不想转链接的话就需要组织这个默认行为被调用。
解决方法:在onclick事件处理函数所触发的JavaScript代码里增加一条return false语句,就可以防止用户被带到目标链接窗口。例:
<a href="https://www.baidu.com" onclick="showPic(this);return false;">
- childNodes属性:childNodes属性可以用来获取任何一个元素的所有子元素,它是一个包含这个元素全部子元素的数组。注意:由childNodes属性返回的数组包含所有类型的节点,而不仅仅是元素节点。事实上,文档里几乎每一样东西都是一个节点,甚至连空格和换行符都会被解释为节点,而它们也全都包含在childNodes属性所返回的数组当中!!
- nodeValue属性:它用来得到(和设置)一个节点的值
<p id="description">Choose an image.</p> <script> var description = document.getElementById("description"); alert(description.nodeValue); </script>
注意一个细节:在这里用nodeValue属性获取description对象的值时,得到的并不是包含在这个段落里的文本。示例中输出的将是“null”。因为<p>
元素本身的nodeValu是一个空值,而我们真正需要的是<p>
元素所包含的文本的值。
包含在<p>
元素里的文本是另一种节点,它是<p>
元素的第一个子节点。因此想要得到的其实是它的第一个子节点的nodeValue属性值。所以应该是
alert(description.childNodes[0].nodeValue); 或alert(description.firstChild.nodeValue);
第五章:
- 在网页加载完成时触发的事件,用window.onload=test();时出现了方法无法调用问题,把括号去掉之后问题就解决了。
下面我们来分析一下原因:
经过上网查资料和自己动手编写示例发现,window.onload=test();这种写法在程序运行到这句时,先执行test()函数,然后将test的返回值赋给window.onload,这样的赋值毫无意义
window.onload=test;这种写法是在网页加载完成后,调用test()方法。
如果有一个使用了getElementById()方法的函数,就可以在调用getElementById()方法之前先检查用户所使用的浏览器是否支持这个方法。在使用对象检测时,一定要删掉方法名后面的圆括号,如果不删掉,测试的将是方法的结果,无论方法是否存在。
function myFunction(){ if(document.getElementById){ statement using getElemtById } }
这个解决方法的唯一不足是,如此编写出来的函数会增加一对花括号。如果需要在函数里检测多个Dom方法和/或属性是否存在,这个函数中最重要的语句就会被深埋在一层又一层的花括号里,而这样的代码往往很难阅读和理解。所以把测试条件改为“如果你不理解这个方法,请离开”则更简单
if(!getElementById){ return false; } -->if(!getElemtentById) return false;
性能考虑
1.尽量少访问Dom和尽量减少标记:
尽量减少文档中的标记数量。过多不必要的元素只会增加Dom树的规模,进而增加遍历Dom树以查找特定元素的时间。
2.合并和放置脚本:
将多个.js文件合并到一个.js文件中,这样可以减少加载页面时发送的请求数量。而减少请求数量通常的都是在性能优化时首先要考虑的。
把所有<script>标签都放到文档的末尾,</body>标记之前,就可以让页面变得更快。即使这样,在加载脚本时,window对象的load时间依然可以执行对文档进行的各种操作。
3.压缩脚本:
所谓压缩脚本文件,指的是把脚本文件中不必要的字节,如空格和注释,统统删除,从而达到“压缩”文件的目的。或者使用更短的变量名。
第七章
- document.write()和innnerHTML属性都是HTML专有属性,不能用于任何和其它标记语言文档。浏览器在呈现正宗的XHTML文档(即MIME类型是application/xhtml+xml的XHTML文档)时会直接忽略掉innerHTML属性。
- 在任何时候,标准的Dom都可以用来替代innerHTML。虽说这往往需要多编写一些代码才能获得同样的效果,但Dom同时也提供了更高的精确性和更强大的功能。
- 编写insertAfter函数
function insertAfter(newElement,targetElement){ var parent=targetElement.parentNode; if(parent.lastChild==targetElement){ parent.appendChild(newElement) } else{ parent.insertBefore(newElement,targetElement.nextSibling); } }
- Ajax的主要优势是对页面的请求以异步方式发送到服务器。而服务器不会用整个页面来响应请求,它会在后台处理请求,于此同时用户还能继续浏览页面并与页面交互。你的脚本则可以按需加载和创建页面内容,而不会打断用户的浏览体验。利用Ajax,Web应用可以呈现出功能丰富、交互敏捷、类似桌面应用版的体验,就像使用谷歌地图时的感觉一样。注意:和任何新技术一样,Ajax有他自己的适用范围。它依赖JavaScript,所以可能会有浏览器不支持它,而搜索引擎的蜘蛛程序也不会抓取到有关内容
- Ajax技术的核心就是XMLHttpRequest对象。这个对象充当着浏览器中的脚本(客户端)与服务器之间的中间人的角色。以往的请求都由浏览器发出,而JavaScript通过这个对象可以自己发送请求,同时自己也处理响应。
- onreadystatechange是一个事件处理函数,它会在服务器给XMLHttpRequest对象送回响应的时候被触发执行。在这个处理函数中,可以根据服务器的具体响应做相应的处理。在此,我们给它制定一个处理函数:
request.onreadystatechange=function(){ //处理响应 if(request.readyState==4){ var para=document.createElement("p"); ... } } ;
- 服务器在向XMLHttpRequest独享发回响应时,该对象有许多属性可用,浏览器会在不同阶段更新readyState属性的值,它又五个可能的值:
0表示未初始化
1表示正在加载
2表示加载完毕
3表示正在交互
4表示完成
第九章
- 文档中的每个元素都是一个对象,每个对象又有着各种各样的属性。有一些属性告诉我们元素在节点树上的位置信息。比如说,parentNode、nextSibling、previousSibling、childNodes。firstChild和lastChild这些属性,就告诉了我们文档中各节点之间的关系信息。其他一些属性(比如nodeType和nodeName属性)包含元素本身的信息。比如说,对某个元素的nodeName属性进行的查询将返回一个诸如“p”之类的字符串。除此之外,文档的每个元素节点还都一个属性style。style属性包含着元素的样式,查询这个属性将返回一个对象而不是一个简单的字符串
- 当需要引用一个中间带减号的CSS属性时,Dom要求你用驼峰命名法。CSS属性font-family变为Dom属性fontFamily;
- style对象的属性的值必须放在引号里,单引号或双引号均可
第十章
- .top .left等需要元素position=absolute
- JavaScript函数parseInt可以把字符串里的数值信息提取出来。如果把一个以数字开头的字符串传递给这个函数,它将返回一个数值:parseInt(string)
- 如果把position属性值是absolute的元素A放在一个position属性值是relative的元素B,B就成为A的容器元素,而A将在B的显示区域里按absolute方式进行摆放。