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将恢复为只读的模式!

上一篇:应用.Net+Consul维护RabbitMq的高可用性


下一篇:JavaScript权威指南--脚本化CSS