【学习笔记七】 - 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
//动态脚本
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扩展】


//
...
//对上面的元素删除'user'类 //方法一: //将类名字符串拆分成数组 var classNames=div.className.split(/\s+/); //找到要删类名下标 var pos=-1,i,len; for(i=0,len=classNames.length;i
//使用innerHTML或outerHTML的次数控制在合理范围内
for (var i = 0; i < values.length; i++) {
	ul.innerHTML+="
  • "+values[i]+"
  • ";//应避免这种操作 } //每次循环设置一次innerHTML效率低,意味着每次循环要访问两次,读、写 //最好的做法是单独构建字符串,再一次性赋值 var itemsHtml=''; for (var i = 0; i < values.length; i++) { itemsHtml+="
  • "+values[i]+"
  • ";//应避免这种操作 } 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中没有内联样式,得到结果为""
    //因为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);
    //

    Hello world!

    //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()赋值文本范围




    你可能感兴趣的:(【学习笔记七】 - DOM+DOM扩展+DOM2级和DOM3级 《js高程》10-12笔记)