常见的DOM操作
Node类型
- 在DOM1级里定义了一组节点类型,每个节点都有一个nodeType属性,用于表明节点在DOM中扮演的角色,同时每一个类型对应着一个值,文档中的每一个节点一定属于其一:
NodeType 节点值 | Named Constant 节点类型 |
---|---|
1 | Node.ELEMENT_NODE(1) |
2 | Node.ATTRIBUTE_NODE(2) |
3 | Node.TEXT_NODE(3) |
4 | Node.CDATA_SECTION_NODE(4) |
5 | Node.ENTITY_REFERENCE_NODE(5) |
6 | Node.ENTITY_NODE(6) |
7 | Node.PROCESSING_INSTRUCTION_NODE(7) |
8 | Node.COMMENT_NODE(8) |
9 | Node.DOCUMENT_NODE(9) |
10 | Node.DOCUMENT_TYPE_NODE(10) |
11 | Node.DOCUMENT_FRAGMENT_NODE(11) |
12 | Node.NOTATION_NODE(12) |
+ 如果你获取的那个节点为someNode
if(someNode.nodeType==Node.ELEMENT_NODE){
//Node.ELEMENT_NODE这个在IE中是不认的!我们需要做一些改变,因为它本身是有值的,我们可以利用这个值
alert("Node is an element!");
}
if(someNode.nodeType==1){ //这个就适用于所有的浏览器了
alert("Node is an element!");
}
Node Types
- 文档、元素、属性以及 HTML 或 XML 文档的其他方面拥有不同的节点类型。存在 12 种不同的节点类型,其中可能会有不同节点类型的子节点:
序号 | 节点类型 | 描述 | 子节点 |
---|---|---|---|
1 | Element | 代表元素 | Element, Text, Comment, ProcessingInstruction, CDATASection, EntityReference |
2 | Attr | 代表属性 | Text, EntityReference |
3 | Text | 代表元素或属性中的文本内容。 | None |
4 | CDATASection | 代表文档中的 CDATA 部分(不会由解析器解析的文本)。 | None |
5 | EntityReference | 代表实体引用。 | Element, ProcessingInstruction, Comment, Text, CDATASection, EntityReference |
6 | Entity | 代表实体。 | Element, ProcessingInstruction, Comment, Text, CDATASection, EntityReference |
7 | ProcessingInstruction | 代表处理指令。 | None |
8 | Comment | 代表注释。 | None |
9 | Document | 代表整个文档(DOM 树的根节点)。 | Element, ProcessingInstruction, Comment, DocumentType |
10 | DocumentType | 向为文档定义的实体提供接口 | None |
11 | DocumentFragment | 代表轻量级的 Document 对象,能够容纳文档的某个部分 | Element, ProcessingInstruction, Comment, Text, CDATASection, EntityReference |
12 | Notation | 代表 DTD 中声明的符号。 | None |
节点类型的返回值
- 对于每种节点类型,nodeName 和 nodeValue 属性的返回值:
序号 | 节点类型 | nodeName 返回 | nodeValue 返回 |
---|---|---|---|
1 | Element | 元素名 | null |
2 | Attr | 属性名称 | 属性值 |
3 | Text | text | 节点的内容 |
4 | CDATASection | cdata-section | 节点的内容 |
5 | EntityReference | 实体引用名称 | null |
6 | Entity | 实体名称 | null |
7 | ProcessingInstruction | target | 节点的内容 |
8 | Comment | comment | 注释文本 |
9 | Document | document | null |
10 | DocumentType | 文档类型名称 | null |
11 | DocumentFragment | document 片段 | null |
12 | Notation | 符号名称 | null |
- 当然这些并不需要你记住它,但是需要你知道它,用到它的时候会查,或者看到代码要知道它表达的是什么意思!
有趣的数组基本操作
- js里的数组是一个大大区别于另外的强类型语言的“另类”!因为它可以同时装任何类型的数据!如:
var myArray=[1,"1",{name:Wytheo},[1]];
所以,js里的数据结构也是最复杂,最灵活的数据结构!
数组声明
- 普通声明
直接var一个数组对象,然后赋一个空数组给它[]:
var myArray=[];
myArray[0]=1;
myArray[1]=2;
- 对象声明
用Array对象创建数组,参数可以是数字(代表长度length)、字符串(代表数字其中的一项):
var myArray=new Array(3);
myArray.length; //3
var myColor=new Array("blue","red"); //["blue","red"]
创建数组你需要注意的地方
- 如果是一个有空白单位的稀疏数组,没有定义的单位会忽略,但是任然会占据一个位置,引擎会自动给它赋值一个undefined:
var a=[];
a[0]=1;
a[2]=[3];//这里并没有定义a[1]的值
a[1]; //undefined
a.length;//3
- 数组可是一个对象啊!
数组继承与对象,自然包含对象的一些特性!
var a=[];
a[0]=1;
a["footbar"]=2;
a.length; //1
a["footbar"];//2
a.footbar;//2
但是,要注意的是,如果里面不是字符串而是数字的话:
var a=[];
a[0]=1;
a["13"]=42;
a.length;//14
- 如何检测数组
var a=[];
console.log(typeof a); //object
console.log(typeof Array()); //object
- 有人说用instanceof可以啊!但是这个并不安全,为什么呢?看下面一行代码:
var isArray=value instanceof Array;
如果以上代码返回true则证明value是一个数组对吧!事实则没有这么简单!
返回true必须包含两个条件,第一,value是一个数组,第二,还必须与Array对象构造函数在同一个全局作用域中(提醒,Array的构造函数作用域在window下),如果value是在另一个frame中定义的数组,那么就会返回false!虽然instanceof在大部分条件是即使你没有注意,它是可以使用的,但是,我们有更好的解决办法,为什么不用呢?如下:
console.log(Object.prototype.toString.call(value)); //"[object Array]"
//为此,我们可以这样写:
function isArray(value){
return Object.prototype.toString.call(value)=="[object Array]";
}
如此这般,边能解决安全的数据类型检测,同样,我们也可以通过这种办法检测某个值是不是原生函数或者正则表达式。
数组的常用函数
方法 | 描述 |
---|---|
concat() | 连接两个或更多的数组,并返回结果。 |
join() | 把数组的所有元素放入一个字符串。元素通过指定的分隔符进行分隔。 |
pop() | 删除并返回数组的最后一个元素 |
push() | 向数组的末尾添加一个或更多元素,并返回新的长度。 |
reverse() | 颠倒数组中元素的顺序。 |
shift() | 删除并返回数组的第一个元素 |
slice() | 从某个已有的数组返回选定的元素 |
sort() | 对数组的元素进行排序 |
splice() | 删除元素,并向数组添加新元素。 |
toString() | 把数组转换为字符串,并返回结果。 |
toLocaleString() | 把数组转换为本地数组,并返回结果。 |
unshift() | 向数组的开头添加一个或更多元素,并返回新的长度。 |
valueOf() | 返回数组对象的原始值 |
+ 栈组合
栈方法是数组实现栈的行为特性的方法,它有两个函数:pop(),push()
,push()方法可以接收任意数量的参数,把它们逐个添加到数组的末尾,并返回修改后数组的长度。pop()方法则从数组末尾删除最后一项,减少length的值,然后返回移除的项:
var colors=new Array();
var count=colors.push("red","green");
console.log(count);//2
var item=colors.pop();
console.log(item); //"green"
console.log(colors.length); //1
堆栈是数据结构里非常重要的知识,不管是计算机系统的应用,还是数据逻辑里,都非常实用,非常经典的一个例子,计算器!用栈实现将一个表达式(3+(2-5)*8)这种!简单却不简单!
- 队列方法
和栈里的push()方法恰巧相反,数组实现队列的特性是依靠shift()方法,它将数组的第一个项移除并返回,同时数组长度减一,结合push()方法,则能实现队列的特性了!
var colors=new Array();
var count=colors.push("red","green");
console.log(count);//2
var item=colors.shift();
console.log(item); //"red"
console.log(colors.length); //1
- 自带的排序方法
sort()和reverse(),sort()排序是个大坑,它比较并不是按照正常的大小,因为它把所有的都当做了字符串进行比较,就和文件系统的文件夹排序一样!reverse()只是单纯的把数组前后颠倒!
var a=[0,1,10,5,7,9,15];
console.log(a); //(7)[0, 1, 10, 5, 7, 9, 15]
console.log(a.reverse()); //(7)[15, 9, 7, 5, 10, 1, 0]
console.log(a.sort()); //(7)[0, 1, 10, 15, 5, 7, 9]
console.log(a.reverse()); //(7)[9, 7, 5, 15, 10, 1, 0]
- 解决sort()排序方式问题:
var a=[0,1,10,5,7,9,15];
console.log(a); //(7)[0, 1, 10, 5, 7, 9, 15]
a.sort(mySort);
console.log(a); //(7)[0, 1, 5, 7, 9, 10, 15]
function mySort(val1, val2) {
if (val1 > val2) {
return 1;
} else if (val1 < val2) {
return -1;
} else {
return 0;
}
}
sort()可选参数为一个函数,返回值正数代表第一个参数应该在第二个之后,相反,负数就是之前,而0表示相等,不交换。
- slice()函数
slice() 方法可从已有的数组中返回选定的元素。返回一个新的数组,包含从 start 到 end (不包括该元素)的 arrayObject 中的元素。
arrayObject.slice(start,end)
start 必需。规定从何处开始选取。如果是负数,那么它规定从数组尾部开始算起的位置。也就是说,-1 指最后一个元素,-2 指倒数第二个元素,以此类推。
end 可选。规定从何处结束选取。该参数是数组片断结束处的数组下标。如果没有指定该参数,那么切分的数组包含从 start 到数组结束的所有元素。如果这个参数是负数,那么它规定的是从数组尾部开始算起的元素。
var arr = new Array(3);
arr[0] = "George";
arr[1] = "John";
arr[2] = "Thomas";
document.write(arr + "<br />");
document.write(arr.slice(1) + "<br />"); //从下标为1的位置开始截取,至最后
document.write(arr);
/*
George,John,Thomas
John,Thomas
George,John,Thomas
*/
- splice()函数
splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目。
arrayObject.splice(index,howmany,item1,.....,itemX)
参数 | 描述 |
---|---|
index | 必需。整数,规定添加/删除项目的位置,使用负数可从数组结尾处规定位置。 |
howmany | 必需。要删除的项目数量。如果设置为 0,则不会删除项目。 |
item1, …, itemX | 可选。向数组添加的新项目。 |
splice() 方法可删除从 index 处开始的零个或多个元素,并且用参数列表中声明的一个或多个值来替换那些被删除的元素。如果从 arrayObject中删除了元素,则返回的是含有被删除的元素的数组。
var arr = new Array(6);
arr[0] = "George";
arr[1] = "John";
arr[2] = "Thomas";
arr[3] = "James";
arr[4] = "Adrew";
arr[5] = "Martin";
document.write(arr + "<br />");
arr.splice(2, 0, "William");
document.write(arr + "<br />");
/*
George,John,Thomas,James,Adrew,Martin
George,John,William,Thomas,James,Adrew,Martin
*/
var arr = new Array(6);
arr[0] = "George";
arr[1] = "John";
arr[2] = "Thomas";
arr[3] = "James";
arr[4] = "Adrew";
arr[5] = "Martin";
document.write(arr + "<br />");
arr.splice(2, 1, "William"); //删除当前下标后起1位,即Thomas
document.write(arr + "<br />");
/*
George,John,Thomas,James,Adrew,Martin
George,John,William,James,Adrew,Martin
*/
- contact()函数
concat() 方法用于连接两个或多个数组。
该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本。
arrayObject.concat(arrayX,arrayX,......,arrayX)
arrayX 必需。该参数可以是具体的值,也可以是数组对象。可以是任意多个。
var arr = new Array(3);
arr[0] = "George";
arr[1] = "John";
arr[2] = "Thomas";
var arr2 = new Array(3);
arr2[0] = "James";
arr2[1] = "Adrew";
arr2[2] = "Martin";
var arr3 = new Array(2);
arr3[0] = "William";
arr3[1] = "Franklin";
document.write(arr.concat(arr2, arr3));
document.write("<br/>" + arr); //arr并没有被改变
/*
George,John,Thomas,James,Adrew,Martin,William,Franklin
George,John,Thomas
*/
- join()函数
join() 方法用于把数组中的所有元素放入一个字符串。
元素是通过指定的分隔符进行分隔的。
arrayObject.join(separator)
separator 可选。指定要使用的分隔符。如果省略该参数,则使用逗号作为分隔符。
返回一个字符串。该字符串是通过把 arrayObject 的每个元素转换为字符串,然后把这些字符串连接起来,在两个元素之间插入 separator 字符串而生成的。
var arr = new Array(3);
arr[0] = "George";
arr[1] = "John";
arr[2] = "Thomas";
console.log(arr.join()); //George,John,Thomas
console.log(arr.join("||")); //George||John||Thomas
- 数组的迭代方法*
every():对数组中的每一项运行给定函数,如果该函数对每一项都返回true,则返回true。
var numbers = [1, 2, 3, 4, 5, 4, 3, 2, 1];
var everyResult = numbers.every(function (item, index, array) {
return (item > 2);
});
alert(everyResult); //false
var someResult = numbers.some(function (item, index, array) {
return (item > 2);
});
filter():对数组中的每一项运行给定函数,返回该函数会返回true 的项组成的数组。
number = [1, 2,1, 3, 5, 3, 4, 9, 6, 9];
var result = number.filter(function (item, index, array) {
return (item > 5);
});
alert(result); //[9,6,9];
forEach():对数组中的每一项运行给定函数。这个方法没有返回值。就是个遍历。
map():对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组。
var numbers = [1, 2, 3, 4, 5, 6, 7];
var mapresult = numbers.map(function (item, index, array) {
return item * 2;
});
alert(mapresult);//[2,4,6,8,10,12,14];
some():对数组中的每一项运行给定函数,如果该函数对任一项返回true,则返回true.
every主要是用于判断一个素组中的值是否符合某个标准。必须是每个值都符合才会返回true。否则返回false.
而some()函数只需要有一个值返回的是true就会返回true.
- 数组的归并方法*
reduce(),reduceRight()。
迭代i数组中的所有值,返回一个按条件计算的最终值。
reduce是从数组的逐个遍历
到最后。而reduceRight()则从数组的最后一项开始,向前遍历到第一项。
var values = [1,2,3,4,5];
var sum = values.reduce(function(prev, cur, index, array){
return prev + cur;
});
alert(sum); //15