javascript脚本化文档
1、getElememtById
/** * 获取指定id的的元素数组 */ function getElements(/*ids...*/) { var elements = {}; for(var i = 0; i < arguments.length; i++) { var id = arguments[i]; var elt = document.getElementById(id); if (elt == null) throw new Error("No element with id: " + id); elements[id] = elt; } return elements; }
在低于IE8以下版本的浏览器,getElementById()对匹配元素的id不区分大小写,而且也返回匹配name属性的元素!
2、getElememtsByName
在IE8下,getElementsByName()会返回id属性匹配的元素!
包含name属性的元素只有少量元素如:form,表单元素,iframe,和 img元素!
getElememtsByName //返回的是nodeList对象
3、getElememtsByTagName
选择指定标签的元素名称的元素!
var span = document.getElementsByTagName('span');
类似于getElememtsByName,getElememtsByTagName返回也是nodeList元素对象。
html标签是不区分大小写的,所以getElememtsByTagName也是不区分大小写的查找元素的!
查找元素的后代元素
var p = document.getElementsByTagName('p');//查找p元素
var p_span = p.getElementsByTagName('span');//查找p元素下span元素
获取指定name属性的表单元素
document.testFrom;//获取表单名称为testFrom的表单
document.forms.testFrom;//获取表单名称为testFrom的表单或者id为testForm的元素
getElementsByTagName和getElememtsByName,返回的都是nodeList对象
而对于document.images和document.forms,他们返回的是HTMLCollection对象,这些对象只有只读属性,他们有length属性,也可以像真正的数组进行索引
但是只是读而不是写!
如下代码
for(var i=0;i<document.images.length;i++){//循环所有img对象 document.images[i].style.display = 'none';//隐藏他们 }
4、通过css类来调用元素
document.getElememtsByClassName();//基于class的名字来获取元素
例子:
var waring = document.getElementsByClassName('waring');//获取class为waring的元素
var p = document.getElememtById('p');
var p_ch = p.getElememtsByClassName('fat error');//在ID为p的元素下面找到类名为fat和error,参数的里面类名顺序不区分,通过空格分割。
注明:
除了IE8以下的版本的浏览器,其他浏览器都实现了getElememtsByClassName方法!
5、节点树node对象
parentNode 指定元素的父元素节点,没有父节点返回null
childNodes 只读的类数组对象,它是该节点的子节点的实时表示!
firstChild,lastChild 该节点的子节点的第一个子节点和最后一个子节点!
nextSibling,previoursSlibing 该节点的子节点的下一个和上一个兄弟节点!
nodeType 节点的类型(9)document节点(1)element节点,(3)text节点,(8)commount节点。。
nodeValue 节点的值 text节点和comment节点的内容
nodeName 节点的名称 大写
例子:
document.childNodes[0].childNodes[1];//document节点的子节点的第一个节点下的第二个子节点
document.firstChild.firstChild.nextSibling;//document节点的第一个子节点的第一个子节点的下一个兄弟节点!
6、element
element节点的children属性类似childNodes对象,不同的是children属性只包含element元素!
例子:
可移植的文档遍历函数
/* 返回元素e第n层父元素 如果不存在此类祖先或者祖先元素不是element类型,返回null 如果n为0 返回自己 如果n为1或者省略返回父元素 */ function parent(e,n){ if(n == undefined) n = 1; while(n-- && e) e = e.parentNode; if(!e || e.nodeType != 1) return null; return e; } /** * Return the nth sibling element of Element e. * If n is postive return the nth next sibling element. * If n is negative, return the -nth previous sibling element. * If n is zero, return e itself. */ function sibling(e,n) { while(e && n !== 0) { // If e is not defined we just return it if (n > 0) { // Find next element sibling if (e.nextElementSibling) e = e.nextElementSibling; else { for(e=e.nextSibling; e && e.nodeType !== 1; e=e.nextSibling) /* empty loop */ ; } n--; } else { // Find the previous element sibling if (e.previousElementSibing) e = e.previousElementSibling; else { for(e=e.previousSibling; e&&e.nodeType!==1; e=e.previousSibling) /* empty loop */ ; } n++; } } return e; } /** * Return the nth element child of e, or null if it doesn't have one. * Negative values of n count from the end. 0 means the first child, but * -1 means the last child, -2 means the second to last, and so on. */ function child(e, n) { if (e.children) { // If children array exists if (n < 0) n += e.children.length; // Convert negative n to array index if (n < 0) return null; // If still negative, no child return e.children[n]; // Return specified child } // If e does not have a children array, find the first child and count // forward or find the last child and count backwards from there. if (n >= 0) { // n is non-negative: count forward from the first child // Find the first child element of e if (e.firstElementChild) e = e.firstElementChild; else { for(e = e.firstChild; e && e.nodeType !== 1; e = e.nextSibling) /* empty */; } return sibling(e, n); // Return the nth sibling of the first child } else { // n is negative, so count backwards from the end if (e.lastElementChild) e = e.lastElementChild; else { for(e = e.lastChild; e && e.nodeType !== 1; e=e.previousSibling) /* empty */; } return sibling(e, n+1); // +1 to convert child -1 to sib 0 of last } }
7、设置和获取非标准的HTML属性
getAttribute()和setAttribute()方法!查询和设置非标准的html属性。
element类型还设置了另外两个方法,hasAttribute()和removeAttribute(),用来检测属性是否存在,和删除属性。
8、获取元素的文本内容
// Return the plain-text content of element e, recursing into child elements. // This method works like the textContent property function textContent(e) { var child, type, s = ""; // s holds the text of all children for(child = e.firstChild; child != null; child = child.nextSibling) { type = child.nodeType; if (type === 3 || type === 4) // Text and CDATASection nodes s += child.nodeValue; else if (type === 1) // Recurse for Element nodes s += textContent(child); } return s; }
9、创建节点
创建新的element节点可以使用createElement()方法。给元素传递标签名字,对html文档来说该名字不区分大小写,对XML文档则区分大小写!
text节点的创建的方式类似
如:var newnode = document.createTextNode('dsjfhdsf sfdfhsdfsdjfh sdjhf');
9.1复制节点创建节点!
每一个节点都有cloneNode方法来返回一个该节点的一个全新的副本。给方法传递参数true也能够递归的复制所有后代的子节点,或传递一个一个false
只是进行一个浅复制。
9.2 插入节点
一旦有了一个节点就可以用node方法appendChild或者insertBefore()将他插入到文档中。appendChild()是在需要插入Element节点上调用的
,它插入到指定节点成为那个节点的最后一个子节点!
insertBefore()和appendChild()类似,它传入两个参数,第一个参数是待插入的节点,第二个参数是已经存在的节点。新节点将插入到该节点的前面。
该方法应该是在新节点的父节点上调用的!第二个参数必须是该父节点的子节点,如果第二个参数为null,则它和appendChild类似!
/*将节点插入到父节点指定的位置中*/ function insertAt(parent,child,n){ if(n<0 || n > parent.childNodes.length) throw new Error('invalid index'); else if(n == parent.childNodes.length) parent.appendChild(child); else{ parent.insertBefore(child,parent.childNodes[n]); } }
9.3 表格行的排序
// 根据指定表格每行指定的第n个单元格的内容对表格内容进行排序 // 如果存在比较函数则使用它如果没有则按照字母表进行排序 function sortrows(table, n, comparator) { var tbody = table.tBodies[0]; // 第一个<tbody> 可能是隐式创建的 var rows = tbody.getElementsByTagName("tr"); // 查找tbody下所有行 rows = Array.prototype.slice.call(rows,0); // 真实数组中的快照 // 基于第n个单元格的内容进行排序 //sort() 方法用于对数组的元素进行排序。 rows.sort(function(row1,row2) { var cell1 = row1.getElementsByTagName("td")[n]; var cell2 = row2.getElementsByTagName("td")[n]; var val1 = cell1.textContent || cell1.innerText; var val2 = cell2.textContent || cell2.innerText; if (comparator) return comparator(val1, val2); if (val1 < val2) return -1; else if (val1 > val2) return 1; else return 0; }); // 添加排序好的行添加到tobody的最后 for(var i = 0; i < rows.length; i++) tbody.appendChild(rows[i]); } // 查找表格中的th元素(假设只有一行) // 并且使他们可以点击 //以便点击该标题进行排序 function makeSortable(table) { var headers = table.getElementsByTagName("th"); for(var i = 0; i < headers.length; i++) { (function(n) { headers[i].onclick = function() { sortrows(table, n); }; }(i)); } }
9.4 删除和替代节点
removeChild() 是从文档树种删除一个节点。此方法只能在待删除的节点的父节点上调用;
例如:节点n的删除是这样
n.parentNode.removeChild(n);
replaceChild() 删除一个子节点并用新的子节点来替代,同样是在父节点上调用此方法!
n.parentNode.replaceChild(document.createTextNode('fgdfg'),n);
replaceChild()函数的另一个用法
//用一个<b>元素替换元素n,并让n成为b的子元素 function embe(n){ if(typeOf n == 'string'){//如果n为字符串则当做传入元素的ID使用 n = document.getElememtById(n); } var b = document.createElement('b'); n.parentNode.replaceChild(b,n); b.appendChild(n); }
9.5 使用innerHTML实现outerHTML
// Implement the outerHTML property for browsers that don't support it. // Assumes that the browser does support innerHTML, has an extensible // Element.prototype, and allows getters and setters to be defined. (function() { // If we already have outerHTML return without doing anything if (document.createElement("div").outerHTML) return; // Return the outer HTML of the element referred to by this function outerHTMLGetter() { var container = document.createElement("div"); // Dummy element container.appendChild(this.cloneNode(true)); // Copy this to dummy return container.innerHTML; // Return dummy content } // Set the outer HTML of the this element to the specified value function outerHTMLSetter(value) { // Create a dummy element and set its content to the specified value var container = document.createElement("div"); container.innerHTML = value; // Move each of the nodes from the dummy into the document while(container.firstChild) // Loop until container has no more kids this.parentNode.insertBefore(container.firstChild, this); // And remove the node that has been replaced this.parentNode.removeChild(this); } // Now use these two functions as getters and setters for the // outerHTML property of all Element objects. Use ES5 Object.defineProperty // if it exists and otherwise fall back on __defineGetter__ and Setter__. if (Object.defineProperty) { Object.defineProperty(Element.prototype, "outerHTML", { get: outerHTMLGetter, set: outerHTMLSetter, enumerable: false, configurable: true }); } else { Element.prototype.__defineGetter__("outerHTML", outerHTMLGetter); Element.prototype.__defineSetter__("outerHTML", outerHTMLSetter); } }());
10、浏览器窗口的滚动条的位置
除了IE8及更早的版本以外,window对象的pageXOffset 和 pageYOffset属性在所有的浏览器中指代浏览器窗口的滚动条的位置。
IE和所有现代的浏览器也可以通过scrollLeft和scrollTop属性来获得浏览器的滚动条的位置。正常情况下一般是通过
document.documentElement来获取这些值,但是在怪异模式下必须在document.body下去获取这些值
//查询窗口滚动条的位置 function getScrollOffset(w){ w = w || window; //除了IE8及更早的版本以外 if(w.pageXOffset != null){ return {x:w.pageXOffset,y:w.pageYOffset}; } //对标准模式下IE(或任何浏览器) var d = w.document; if(document.compatMode == 'CSS1Compat'){ return {x:d.documentElement.scrollLeft,y:d.documentElement.scrollTop}; } //如果是怪异模式下 return {x:document.body.scrollLeft,y:document.body.scrollTop}; }
11、浏览器视口的大小
利用滚动偏移量来查询视口的大小在IE8及更早的版本无法获取,而且在IE下还有判定当前文档是在怪异模式还是普通模式!
//获取浏览器视口的大小 function getViewPortSize(w){ w = w || window; if(w.innerWidth != null ){ return {w:w.innerWidth,h:w.innerHeight}; } //对标准模式下IE(或任何浏览器) var d = w.document; if(document.compatMode == 'CSS1Compat'){ return {x:d.documentElement.clientWidth,y:d.documentElement.clientHeight}; } //如果是怪异模式下 return {x:document.clientWidth.scrollLeft,y:document.body.clientHeight}; }
12、查询元素的几何尺寸
查询元素几何尺寸和位置最简单的方法是就是调用getBoundingClientRect()方法,它不要参数返回一个有left,right,top和bottom属性的对象。
这个方法返回的是元素在视口坐标中的位置。
var box = e.getBoundingClientRect();//获取元素在视口中的位置 var offset = getScrollOffset();//获取滚动条滚动的位置 var x = box.left + offset.x;//计算出元素在文档中的x的位置 var y = box.top + offset.y;//计算出元素在文档中的y的位置 //很多浏览中getBoundingClientRect();返回的方法还包含width和height属性,但在原始的IE中没有实现 //下面计算元素的宽度和高度 var box = e.getBoundingClientRect(); var w = box.width || (box.right-box.left); var h = box.height || (box.top - box.bottom); //getBoundingClientRect();返回的数据包含元素的内边距和边框,但不包含外边距。 //getBoundingClientRect();它指定返回的是块级元素的数据,如果要返回的是内联元素的数据时候使用getClientRect(); //注意:getBoundingClientRect()和getClientRect()返回的数据不是实时的,它只是最初的一个快照而已。
13、滚动
window.scrollTo();接受一个点的x和y坐标并作为滚动条的偏移量来设置滚动条。
window的scrollBy()和scroll()和scrollTo类似,但它的参数是相对的,是在当前滚动条的位置上进行增加。
例如:
javascript:void setInterval(function(){window.scrollBy(0,10)},500);
让浏览器滚动到指定元素的位置
box.scrollIntoView();//此方法和锚链接类似
默认情况下它与元素的上边距靠近,如果只传递false做为参数的时候,它将试图与元素的下边缘靠近!
getBoundingClientRect在所有当代的浏览器中都有定义,但在更老的浏览器中不能使用它!
这里介绍如下方法获取
任何html元素都有offsetWidth和offsetHeight属性,此方法返回元素的宽高,包括边框和内边距不包含外边距
另外offsetLeft,offsetTop返回的是元素x,y坐标,对于很多元素该值就是元素在文档中的位置。但对于已经定位的元素的后代元素和
其他的一些元素,如(表格单元),这些元素返回的都是相对于父元素的位置!
//获取元素的位置(计算元素的文档位置) function getElementPos(e){ var x = 0; var y = 0; while(e != null){ x += e.offsetLeft; y += e.offsetTop; e = e.offsetParent; } return {x:x,y:y}; } //获取元素的视口的位置 function getElementViewPos(elt){ var x = 0; var y = 0; for(var e = elt;e!=null;e = offsetParent){ x += e.offsetLeft; y += e.offsetTop; } for(var e=elt.parentNode;e!=null && e.nodeType == 1;e = e.parentNode){ x -= e.scrollLeft; y -= e.scrollTop; } return {x:x,y:y}; }
14、表单
要明确选取一个表单元素可以索引表单对象的elements属性
document.forms.address.elements[0]
document.forms.address.street
<form name="shopping"> <label><input type="radio" name="method"/>first</label> <label><input type="radio" name="method"/>sec</label> <label><input type="radio" name="method"/>thr</label> </form>
对于该表单元素数组可以采用如下的方式获取:
var methods = document.forms.shopping.elements.method;
遍历数组查询已经被选中的元素
var shopmet; for(var i=0;i < methods.length;i++){ if(methods[i].checked){ shopmet = methods[i].value; } }
javascript方法有两个方法submit()和reset(),用来提交表单和重置表单数据!
15、可编辑的html内容
有两种方法启用html的编辑功能。
其一:设置任何html标签的 contenteditable属性;
其二:设置对应元素的javascript contenteditable
这都将使得该元素变成可编辑的状态。
例如:
<div contenteditable> click it edit </div>
将document.designMode属性设置为字符串‘on’时候使得整个文档都是可以编辑的,设置为off将恢复为只读的模式!