【学习笔记七】 - DOM+DOM扩展+DOM2级和DOM3级 《js高程》10-12笔记

写在前面:

如题,这篇是《js高程》第10-12章笔记,记在网上也是方便自己以后随时随地可以回看。


【DOM】


//将NodeList对象转换为数组
function convertToArray(nodes){
	var array=null;
	try{
		//非IE
		array=Array.prototype.slice.call(nodes,0;)
	}catch(ex){
		array=new Array();
		for (var i = 0,len=nodes.length; i < len; i++) {
			//因为长度是动态变化的,所以先赋值给变量len
			array.push(nodes[i]);
		}
	}
	return array;
}
//NodeList对象是一个类数组对象,不是Array的实例
//应尽量减少访问NodeList的次数,因为每次访问都会运行一个基于文档的查询,所以考虑将值缓存
//遍历特性
function outputAttributes(element){
	var pairs=new Array(),
	//用一个数组来保存名值对,最后再以空格为分隔符拼接
	//这是序列化长字符串时一种常用技巧
		attrName,
		attrValue,
		i,
		len;
	for (var i = 0,len=element.attributes.length; i < len; i++) {
		//针对attributes对象中的特性,不同浏览器返回的顺序不同
		attrName=element.attributes[i].nodeName;
		attrValue=element.attributes[i].nodeValue;
		if(element.attributes[i].specified){
			//通过specified属性排除没有指定的特性
			pairs.push(attrName+'=\"'+attrValue+'\"');
		}
	}
	return pairs.join(' ');
}

//不同浏览器对待childNodes属性中包含的不同子节点有不同的处理
//如:对于元素间的空格,IE9及以前的版本不会返回文本节点,其他浏览器会返回文本节点
//在执行某项操作前最好先检查nodeType
function(var i,len=element.childNodes.length;i<len;i++){
	if(element.childNodes[i].nodeType==1){
		//...
	}
}

//DocumentFragment类型,在文档中没有对应标记
//DOM规定文档片段(document fragment)是一种“轻量级”文档,可作为一个“仓库”

var fragment=document.createDocumentFragment();
var ul=document.getElementById('myList');
var li=null;
for (var i = 0; i < 3; i++) {
	li=document.createElement('li');
	li.appendChild(document.createTextNode('Item '+(i+1)));
	fragment.appendChild(li);
	//将li加到仓库中,再一次性加给ul,避免浏览器反复渲染
}
ul.appendChild(fragment);
//动态脚本
function loadScript(url){
	var script=document.createElement('script');
	script.type='text/javascript';
	script.src=url;
	document.body.appendChild(script);
}
//另一种指定script方式
script.appendChild(document.createTextNode("function sayHi(){alert('hi');}"));
//但IE将script视为一个特殊元素,不允许DOM访问其子节点
//但可以text属性来指定js代码
script.text="function sayHi(){alert('hi');}";
//safari 3之前不支持text,却允许使用文本节点技术指定代码

function loadScriptString(code){
	var script=document.createElement('script');
	script.type='text/javascript';
	try{
		script.appendChild(document.createTextNode(code));
	}catch(ex){
		script.text=code;
	}
	document.body.appendChild(script);
}
loadScriptString("function sayHi(){alert('hi');}");
//这样执行代码与在全局作用域中把相同的字符串传递给eval()是一样的
//动态样式
function loadStyleString(css){
	var style=document.createElement('style');
	style.type='text/css';
	try{
		style.appendChild(document.createTextNode(css));
	}catch(ex){
		style.styleSheet.cssText=css;
	}
	var head=document.getElementsByTagName('head')[0];
	head.appendChild(style);
}
loadStyleString('body{background-color:yellow}');
//操作表格
//创建table
var table=document.createElement('table');
table.border=1;
table.width="100%";
//创建tbody
var tbody=document.createElement('tbody');
table.appendChild(tbody);
//创建第一行
tbody.insertRow(0);
tbody.rows[0].insertCell(0);
tbody.rows[0].cells[0].appendChild(document.createTextNode('Cell 1,1'));
tbody.rows[0].insertCell(1);
tbody.rows[0].cells[1].appendChild(document.createTextNode('Cell 2,1'));
//创建第二行
tbody.insertRow(1);
tbody.rows[1].insertCell(0);
tbody.rows[1].cells[0].appendChild(document.createTextNode('Cell 1,2'));
tbody.rows[1].insertCell(1);
tbody.rows[1].cells[1].appendChild(document.createTextNode('Cell 2,2'));




【DOM扩展】


//<div class="bd user disabled">...</div>
//对上面的元素删除'user'类
//方法一:
//将类名字符串拆分成数组
var classNames=div.className.split(/\s+/);
//找到要删类名下标
var pos=-1,i,len;
for(i=0,len=classNames.length;i<len;i++){
	if(classNames[i]=='user'){
		pos=i;
		break;
	}
}
//删除类名
classNames.splice(pos,1);
//还原
div.className=classNames.join(' ');
//方法二:
div.classList.remove('user');
//使用innerHTML或outerHTML的次数控制在合理范围内
for (var i = 0; i < values.length; i++) {
	ul.innerHTML+="<li>"+values[i]+"</li>";//应避免这种操作
}
//每次循环设置一次innerHTML效率低,意味着每次循环要访问两次,读、写
//最好的做法是单独构建字符串,再一次性赋值
var itemsHtml='';
for (var i = 0; i < values.length; i++) {
	itemsHtml+="<li>"+values[i]+"</li>";//应避免这种操作
}
ul.innerHTML=itemsHtml;
//判断某个节点是不是另一个节点后代——contains()
//IE\firefox9+\safari\opera\chrome
//DOM level 3 compareDocumentPosition(),返回一个表示关系的位掩码
//IE9+\firefox\safari\opera9.5+\chrome
//掩码:1——给定节点不在当前文档中
//2——给定节点在dom树种位于参考节点之前
//4——给定节点在dom树种位于参考节点之后
//8——给点节点是参考节点的祖先
//16——给点节点是参考节点的后代

//通用contains()
function contains(refNode,otherNode){
	if(typeof refNode.contains=='function'&&(!client.engine.webkit||client.engine.webkit>=522));{
		//client.engine.webkit>=522,检查当前浏览器所用webkit版本号是至少safari3(webkit版本号为522或更高)
		return refNode.contains(otherNode);
	}else if(typeof refNode.compareDocumentPosition=='function'){
		return !!(refNode.compareDocumentPosition(otherNode)&16);
	}else{
		var node=otherNode.parentNode;
		do{
			if(node==refNode){
				return true;
			}else{
				node=node.parentNode;
			}
		}while(node!=null);
		return false;
	}
}
//innerText——IE4+\safari3+\opera8+\chrome
//textContent——firefox\IE9+\safari3+\opera10+\chrome
//为了确保跨浏览器兼容:
function getInnerText(element){
	return (typeof element.textContent=='string')?element.textContent:element.innerText;
}
function setInnerText(element,txt){
	if(typeof element.textContent=='string'){
		element.textContent=txt;
	}else{
		element.innerText=txt;
	}
}
setInnerText(div,'hello');
alert(getInnerText(div));



【DOM2级和DOM3级】


//确定浏览器是否支持不同dom模块
var supportsDOM2Core=document.implementation.hasFeature('Core','2.0');
var supportsDOM3Core=document.implementation.hasFeature('Core','3.0');
var supportsDOM2HTML=document.implementation.hasFeature('HTML','2.0');
var supportsDOM2Views=document.implementation.hasFeature('Views','2.0');
var supportsDOM2XML=document.implementation.hasFeature('XML','2.0');
//确定浏览器是否支持dom2级定义的CSS能力
var supportsDOM2CSS=document.implementation.hasFeature('CSS','2.0');
var supportsDOM2CSS2=document.implementation.hasFeature('CSS2','2.0');
//确定浏览器是否支持dom2级样式表
var supportsDOM2StyleSheets=document.implementation.hasFeature('StyleSheets','2.0');
//样式

//getPropertyValue()取得CSS属性值的字符串表示
//IE9+、Firefox、Safari、Opera9+、Chrome
var prop,value,i,len;
for(i=0,len=maDiv.style.length;i<len;i++){
	prop=myDiv.style[i];
	value=myDiv.style.getPropertyValue(prop);
	alert(prop+":"+value);
}
//removeProperty()从元素的样式表中移除某个CSS属性
myDiv.style.removeProperty("border");
//IE9+、Firefox、Safari、Opera9+、Chrome


//element.style.color未必能获取实际样式,
//如<input type="text"></input>中没有内联样式,得到结果为""
//因为style对象不含从样式表层叠而来并影响到当前元素的样式信息
//所以可以用document.defaultView.getComputedStyle()/window.getComputedStyle()
//接收两个参数,一个是要计算的元素,一个是伪元素字符串如":after"
//不同浏览器返回值的表示方式可能不同,最后再多几种浏览器中测试以下
//IE不支持getComputedStyle()方法,用element.currentStyle


//CSSRule对象表示样式表中每一条规则。
//CSSStyleRule类型继承自CSSRule,常用属性:cssText、selectorText、style
//cssText与style.cssText类似,但前者包含选择符文本和花括号,后者只含样式信息,前者只读,后者可重写
//div.box{bacaground-color:blue;}
var sheet=document.styleSheets[0];
var rules=sheet.cssRules||sheet.rules;
var rule=rules[0];
alert(rule.selectorText);//div.box
alert(rule.style.backgroundColor);//blue
//添加规则用insertRule(),Firefox、Safari、Opera、Chrome
//IE8及以前版本用addRule()
function insertRule(sheet,selectorText,cssText,position){
	if(sheet.insertRule){
		sheet.insertRule(selectorText+'{'+cssText+'}',position);
	}else{
		sheet.addRule(selectorText+'{'+cssText+'}',position);
	}
}
//删除用deleteRule(),IE用removeRule()
sheet.deleteRule(0);


//想要知道元素在页面上的偏移量,将这个元素的offsetLeft和offsetTop(边框以外不含边框)与其offsetParent的相同属性增加,
//循环至根元素,可得一个基本准确的值
function getElementLeft(element){
	var actualLeft=element.offsetLeft;
	var current=element.offsetParent;

	while(current !==null){
		actualLeft+=current.offsetLeft;
		current=current.offsetParent();;
	}
	return actualLeft;
}
//要确定浏览器视口大小,可用document.documentElement或document.body(IE7-)的clientWidth和clientHeight(边框以内不含边框)
function getVierport(){
	if(document.compatMode=='BackCompat'){
		//先检查document.compatMode属性以确定浏览器是否运行在混杂模式
		//Safari3.1及以前不支持这个属性就会自动执行else
		//Chrome、Opera、Firefox大多数情况下都运行在标准模式下,因此也会执行else
		return{
			width:document.body.clientWidth;
			height:document.body.clientHeight;
		};
	}else{
		return{
			width:document.documentElement.clientWidth;
			height:document.documentElement.clientHeight;
		};
	}
}
//确定文档总高度时,必须取得scrollWidth/clientWidth和scrollHeight/clientHeight中最大值
//scrollWidth:无滚动条时元素内容总宽度
var docHeight=Math.max(document.documentElement.scrollHeight,document.documentElement.clientHeight);
var docWidth=Math.max(document.documentElement.scrollWidth,document.documentElement.clientWidth);

//IE、Firefox3+、Safari4+、Opera9.5+、Chrome为每个属性提供getBoundingClientRect(),
//返回一个矩形对象,包含4个属性:left、top、right、bottom,
//给出元素在页面中相对于视口的位置
//IE8及以前认为文档左上角起点左边为(2,2),其他浏览器及IE9认为(0,0)
//遍历
//“DOM2级遍历和范围”模块定义了两个用于辅助完成顺序遍历DOM结构的类型:
//NodeIterator和TreeWalker
//深度优先
//IE不支持DOM遍历

//确定浏览器是否支持dom2级遍历
//一个只显示p元素的节点迭代器
var supportsTraversals=document.implementation.hasFeature('Traversal','2.0');
var supportsNodeIterator=(typeof document.createNodeIterator=='function');
var supportsTreeWalker=(typeof document.createTreeWalker=='function');

var filter={
	acceptNode:function(node){
		return node.tagName.toLowerCase()=='p'?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP;
	}
};
//如果应该访问当前节点,返回NodeFilter.FILTER_ACCEPT,
//需要跳过当前节点进入下一节点返回NodeFilter.FILTER_SKIP
//NodeFilter.FILTER_REJECT会跳过当前节点及该节点的整个子树
var iterator=document.creatNodeIterator(root,NodeFilter.SHOW_ELEMENT,filter,false);
//四个参数分别表示搜索起点,表示要访问哪些节点的数字代码,
//过滤器(一个NodeIterator对象或函数),最后一个表示是否扩展实体引用在html页面中无用
//NodeFilter.SHOW_ELEMENT表示显示元素节点

//NodeIterator类型的两个主要方法:
//nextNode()、previousNode()

//TreeWalker是NodeIterator的一个更高级版本,多了一些方法:
//parentNode()、firstChild()、lastChild()、nextSibling()、previousSibling()
//范围

var supportsRange=document.implementation.hasFeature('Range','2.0');
var alsoSupportsRange=(typeof document.createRange=='function');

//selectNode()选择整个节点,包括子节点,selectNodeContents()只选择子节点
//deleteContents()从文档中删除范围所包含内容,与其类似,还有extractContents(),但会返回范围的文档片段,
//在将文档片段传入appendChild()时,添加到文档的知识片段的子节点而非本身
//cloneContents()创建范围副本;
//insertNode()向范围选区的开始处插入一个节点;
//surroundContents()环绕范围插入内容,接收参数环绕范围内容的节点

var p1=document.getElementById('p1');
helloNode=p1.firstChild.firstChild;
worldNode=p1.lastChild;
range=document.createRange();//创建范围
var span=document.createElement('span');
span.style.backgroundColor='yellow';
range.surroundContents(span);
//<p><b><span style="background-color:yellow">Hello</span></b> world!</p>

//collapse()折叠范围,参数是一个布尔值,true表示折叠到范围起点,false折叠到范围终点
//compareBoundaryPoints()确定这些范围是否有公共边界(起点或终点),
//接收两个参数,一个是表示比较方式的常量值,一个是比较的范围
//cloneRange()复制范围
//使用完范围后要解除引用方便回收
range.detach();
range=null;

//IE8及以前的版本不支持DOM范围,但有一个类似的文本范围
var range=document.body.createTextRange();//创建范围
//findText("hello")找到第一个匹配给定文本返回true,否则false
//findText可传入第二个参数,正数表示向前搜索,负数表示向后搜索
//范围的text属性克检查范围文本
//类似selectNode()方法,IE有一个moveToElementText()选择该元素所有文本及html标签
//可用范围的htmlText属性取得范围的全部内容,包括文本和HTML
//move()\moveStart()\moveEnd()\expand()——以特定增量向四周移动范围
//接收两个参数("character"\"word"\"sentence"\"textedit",1)
//逐个字符、逐个单词、逐个句子、移动到当前范围选区的开始或结束位置
//可用text或pasteHTML()设置文本,要向范围插入HTML代码时用pasteHTML()方法
//折叠用collapse()
//用boundingWidth属性返回范围宽度判断是否折叠
//compareEndPoints(),类似于dom中的compareBoundaryPoints()
//比较范围:
//isEqual()用于确定两个范围是否相等
//inRange()用于确定一个范围是否包含另一个范围
//duplicate()赋值文本范围




猜你喜欢

转载自blog.csdn.net/jiuto_crx/article/details/78024600