零js基礎 | 程序設計 | 12 - DOM2和DOM3
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");
混合svg写法
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Example XHTML page</title>
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 100 100" style="width:100%; height:100%">
<rect x="0" y="0" width="100" height="100" style="fill:red" />
</svg>
</body>
</html>
在DOM2 级中,Node 类型包含下列特定于命名空间的属性。
localName:不带命名空间前缀的节点名称。
namespaceURI:命名空间URI 或者(在未指定的情况下是)null。
prefix:命名空间前缀或者(在未指定的情况下是)null。
nodeName 等于prefix+":"+ localName
<html>元素來說
localName:html
tagName:html
namespaceURI:http://www.w3.org/1999/xhtml
prefix:null
<s:svg>元素
localName:svg
tagName:s:svg
namespaceURI:http://www.w3.org/2000/svg
prefix:s
DOM3 级在此基础上更进一步,又引入了下列与命名空间有关的方法。
isDefaultNamespace(namespaceURI):在指定的namespaceURI 是当前节点的默认命名空
间的情况下返回true。
lookupNamespaceURI(prefix):返回给定prefix 的命名空间。
lookupPrefix(namespaceURI):返回给定namespaceURI 的前缀。
Document变化
只有在文档中存在两个或多个命名空间时,这些与命名空间有关的方法才是必需的。
//创建一个新的SVG 元素
var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
//创建一个属于某个命名空间的新特性
var att = document.createAttributeNS("http://www.somewhere.com", "random");
//取得所有XHTML 元素
var elems = document.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "*");
Element变化
getAttributeNS(namespaceURI,localName):取得属于命名空间namespaceURI 且名为
localName 的特性。
getAttributeNodeNS(namespaceURI,localName)
getElementsByTagNameNS(namespaceURI, tagName)
hasAttributeNS(namespaceURI,localName)
removeAttriubteNS(namespaceURI,localName)
setAttributeNS(namespaceURI,qualifiedName,value)
setAttributeNodeNS(attNode)
除了第一个参数之外,这些方法与DOM1 级中相关方法的作用相同;第一个参数始终都是一个命
名空间URI。
NamedNodeMap变化
getNamedItemNS(namespaceURI,localName)取得属于命名空间namespaceURI 且名为
localName 的项。
removeNamedItemNS(namespaceURI,localName)
其它变化:
- DocumentType 类型的变化 类型新增了3 个属性:publicId、systemId 和internalSubset。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
中的:publicId == "-//W3C//DTD HTML 4.01//EN",
systemId =="http://www.w3.org/TR/html4/strict.dtd"
alert(document.doctype.publicId);
alert(document.doctype.systemId);
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
[<!ELEMENT name (#PCDATA)>] >
document.doctype.internalSubset //"<!ELEMENT name (#PCDATA)>"
- Document 类型的变化
importNode() - Node 类型的变化
isSupported()
与DOM1级为document.implementation 引入的hasFeature()方法类似,isSupported()方法用于确定当前节点具有什么能力
if (document.body.isSupported("HTML", "2.0")){
//执行只有"DOM2 级HTML"才支持的操作
}
DOM3 额外引入数据:setUserData(要设置的键,实际的数据(可以是任何数据类型),处理函数)
var value = document.body.getUserData("name");
//创建div
var div = document.createElement("div");
//添加数据
div.setUserData("name", "Nicholas", function(operation, key, value, src, dest) {
if (operation == 1) {
dest.setUserData(key, value, function() {});
}
});
//使用cloneNode复制时,会调用处理函数,从而将数据自动复制到副本
var newDiv = div.cloneNode(true);
//调用getUserData()时,返回与原始结点相同的值
alert(newDiv.getUserData("name")); //"Nicholas"
- 框架的变化
var iframe = document.getElementById("myIframe");
var iframeDoc = iframe.contentDocument; //在IE8 以前的版本中无效
兼容
对象,可以使用下列代码。
var iframe = document.getElementById("myIframe");
var iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
cssText
在写入模式下,赋给cssText 的值会重写整个style 特性的值;也就是
说,以前通过style 特性指定的样式信息都将丢失。例如,如果通过style 特性为元素设置了边框,
然后再以不包含边框的规则重写cssText,那么就会抹去元素上的边框。下面是使用cssText 属性的
var div = document.getElementsByTagName('div')[0]
div.style.cssText = 'width:25px;height:100px;background-color:red'
console.log(div.style.cssText) //width:25px;height:100px;background-color:red
for (var i = 0; i < div.style.length; i++) {
alert(div.style[i]) //width/height/backgorund-color
alert(div.style.item(i))
console.log(div.style.getPropertyValue(div.style[i])) //25px 100px red
}
getPropertyValue()方法取得的始终都是CSS 属性值的字符串表
getPropertyCSSValue()它返回一个包含两个属性的CSSValue 对象,这两个属性分,别是:cssText 和cssValueType。
div.style.removeProperty('width') //移除
getComputedStyle() 要取得樣式的元素與一個為元素字條串如:after,第二個參數可以為null;
無論樣式表還是行間樣式;計算後的值
var myDiv = document.getElementById("myDiv");
var computedStyle = document.defaultView.getComputedStyle(myDiv, null);
alert(computedStyle.backgroundColor); // "red"
alert(computedStyle.width); // "100px"
alert(computedStyle.height); // "200px"
alert(computedStyle.border); // 在某些浏览器中是"1px solid black"
IE下
var myDiv = document.getElementById("myDiv");
var computedStyle = myDiv.currentStyle;
alert(computedStyle.backgroundColor); //"red"
alert(computedStyle.width); //"100px"
alert(computedStyle.height); //"200px"
alert(computedStyle.border); //undefined
綜合
function getStyle(obj, attr) {
if (obj.currentStyle) {
return obj.currentStyle[attr]
} else {
return getComputedStyle(obj, false)[attr]
}
};
function getStyleSheet(element){
return element.sheet || element.styleSheet;
}
//取得第一个<link/>元素引入的样式表
var link = document.getElementsByTagName("link")[0];
var sheet = getStyleSheet(link);
var sheet = document.styleSheets[0];
var rules = sheet.cssRules || sheet.rules; //取得规则列表
var rule = rules[0]; //取得第一条规则
alert(rule.selectorText); //"div.box"
alert(rule.style.cssText); //完整的CSS 代码
alert(rule.style.backgroundColor); //"blue"
alert(rule.style.width); //"100px"
alert(rule.style.height); //"200px"
<style>.box{width:100px;}</style> ----sheet = document.styleSheets[0];
<link rel="stylesheet" href="style.css">----sheet = document.styleSheets[1];
<style>.box{height}</style> --sheet = document.styleSheets[2];
var rules = sheet.cssRules || sheet.rules; //取得规则列表
為每一個sheet裏的每一條;{}裏算一條
必须要注意的是,以这种方式修改规则会影响页面中适用于该规则的所有元素。换句话说,如果有两个带有box 类的
var sheet = document.styleSheets[0];
var rules = sheet.cssRules || sheet.rules; //取得规则列表
var rule = rules[0]; //取得第一条规则
rule.style.backgroundColor = "yellow"
function getTop(o) {
var oTop = o.offsetTop;
var current = o.offsetParent;
while (current !== null) {
oTop += current.offsetTop;
current = current.offsetParent;
}
return oTop;
}
alert(getTop(box))
所以视口
function getViewport() {
if (document.compatMode == "BackCompat") {
return {
width: document.body.clientWidth,
height: document.body.clientHeight
};
} else {
return {
width: document.documentElement.clientWidth,
height: document.documentElement.clientHeight
};
}
}
console.log(getViewport())
scrollHeight/scrollWidth/scrollLeft/scrollTop
有些元素(例如<html>元素),即使没有执行任何代码也能自动地添加滚动条;但另外一些元素,则需要通过CSS 的
overflow 属性进行设置才能滚动
scrollWidth 和scrollHeight 主要用于确定元素内容的实际大小
无滚动条时:scrollWidth = clientWidth
实际页面大小:document.documentElement.scrollHeight
视口大小:document.documentElement.clientHeight
无滚动条时:
IE7 chrome
document.documentElement.scrollHeight(页面占用元素大小) < document.documentElement.clientHeight(视口大小)
IE8 /IE9 /IE10 /IE11 firfox
document.documentElement.scrollHeight == document.documentElement.clientHeight
getBoundingClientRect()返回矩形,ie8(2.2),ie9(0,0)
,right 和left 的差值与offsetWidth 的值相等,而bottom 和top 的差值与offsetHeight
相等。而且,left 和top 属性大致等于使用本章前面定义的getElementLeft()和getElementTop()
函数取得的值
function getBoundingClientRect(element) {
var scrollTop = document.documentElement.scrollTop;
var scrollLeft = document.documentElement.scrollLeft;
if (element.getBoundingClientRect) {
if (typeof arguments.callee.offset != "number") {
var temp = document.createElement("div");
temp.style.cssText = "position:absolute;left:0;top:0;";
document.body.appendChild(temp);
arguments.callee.offset = -temp.getBoundingClientRect().top - scrollTop;
document.body.removeChild(temp);
temp = null;
}
var rect = element.getBoundingClientRect();
var offset = arguments.callee.offset;
return {
left: rect.left + offset,
right: rect.right + offset,
top: rect.top + offset,
bottom: rect.bottom + offset
};
} else {
var actualLeft = getElementLeft(element);
var actualTop = getElementTop(element);
return {
left: actualLeft - scrollLeft,
right: actualLeft + element.offsetWidth - scrollLeft,
top: actualTop - scrollTop,
bottom: actualTop + element.offsetHeight - scrollTop
}
}
}
alert(getBoundingClientRect(div).left)
alert(getBoundingClientRect(div).right)
alert(div.offsetWidth)
`
DOM2 级遍历和范围
检测是否有DOM2级能力(IE8返回false)
var supportsTraversals = document.implementation.hasFeature("Traversal", "2.0");
var supportsNodeIterator = (typeof document.createNodeIterator == "function");
var supportsTreeWalker = (typeof document.createTreeWalker == "function");
从document 开始依序向前,向下遍历,到开始根节点为止。NodeIterator
和TreeWalker 都以这种方式执行遍历。
createNodeIterator(root[起点],whatToShow[哪些节点数字代码],filter[NodeFilter对象,一个表示接受或拒绝的特定节点],entityReferenceExpansion[布尔值,表示是否扩展实体引用])
DOM2-----------------------------待放