(一)知识点
1.1属性
- element.className element对象的class字符串数组,每个字符串对应一个element的类名。 .className
- element.childNodes element的所有子节点的集合数组。
- node.nodeType 以数值的形式存储的,节点对象的类型。
节点的类型属性值共有12种,其中3中具有实用价值:
1.元素节点的nodeType属性值为1;
2.属性节点的nodeType属性值为2; //historical
3.文本节点的nodeType属性值为3.
- node.nodeValue 节点的值。可以赋值给别的变量,也可以进行设置。
- node.nodeName 以字符串的形式保存的节点的名称。
-
node.firstChild 所选节点的第一个子节点。与
node.childNodes[0]
等效。 -
node.lastChild 与
node.firstChild
相对应,所选节点的最后一个子节点。 -
window.onload 因为
document
对象是window
对象的一个属性。当window
对象触发onload
事件时,document
对象已经存在。使用示例:
window.onload = function(); //在外部JS文件中使用,可以将javascript与HTML分离。 -
node.nextSibling 返回指定节点的下一个同胞节点。(同理还有
node.previousSibling
) -
element.accesskey 这个属性可以把一个
element
与键盘上的某个按键关联在一起。比如与a
元素关联在一起,那么按下alt+key
就可以激活超级链接。 -
element.style 用于访问指定
element
的CSS样式。但是用style
属性来获取样式有很大的局限性,因为style
属性只能返回内嵌样式,外部式CSS是没法通过这个属性获取的。 - element.property = value; 设置某个量,既不算全局变量, 也不算局部变量。只与当前选择的元素有关,可以使用对象的自建属性。《DOM编程》--P193
-
window.location 用于获得当前页面的地址 (URL),并把浏览器重定向到新的页面。
window.location.href
可以获得当前网站的URL地址。还有window.location.pathname
等属性。
1.2方法
-
new 使用
new
关键字创建一个新实例,比如对象实例,数组实例。
var jhon = new Person; //Person是一个用户定义对象
var arr = new Array(); //Array是JS内建数组对象
-
Date()对象
Date()
用于存储和检索与特定日期和时间有关的信息。具有.getMonth()
、.getDay()
、.getHours()
等一系列方法。会自动使用当前日期和时间对其进行初始化。 -
三种获取元素节点的DOM方法
1..getElementById(id)
返回一个指定id的元素节点对象。
2..getElementsByTagName(tag)
返回一个对象数组,数组中的每个对象对应一个所指定标签的元素。可使tag为"*"
通配符获取选定对象内的所有元素。
3..getElementsByClassName(class)
返回一个对象数组,数组中每个对象对应一个所指定class的元素。 -
obj.getAttribute(attribute) 返回一个字符串,根据传入的
attribute
返回元素节点对象的属性。没有对应attribute
值的话返回null
。 -
obj.setAttribute(attribute,value) 选择一个元素节点对象,设置它的某个
attribute
以及相应的value
。 -
window.open(url,name,features) 使用window对象的
.open()
方法来打开一个新的浏览器窗口。示例:window.open(winURL,"popup","width=320,height=480");
这三个参数都是可选的。
■第一个参数是想在新窗口中打开的URL地址。
■第二个参数是新窗口的名字,可以在代码里通过这个名字与新窗口进行通信。
■第三个参数是新窗口的各种属性,以字符串的形式传递,不同属性用逗号分隔。这些属性包括新窗口的尺寸(高度和宽度)以及新窗口被启用或者禁用的各种浏览功能(工具条、菜单条、初始位置等等)。对于这个参数采用的原则是:浏览功能要少而精。
- typeof var/property 该运算符返回指定变量或者属性的数据类型,主要有以下几种数据类型:
■undefined - 如果变量是 Undefined 类型的
■boolean - 如果变量是 Boolean 类型的
■number - 如果变量是 Number 类型的
■string - 如果变量是 String 类型的
■object - 如果变量是一种引用类型或 Null 类型的
■function - 如果属性是function()函数类型的--见《DOM编程艺术》P83
- for(var in arr/obj) 用于遍历数组或者对象的属性(对数组或者对象的属性进行循环操作)。for(...in...)
-
setTimeout("function",interval) 经过设定的时间后再执行指定的函数。在绝大多数情况下,把这个函数调用赋值给一个变量是一个很好的选择。
var timeout = setTimeout("function",interval);
。 -
clearTimeout(timeout) 取消某个正在等待执行的函数。其参数
timeout
是一个存储了setTimeout()
函数调用的返回值的变量。 - parseInt(string) 把字符串里的数值提取出来,返回一个整型数值。
- parseFloat(string) 把字符串里的数值提取出来,返回一个浮点型数值。
-
eval(str)
eval()
函数可计算某个字符串,并执行其中的JavaScript 代码。注意,该方法的参数只能为原始字符串,不能为形参。eval() -
JSON.parse(str) 这个方法为JSON的方法,用于处理JSON文本,比用
eval()
解析JSON文本的效果好。JSON.parse()
1.3概念及基础知识
-
"javascript:"伪协议 “真”协议用来在计算机之间传输数据包,如HTTP协议(http: //),FTP协议(ftp://)等。伪协议是一种非标准化的协议。
"javascript:"
伪协议让我们通过一个链接来调用javascript函数。示例:
<a href="javascript:function();">example</a>
但是并不推荐通过"javascript:"
伪协议来调用javascript函数。 -
分离JavaScript 类似于CSS的分离,JS也可以进行分离。分离方法为:
element.event = action
,因此关键在于怎么确定对应的element
。这时就可以使用.getElementById()
、.getElementsByTagName()
等DOM方法。 - 向后兼容 要考虑对不支持JS或者不支持某些JS脚本的浏览器的兼容。
-
对象检测 检测JavaScript脚本能不能在当前浏览器中运行,这样就可以考虑到向后兼容的问题,一个简单的办法就是将某个方法打包在一个
if
语句里,如果返回值为true
,说明方法存在,返回为false
说明该方法不存在。示例:
if(method){ //注意method一定要去掉圆括号,否则会返回method的返回值,而非方法是否存在
statement
}
不过这种方法要把欲执行的语句放在if语句的花括号里,不方便阅读。因此如果改成检测“如果不理解此方法,请离开”会更简单。示例:
if(!method){
return false;
}
statement - 性能优化
1.尽量少访问DOM和尽量减少标记
不管什么时候,只要查询DOM中的某些元素,浏览器都会搜索整个DOM树,从中查找可能匹配的元素,所以要尽量少地访问DOM,对于相同的访问,争取次数越少越好。另外要尽量减少标记的数量,过多不必要的元素只会增加DOM树的规格。
2.合并和放置脚本
首先,包含脚本的最佳方式是外部式脚本, 便于维护、复用等。当有多个外部脚本时,对于可以合并到一个文件中去的脚本,应该合并到一个脚本文件中去,这样减少加载页面时发送的请求,减少请求数量通常是性能优化首要考虑的。另外脚本一般放在</body>
标签前面,放在<head>
里会造成页面的文档没加载完,无法在脚本里调用一些内容。
3.压缩脚本
所谓“压缩脚本”,是把脚本中不必要的字节,例如空格和注释,统统删除,从而达到“压缩”文件的目的。
- 如果想用JavaScript代码为页面添加某个行为,不应该让JavaScript代码依赖于页面的结构,这样才能在维护更新时不出错。--《DOM编程艺术》P79
- 在指定函数引用时,比如
var test = myFunction
时,注意函数myFunction
不要加括号,加括号表示立即调用,而我们只是想把函数自身的引用(而不是结果)赋值给test
。 - 在CSS中用连字符表示的属性,在DOM中一律采用驼峰命名法来表示它们。《DOM编程》P153
(二)函数库
-
.getElementsByClassName() 对于没有
.getElementsByClassName()
的老浏览器,自建方法:
function getElementsByClassName(node,classname){
if(node.getElementsByClassName){
//存在的话使用现有方法
return node.getElementsByClassName(classname);
}
else{
var results = new Array();
var elems = node.getElementsByTagName("*");
for(var i = 0; i < elems.length; i++){
if(elems[i].className.indexOf(classname) != -1){
results[results.length] = elems[i];
}
}
return results;
}
} //这个例子不适用于多个类名,《DOM编程艺术第2版》-P42,不清楚为什么
第一个node
参数为选定开始查找的节点,第二个classname
参数为需要查找的class名。 -
addLoadEvent() 在页面加载完毕时欲添加执行指定函数的话,可以使用这个函数。它只有一个参数,就是欲执行的函数的名字。示例:
function addLoadEvent(func){
var oldonload = window.onload;
if(typeof window.onload != 'function'){
window.onload = func; //此处func后面无圆括号
}
else{
window.onload = function(){
oldonload();
func(); //此处func后面有圆括号,不懂原因
}
}
} -
insertAfter(newNode,targetNode) 在目标元素节点后面添加想加的节点。虽然DOM自带
.insertBefore()
,但没有在节点后面添加节点的方法,因此自建.insertAfter()
。
function insertAfter(newNode,targetNode){
var parent = targetNode.parentNode;
if(parent.lastChild == targetNode){
parent.appendChild(newNode);
}
else{
parent.insertBefore(newNode,targetNode.nextSibling);
}
} -
getHTTPObject() 用于创建一个
XMLHttpRequest
对象。
function getHTTPObject(){
if(typeof XMLHttPRequest == "undefined"){
XMLHttpRequest = function(){
try{return new ActiveXObject("Msxml2.XMLHTTP.6.0");}
catch(e){}
try{return new ActiveXObject("Msxml2.XMLHTTP.3.0");}
catch(e){}
try{return new ActiveXObject("Msxml2.XMLHTTP");}
catch(e){}
return false;
}
}
return new XMLHttpRequest;
} -
getNewContent() 利用创建的
XMLHttpRequest
对象的open()
方法从服务器上获取要访问的文件。可以指定的请求类型有:GET
,POST
,SEND
。这个open()
方法的第三个参数用于指定请求是否以异步方式发送和处理。
function getNewContent(){
var request = new getHTTPObject();
if(request){
request.open("GET","example.txt",true); //HTML文件同目录下有一个example.txt。第三个参数与异步有关
request.onreadystatechange = function(){
if(request.readyState == 4){
var para = document.creatElement("p");
var txt = document.creatTextNode(request.requestText);
para.appendChild(txt);
document.getElementById('new').appendChild(para); //放在new节点后面
}
};
}
else{
alert('Sorry, your browser doesn`t support XMLHttpRequest');
}
}
代码中的onreadystatechange
是一个事件处理函数,它会在服务器给XMLHttpRequest
对象送回响应的时候被触发执行。在这个处理函数中,可以根据服务器的具体响应做出对应的处理。在此,我们给它指定了一个响应处理函数:
request.onreadystatechange = function(){
//处理响应
};
readyState属性有5个值,只要readyState属性的值变成了4,就可以访问服务器发送回来的数据了。
■0表示未初始化
■1表示正在加载
■2表示加载完毕
■3表示正在交互
■4表示完成
访问服务器发送回来的数据要通过两个属性完成。一个是responseText
,这个属性用于保存文本字符串形式的数据。另一个属性是responseXML
,用于保存Content-Type
头部中指定为"text/xml"
的数据,其实是一个DocumentFragment
对象。(文档碎片,就像新建立的Element
一样,悬空着)
-
getNextElement(node) 返回指定节点之后的第一个元素节点。(包括
node
本身)
function getNextElement(node){
if(node.nodeType == 1){
return node;
}
if(node.nextSibling){
return getNextElement(node.nextSibling);
}
return null;
} -
addClass(element,value) 指定
element
添加class
。
function addClass(element,value){
if(!element.className){
element.className = value;
}
else{
var newClass = element.className;
newClass += " ";
newClass += value;
element.className = newClass;
}
} -
removeClass(element,value) 删除指定元素的某个类
function removeClass(element,value){
var allClass=element.className;
allClass=allClass.split(' ');
for(var i=0;i<allClass.length;i++){
if(allClass[i]==value){
allClass.splice(i,1);
}
}
allClass=allClass.join(' ');
element.className=allClass;
} -
replaceClass(element,value,targetValue) 替换指定元素的某个类为新的类
function replaceClass(element,value,targetValue){ //targetValue will be replaced
var allClass=element.className;
allClass=allClass.split(' ');
for(var i=0;i<allClass.length;i++){
if(allClass[i]==targetValue){
allClass.splice(i,1,value);
}
}
allClass=allClass.join(' ');
element.className=allClass;
} -
moveElement(elementID,final_x,final_y,interval) 指定元素舒适化(先快后慢)移动到指定位置。(只对层叠布局的元素有效)
function moveElement(elementID,final_x,final_y,interval){ //elementID是字符串变量
if(!document.getElementById) return false;
if(!document.getElementById(ElementID)) return false;
var elem = document.getElementById(elementID);
if(elem.movement){
clearTimeout(elem.movement);
}
if(!elem.style.left){
elem.style.left = "0";
}
if(!elem.style.top){
elem.style.top = "0";
}
var xpos = parseInt(elem.style.left); //当水平方向属性设为right时用right
var ypos = parseInt(elem.style.top); //当竖直方向属性设为bottom时用bottom
var step = 0;
if(xpos == final_x && ypos == final_y){
return true;
}
if(xpos < final_x){
step = Math.ceil((final_x - xpos) / 10);
xpos += step;
}
else if(xpos > final_x){
step = Math.ceil((xpos - final_x) / 10);
xpos -= step;
}
if(ypos < final_y){
step = Math.ceil((final_y - ypos) / 10);
ypos += step;
}
else if(ypos > final_y){
step = Math.ceil((ypos - final_y) / 10);
ypos -= step;
}
elem.style.left = xpos + "px";
elem.style.top = ypos + "px";
var repeat = "'moveElement(" + elementID + "," + final_x + "," + final_y + "," + interval + ")'"; //作为之后setTimeout的第一参数传递进去。
elem.movement = setTimeout(repeat,interval); //定义movement为对象属性,既可在函数外部终止,又只属于要移动的元素
}