JS学习11(DOM2&DOM3)

DOM1级主要是在定义HTML和XML文档的低层结构。D2和D3则在这个结构的基础上引入了更多的交互能力。它们被分为了许多模块:

  • DOM Level 2 Core:为1级核心添加了更多方法和属性
  • DOM Level 2 Views:为文档定义了基于样式信息的不同视图
  • DOM Level 2 Events:说明了如何使用事件与DOM文档交互
  • DOM Level 2 Style:有关CSS
  • DOM Level 2 Traversal and Range:遍历和选择的新API
  • DOM Level 2 HTML:添加了新方法和属性的HTML

DOM变化

DOM2级核心没有引进新类型,增强了既有类型。DOM3级核心既引进了新类型又增强了既有类型。

DOM Level 2 Views、DOM Level 2 HTML也提供了新的属性和方法。

重点之一是对命名空间的支持。

看浏览器兼不兼容:

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"); 

针对 XML命名空间的变化

有了XML命名空间,不同XML文档的元素就可以混合在一起。技术上说HTML不支持XML命名空间,但JSP,XHTML支持。

命名空间使用xmlns特性来指定。XHTML的命名空间是http://www.w3.org/1999/xhtml

<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>Example XHTML page</title>
    </head>
    <body>
        Hello world!
    </body>
</html> 

在上面的例子中,所有元素都默认为XHTML命名空间的元素。想要明确的指定那些元素属于这个命名空间就要使用前缀:

<xhtml:html xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <xhtml:head>
        <xhtml:title>Example XHTML page</xhtml:title>
    </xhtml:head>
    <xhtml:body xhtml:class="home">
        Hello world!
    </xhtml:body>
</xhtml:html> 

这时所有的XHTML元素的前缀都要是这个才行,有时为了避免冲突,也需要用命名空间来限定特性。这个在使用单一语言来编写XML文档时没啥用,但是在多语言时就有用了:

<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>  

<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>Example XHTML page</title>
    </head>
    <body>
        <s:svg xmlns:s="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 100 100" style="width:100%; height:100%">
            <s:rect x="0" y="0" width="100" height="100" style="fill:red"/>
        </s:svg>
    </body>
</html>  

这个例子中通过设置命名空间,将svg标识为了与包含文档无关的元素。此时svg元素的所有子元素以及这些元素的所有特性都属于了http://www.w3.org/2000/svg。所以即便这是一个XHTML文档,其中的svg代码还是有效的。

DOM2同时提供了相应的查询和创建有命名空间归属的节点版本的方法。

Node类型的变化

在DOM2级中,node类型包含下列特定于命名空间的属性。

  • localName:不带命名空间前缀的节点名称
  • namespaceURI:命名空间URI
  • prefix:命名空间前缀

    DOM3级中有如下方法:

  • isDefaultNamespace(namespaceURI):看看当前节点的默认命名空间是不是传入的参数
  • lookupNamespaceURI(prefix):返回给定前缀的命名空间
  • lookupPrefix(namespaceURI):返回给定URI的前缀

这里有个神奇的事情:

//这里比较有趣,svg节点的defaultNameSpace不是我们给他设置的那个而是上一级的。
alert(svg.isDefaultNamespace("http://www.w3.org/1999/xhtml")); //true
alert(svg.isDefaultNamespace("http://www.w3.org/2000/svg")); //false

Document类型的变化

createElementNS(namespaceURI, tagName)

createAttributeNS(namespaceURI, attributeName)

getElementsByTagNameNS(namespaceURI, tagName)

Element类型的变化

getAttributeNS(namespaceURI,localName)

getAttributeNodeNS(namespaceURI,localName)

getElementsByTagNameNS(namespaceURI, tagName)

hasAttributeNS(namespaceURI,localName)

removeAttriubteNS(namespaceURI,localName)

setAttributeNS(namespaceURI,qualifiedName,value)

setAttributeNodeNS(attNode)

NamedNodeMap 类型的变化

getNamedItemNS(namespaceURI,localName)

removeNamedItemNS(namespaceURI,localName)

setNamedItemNS(node)

其他方面变化

DocumentType

新增3个属性publicId、systemId、internalSubset

Document类型的变化

importNode()

这个方法用于导入一个来自其他文档的节点appendChild()如果加入一个来自其他文档的节点会报错。这个方法会把别的文档的节点转化成本文档的。这个方法有点像cloneCode(),都是接收一个节点和一个布尔值,返回浅复制或深复制的节点,只不过这个节点的ownerDocument会被重置。

var newNode = document.importNode(oldNode, true);
document.body.appendChild(newNode);

defaultView

这个指针指向拥有给定文档的窗口或框架,View。IE不支持,I使用parentWindow,所以要是想判断文档归属的窗口:

var parentWindow = document.defaultView || document.parentWindow;

createDocumentType()、createDocument()

document.implementation的方法,Core。创建一个DocumentType、创建一个新文档

//新建一个XHTML文档
var doctype = document.implementation.createDocumentType("html",
                    " -//W3C//DTD XHTML 1.0 Strict//EN",
                    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd");
var doc = document.implementation.createDocument("http://www.w3.org/1999/xhtml", "html", doctype);

createHTMLDocument()

用来创建一个完整的HTML文档,包括html,head,body,title。接收的字符串参数会放到title里。HTML

Node类型的变化

isSupported()

当前节点具有的能力

if (document.body.isSupported("HTML", "2.0")){
}

isSameNode()、isEqualNode()

DOM3

isSameNode()代表两个节点引用同一个对象。

isEqualNode()代表两个节点类型相同,属性相同,属性值相等。

//相等,不相同的两个节点
var div1 = document.createElement("div");
div1.setAttribute("class", "box");
var div2 = document.createElement("div");
div2.setAttribute("class", "box");
alert(div1.isSameNode(div1)); //true
alert(div1.isEqualNode(div2)); //true
alert(div1.isSameNode(div2)); //false

setUserData()

这个方法比较神奇,可以为节点额外添加数据,3个参数:键,值,处理函数。这个处理函数会在节点被复制,导入新文档,删除,重命名时被调用。这个函数接受5个参数:操作类型(1、2、3、4),数据键、数据值、源节点、目标节点。

/***********************Node类型的新方法:setUserData(),不过Safari和chrome都不支持貌似********/
var div = document.createElement("div");
div.setUserData("name", "Nicholas", function(operation, key, value, src, dest){
    if (operation == 1){
        dest.setUserData(key, value, function(){});
    }
});
var newDiv = div.cloneNode(true);
alert(newDiv.getUserData("name"));      //"Nicholas"

框架的变化

框架和内嵌框架HTMLFrameElement、HTMLIFrameElement。这两个类型有新属性contentDocument。指向表示框架内容的文档对象。

在此之前无法通过元素获得这个对象,这个对象是Document类型的。IE8之前不支持,可以使用contentWindow。contentWindow所有浏览器都支持。

var iframe = document.getElementById("myIframe");
var iframeDoc = iframe.contentDocument || iframe.contentWindow.document;

样式

要支持DOM2级CSS

var supportsDOM2CSS = document.implementation.hasFeature("CSS", "2.0");
var supportsDOM2CSS2 = document.implementation.hasFeature("CSS2", "2.0");

访问元素的样式

任何支持style特性的HTML元素在JS中都有一个对应的style属性。它是CSSStyleDeclaration的实例,这里包含通过HTML的style特性指定的所有样式信息,但不包含外部与内嵌样式表的样式。样式通过属性访问,驼峰命名。

var myDiv = document.getElementById("myDiv");
myDiv.style.backgroundColor = "red";
myDiv.style.width = "100px";
myDiv.style.height = "200px";
myDiv.style.border = "1px solid black";

DOM样式属性和方法

属性和方法用来访问和修改样式。

- ‰ cssText:访问CSS中的特性代码,设置时覆盖原来的。

- length:CSS属性的数量

- parentRule:CSSRule对象

- getPropertyCSSValue(propertyName):给定属性的CSSValue

- getPropertyPriority(propertyName):如果给定属性有!important则返回”important”,否则空字符串。

- getPropertyValue(propertyName):给定属性值 ‰

- item(index):给定位置的CSS属性名称

- removeProperty(propertyName):从样式表中删除给定属性

- setProperty(propertyName,value,priority):为给定属性设置值和优先级。

var prop, value, i, len;
for (i=0, len=myDiv.style.length; i < len; i++){
    prop = myDiv.style[i];  //myDiv.style.item(i)
    value = myDiv.style.getPropertyValue(prop);
    alert(prop + " : " + value);
}

计算的样式

style只包含直接写在HTML里的特性,但是不支持样式表的。这是个大问题。

document.defaultView.getComputedStyle()

这个方法接收两个参数,要取得计算样式的元素和一个伪元素字符串。返回一个CSSStyleDeclaration。包含所有计算后的属性。

IE不支持,但是IE每个节点都有一个currentStyle属性,这里包含了计算后的属性。

计算后样式只读。

var myDiv = document.getElementById("myDiv");
var computedStyle = document.defaultView.getComputedStyle(myDiv, null);
//IE不支持,使用currentStyle
//var computedStyle = myDiv.currentStyle;
alert(computedStyle.height);    // "200px" 

操作样式表

CSSStyleSheet类型表示样式表,继承自StyleSheet,后者可以作为一个基础接口来定义非CSS样式表。CSSStyleSheet继承了如下属性。

  • disabled:样式表是否被禁用
  • href:样式表的URL
  • media:样式表支持的媒体类型集合
  • ownerNode:指向拥有当前样式表节点的指针,IE不支持
  • parentStyleSheet:当前样式表通过@import导入的情况下,这个属性指向导入它的样式表
  • title:ownerNode中title的值
  • type:表示样式表类型的字符串
  • cssRules:样式表中包含的样式规则的集合,IE使用rules
  • ownerRule:当前样式表通过@import导入的情况下,指向表示导入的规则,IE不支持
  • deleteRule(index):删除cssRules集合中指定位置的规则,IE使用removeRule()
  • insertRule(rule,index):向cssRules集合中指定位置插入rule字符串,IE使用addRule()

应用于文档的所有样式通过document.styleSheets集合来表示。

var sheet = null;
for (var i=0, len=document.styleSheets.length; i < len; i++){
    sheet = document.styleSheets[i];
    alert(sheet.href);
}

直接通过link,style元素取得CSSStyleSheet。

function getStyleSheet(element){
    return element.sheet || element.styleSheet;
}
var link = document.getElementsByTagName("link")[0];
var sheet = getStyleSheet(link);
alert(sheet.href);

CSSRule对象

这个对象表示样式表中的每一条规则。它是一个基类,不止是CSS规则,包括@import、@font-face、@page、@charset等。不过其中最常用的当然是CSS规则咯,是CSSStyleRule类型,有下面这些属性:

  • cssText:文本咯,只读的,包括选择符,花括号等等一整套
  • parentRule:如果当前规则是导入的规则,这个属性引用导入规则,否则为null
  • parentStyleSheet:规则所归属的样式表
  • selectorText:规则的选择符文本
  • style:CSSStyleDeclaration 对象,通过这个可以设置和取得规则中的样式值
  • type:规则类型的常量值
var sheet = document.styleSheets[0]; //取得样式表
var rules = sheet.cssRules || sheet.rules;   //为兼容IE
var rule = rules[0];
alert(rule.selectorText);
alert(rule.cssText);
alert(rule.style.cssText);
alert(rule.style.height);
//这里的修改并不成功????
rule.style.height = "2000ps";
alert(rule.style.height);

创建规则

//添加规则
function insertRule(sheet, selectorText, cssText, position){
    if (sheet.insertRule){
        sheet.insertRule(selectorText + "{" + cssText + "}", position);
    } else if (sheet.addRule){
        sheet.addRule(selectorText, cssText, position);
    }
} 

删除规则

//删除规则
function deleteRule(sheet, index){
    if (sheet.deleteRule){
        sheet.deleteRule(index);
    } else if (sheet.removeRule){
        sheet.removeRule(index);
    }
} 

元素尺寸大小

偏移量

元素的可见大小由其内容,内边距,滚动条和边框大小决定,并不包括外边距。有下面4个属性:

  • offsetHeight
  • offsetWidth
  • offsetLeft
  • offsetTop

    其中offsetLeft和offsetTop是相对包含它的元素而言的。包含元素的引用保存在offsetParent中,这个并不一定是元素的父节点,而是父节点中第一个有大小的元素,比如td的就是table而不是tbody。

    由于这里的偏移都是基于父元素的,想要获得绝对偏移就需要迭代父元素。

    偏移量属性只读,每次读取时是现计算的。代价比较大,最好保存起来用。

//获得元素绝对上偏移
function getElementTop(element){
    var actualTop = element.offsetTop;
    var current = element.offsetParent;
    while (current !== null){
        actualTop += current. offsetTop;
        current = current.offsetParent;
    }
    return actualTop;
}

客户区大小

clientWidth、clientHeight包括内边距和内容

滚动大小

  • scrollHeight:元素内容真正的高度
  • scrollWidth:真正的宽度
  • scrollLeft:被隐藏的内容区域左侧的像素数
  • scrollTop:顶部的

    scrollLeft和scrollTop都可以设置,用来自动滚动元素。

    确定元素大小

    每个元素有个方法:getBoundingClientRect()

    这个方法返回一个矩形对象,包含 4个属性left,top,right,bottom。不过有个小问题,IE8及以前的版本会认为文档左上角的坐标是(2,2),其他的都是正常的(0,0)。

    还有就是有的老浏览器可能不支持这个方法,使用之前的getElementLeft()函数得到left,再加加offsetWidth得到right。

function getBoundingClientRect(element){
    var scrollTop = document.documentElement.scrollTop;
    var scrollLeft = document.documentElement.scrollLeft;
    //在支持getBoundingClientRect方法的情况下
    if (element.getBoundingClientRect){
        //这里利用了函数自身的属性,如果这个函数刚才已经执行过了。arguments.callee.offset就已经存在了
        //就说明这个浏览器的调整量已经设置过了,直接使用就好了。就不必执行下面这个开销比较大的代码块了
        if (typeof arguments.callee.offset != "number"){
            //利用一个新元素,将他设置在浏览器的左上角,再获取它的top值
            //看看这个浏览器的偏差是多少,反向减掉
            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
        };
    //在支持getBoundingClientRect方法的情况下,使用之前的getElementLeft()函数得到left,再加加offsetWidth得到right
    //这个方法可能不太准确,不过谁叫你不支持getBoundingClientRect的
    } 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
        }
    }
}
var rect = getBoundingClientRect(document.getElementById("myDiv"));
alert(rect.bottom);
alert(rect.top);
alert(rect.left);
alert(rect.right);

遍历

DOM2级遍历和范围模块定义了两个用于辅助完成顺序遍历DOM结构的类型。NodeIterator和TreeWalker。这两个类型能够基于给定的节点进行深度优先遍历。IE不支持。

检测兼容:

var supportsTraversals = document.implementation.hasFeature("Traversal", "2.0");
var supportsNodeIterator = (typeof document.createNodeIterator == "function");
var supportsTreeWalker = (typeof document.createTreeWalker == "function"); 

NodeIterator

document.createNodeIterator()来创建,这个方法有4个参数:

  • root:搜索起点
  • whatToShow:要遍历那些类型的节点 ‰
  • filter:NodeFilter对象,或者表示接受还是拒绝某种节点的函数
  • entityReferenceExpansion:在HTML中没啥用

whatToShow通过应用一个或多个过滤器来确定要访问哪些节点。位掩码。

  • NodeFilter.SHOW_ALL
  • NodeFilter.SHOW_ELEMENT
  • NodeFilter.SHOW_ATTRIBUTE
  • NodeFilter.SHOW_TEXT
  • NodeFilter.SHOW_CDATA_SECTION
  • NodeFilter.SHOW_ENTITY_REFERENCE
  • NodeFilter.SHOW_ENTITYE
  • NodeFilter.SHOW_PROCESSING_INSTRUCTION
  • NodeFilter.SHOW_COMMENT
  • NodeFilter.SHOW_DOCUMENT
  • NodeFilter.SHOW_DOCUMENT_TYPE
  • NodeFilter.SHOW_DOCUMENT_FRAGMENT
  • NodeFilter.SHOW_NOTATION
var whatToShow = NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT; 
var filter = {
    acceptNode: function(node){
        return node.tagName.toLowerCase() == "p" ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
    }
};
//直接定义函数也行
// var filter = function(node){
//     return node.tagName.toLowerCase() == "p" ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
// };
var iterator = document.createNodeIterator(document.documentElement, NodeFilter.SHOW_ELEMENT, filter, false);
//或者遍历所有节点
iterator = document.createNodeIterator(document, NodeFilter.SHOW_ALL, null, false);
var node = iterator.nextNode();
while (node !== null) {
    alert(node.tagName);
    node = iterator.nextNode();
}

NodeIterator的两个方法是nextNode()和previousNode(),在遍历到头的时候,这两个方法返回null。

TreeWalker

TreeWalker是高级的NodeIterator:

  • parentNode() ‰
  • firstChild() ‰
  • lastChild() ‰
  • nextSibling() ‰
  • previousSibling()
  • nextNode()
  • previousNode()

创建和NodeIterator接受一样的参数,不过过滤器在这里有些不同,有3种返回值:NodeFilter.FILTER_SKIP、NodeFilter.FILTER_REJECT、NodeFilter.FILTER_ACCEPT。reject会跳过该节点及其子树,skip就单单跳过这个节点。

var walker = document.createTreeWalker(document.documentElement, NodeFilter.SHOW_ELEMENT, null, false);
walker.firstChild();
walker.nextSibling();
var node = walker.firstChild();
while (node !== null) {
    alert(node.tagName);
    node = walker.nextSibling();
}

它还有一个currentNode属性,表示上一次遍历的节点,这个属性可以设置,就改变了继续遍历的起点。

IE啥都不支持

范围

范围用来选择文档中的一个区域而不必考虑节点的界限。在常规的DOM操作不能更有效的修改文档时,范围往往可以实现目的。除IE外都支持,IE8及以前有自己的实现方式。

DOM中的范围(除IE8及以下浏览器外支持的范围)

使用createRange()方法创建DOM范围。新创建的范围与创建它的文档相关联,不能用于其它文档。在创建了范围并设置了其位置之后,可以针对范围的内容实现多种操作,从而实现对底层DOM树的更精细的控制。

每个范围由一个Range类型的实例表示,这个实例由很多属性和方法,下列属性提供了当前范围在文档中的位置信息。

  • startContainer:包含范围起点的节点,也就是选区中第一个节点的父节点
  • startOffset:范围在startContainer中起点的偏移量。如果startContainer是文本节点、注释节点或CDATA节点,那么startOffset就是范围起点之前跳过的字符数量。否则就是范围中第一个子节点在父节点(startContainer)中的索引
  • endContainer:包含范围终点的节点
  • endOffset:范围在endContainer中终点的偏移量
  • commonAncestorContainer:startContainer和endContainer共同的祖先节点在文档树中位置最深的那个

用DOM范围实现简单选择

selectNode()、selectNodeContents()

这两个方法都接受一个DOM节点作为参数,然后使用该节点中的信息来填充范围,selectNode()选择整个节点包括子节点;selectNodeContents()只选择节点的子节点。

<body>
    <div id="myDiv" data-appId="12345" data-myname="Nicholas">
        哈哈哈我在div里
        <span>测试Span</span>
        <a>我是一个a标签~~~~~</a>
    </div>
</body>
var range1 = document.createRange();
var range2 = document.createRange();
var div = document.getElementById("myDiv");
range1.selectNode(div);
range2.selectNodeContents(div);
alert(range1.startContainer.tagName); //body
alert(range1.endContainer.tagName); //body
alert(range1.commonAncestorContainer.tagName); //body
alert(range1.startOffset); //这个div在body中的索引哦,1
alert(range1.endOffset); //startOffset+1,因为只选择了一个节点
alert(range2.startContainer.tagName); //div
alert(range2.endContainer.tagName); //div
alert(range2.commonAncestorContainer.tagName); //div
alert(range2.startOffset); //永远都是0
alert(range2.endOffset); //子节点数目

如果想要更精细的控制,有下面这些方法:

  • setStartBefore(refNode):将范围起点设置在refNode之前,refNode就成为了范围中第一个节点。startContainer会被设为refNode.parentNode,startOffset会被设成refNode在其父节点childNodes中的索引。
  • setStartAfter(refNode)
  • setEndBefore(refNode)
  • setEndAfter(refNode)

用DOM范围实现复杂选择

setStart()和setEnd()

这两个方法接受两个参数:一个参照节点和一个偏移量值。setStart()的参照节点会变成startContainer,偏移量会变成startOffset;setEnd()同理。

var div = document.getElementById("myDiv");
var textNode = div.childNodes[1].firstChild;
var worldNode = div.lastChild;
var range = document.createRange();
range.setStart(textNode, 4);
range.setEnd(worldNode, 0);
alert(range);  //an /n 我是一个a标签~~~~~

操作DOM范围中的内容

创建范围时,内部会为这个范围创建一个文档片段,范围所属的所有节点都会被添加到这个文档片段中,为了创建这个文档片段,范围的格式必须正确有效,这就意味着要有正确的DOM结构,但是像我们刚才那样选择,起始和结束都在一个节点的内部,这样的DOM结构并不正确。不过范围知道自己缺少哪些标签,并重新构建有效的DOM结构。不过在你真正对DOM做出修改之前,范围是不会修改DOM结构的,也确实没必要。

在创建了范围之后,就可以使用各种方法对范围的内容进行操了,表示范围的内部文档片段中所有节点都只是指向文档中相应节点的指针

  • deleteContents():删除范围中所包含的内容。
  • extractContents():同样是删除,只不过会返回范围的文档片段。可以将其插入其他地方。
  • cloneContents():复制内容
var fragment = range.extractContents();
document.getElementById("myButton").parentNode.appendChild(fragment);

插入DOM范围中的内容

对于这里的方法要注意,范围并不会在使用这里的方法的时候自动创建有效的DOM结构,这对insertNode()的影响不大,但是对 surroundContents()就有影响了,因为这很可能出现错乱的DOM结构。

insertNode()方法在范围选区的开始插入一个节点

var span = document.createElement("span");
span.style.color = "red";
span.appendChild(document.createTextNode("Inserted text"));
range.insertNode(span);

surroundContents()环绕范围插入节点,后台会做这些事情:

  1. 提取范围中的内容
  2. 将给定节点插入到文档中原来范围所在位置
  3. 将文档片段内容添加到给定节点中

如果你选中的是像之前那样不完整的DOM节点。。。那这里就会添加失败。。。这里范围不会自己创建有意义的DOM结构

var div = document.getElementById("myDiv");
var textNode = div.childNodes[1].firstChild;
var range = document.createRange();
range.selectNode(textNode);
var span = document.createElement("span");
span.style.backgroundColor = "yellow";
range.surroundContents(span);
alert(range);

折叠DOM范围

collapse()

折叠后的范围不选择文档的任何部位,传入true可以折叠到范围起始位置,false折叠到范围结束位置。通过范围的collapsed可以检测是否折叠,这个属性就是检测范围的起始和结尾是不是同一个位置,如果是,就算不是使用collapse()折叠的也会返回true。这个可以用来检测范围是不是空的。

比较DOM范围

compareBoundaryPoints()

比较两个范围是否有公共起点和终点

alert(range1.compareBoundaryPoints(Range.START_TO_START, range2)); 

Range.START_TO_START(0) ‰比较起点

Range.START_TO_END(1) ‰ 第一个的起点和第二个的终点

Range.END_TO_END(2) ‰

Range.END_TO_START(3)

第一个点在第二个前面-1,相等0,后面1。

复制DOM范围

var newRange = range.cloneRange(); 

清理DOM范围

range.detach();      //从文档中分离
range = null;        //解除引用 

IE8及更早版本中的范围

IE8以及之前的版本不支持DOM范围,但是支持一种文本范围。

可以在文档和元素上创建文本范围,在元素上创建的文本范围只能在本元素内使用。

var range = document.body.createTextRange();  

简单选择

findText()接收一个字符串,可选的传入方向值,返回一个布尔

这个方法会找到第一次出现的给定文本,并将范围移过来环绕该文本。

var range = document.body.createTextRange();
var found = range.findText("我是");
var foundAgain = range.findText("我是", 1);
alert(found);           //true
alert(range.text);
alert(foundAgain);
alert(range.text);

moveToElementText()接收一个节点,并选择这个节点所有的文本,如果这个元素里有HTML标签,使用htmlText属性可以同时获取到标签和文本。

range.moveToElementText(div);
alert(range.text);
alert(range.htmlText);

parentElement()可以得到选区的父节点

复杂选择

move()、moveStart()、moveEnd()、expand()

这些方法都接收两个参数,移动单位和移动单位的数量,移动单位是字符串:”character”、‰ “word”、‰ “sentence”、”textedit”。

expand(“word”)会将现有的选区里单词不全的选全。

move会先折叠选区,再将范围移动指定的单位数量。然后再moveStart()、moveEnd()手动展开选区。

操作内容

range.text = "Howdy";
range.pasteHTML("<em>Howdy</em>");

折叠范围

collapse()

这个倒是和DOM范围一样。不过检测时要使用boundingWidth、boundingHeight、boundingLeft、boundingTop这些是范围的尺寸信息,以像素为单位,boundingWidth为0就代表范围折叠了。

比较范围

compareEndPoints()

这个是差不多的方法,”StartToStart”“StartToEnd”“EndToEnd”“EndToStart”

range1.compareEndPoints("StartToStart", range2)

还有两个特别的方法:

range1.isEqual(range2)
range1.inRange(range2)

复制IE范围

var newRange = range.duplicate(); 
时间: 2024-10-06 01:39:18

JS学习11(DOM2&DOM3)的相关文章

d3.js学习11

单元素动画transition().duration(duration) var body = d3.select("body"), duration = 5000; body.append("div") .classed("box",true) .style("background-color","#e9967a") .transition() .duration(duration) .style(&qu

js学习总结----DOM2兼容处理顺序问题

解决顺序问题:我们不用浏览器自带的事件池了,而是自己模拟标准浏览器的事件池实现,具体代码如下: /* bind:处理DOM2级事件绑定的兼容性问题(绑定方法) @parameter: curEle->要绑定事件的元素 evenType->要绑定的事件类型("click","mouseover") evenFn->要绑定的方法 */ function bind(curEle,evenType,evenFn){ if('addEventListener

js学习总结----DOM2兼容处理重复问题

在解决this问题之后,只需要在每次往自定义属性和事件池当中添加事件的时候进行一下判断就好了,具体代码如下 /* bind:处理DOM2级事件绑定的兼容性问题(绑定方法) @parameter: curEle->要绑定事件的元素 evenType->要绑定的事件类型("click","mouseover") evenFn->要绑定的方法 */ function bind(curEle,evenType,evenFn){ if('addEventLi

Ext JS学习第五天 Ext_window组件(一)

此文来记录学习笔记 •第一个组件:Ext.window.Window.对于组件,也就是Ext最吸引开发者的地方,那么我们要真正的使用Ext的组件,首先必须学会阅读API文档. –xtype:组件的别名 –Hierarchy 层次结构 –Inherited mixins 混入的类 –Requires 该组件需要使用的类 –configs:组件的配置信息 –properties:组件的属性 –methods:组件的方法 –events:组件的事件 •window组件常用属性和方法讲解: •confi

【转】Backbone.js学习笔记(二)细说MVC

文章转自: http://segmentfault.com/a/1190000002666658 对于初学backbone.js的同学可以先参考我这篇文章:Backbone.js学习笔记(一) Backbone源码结构 1: (function() { 2: Backbone.Events // 自定义事件 3: Backbone.Model // 模型构造函数和原型扩展 4: Backbone.Collection // 集合构造函数和原型扩展 5: Backbone.Router // 路由

Ext JS学习第五天 Ext_window组件(二)

此文用来记录学习笔记 •上一讲我们已经学过了window的使用,那么在这将中,我们将结合然后把Ext中需要注意的地方,以及组建的使用给予介绍.indow做几个Web开发的经典示例. •ExtWeb实战300例: –例1:点击按钮打开一个window,window重复创建的问题 •重点分析:这个问题是初学者经常会犯错的地方,一般来说简单的代码不会产生此问题,但是如果以后代码复杂以后,这个问题如果发生调试起来会非常麻烦!! 附上栗子代码 1 Ext.onReady(function () { 2 3

Ext JS学习第三天 我们所熟悉的javascript(二)

•javascript之函数 •对于Ext开发者,我还是希望你能对javascript原生的东西非常了解.甚至熟练掌握运用.那么函数,无疑是非常重要的概念.首先在前面一讲,我们知道了函数也是一种数据类型,创建函数一共有三种方式.每种方式他们都会有区别,分别为: –function语句形式 –函数直接量形式 –构造函数形式 •函数中的arguments对象 –argument的作用一:接受函数的实际参数 –argument的作用二:用于做递归操作 栗子代码 1 //Function 函数 2 //

Ext JS学习第二天 我们所熟悉的javascript(一)

此文用来记录学习笔记: •ExtJS是一个强大的javascript框架,如果想真正的掌握ExtJS,那么我们必须要对javascript有一定的认识,所以很有必要静下心来,抱着一本javascript书籍,恶补一番.推荐书籍<javascript高级程序设计>.<javascript设计模式>. •在这里我们学习一下可能你从未接触过的javascript,这些javascript知识是我们要学好ExtJS这个框架非常有必要的.必备的知识.我们需要掌握的内容有: –javascri

Node.js学习笔记(3) - 简单的curd

这个算是不算完结的完结吧,前段时间也是看了好久的Node相关的东西,总想着去整理一下,可是当时也没有时间: 现在看来在整理的话,就有些混乱,自己也懒了,就没在整理,只是简单的记录一下 一.demo的简单介绍 这次demo,只涉及到简单的curd操作,用到的数据库是mongo,所以要安装mongo数据库,数据库连接驱动是mongoose: 当然关于mongo的驱动有很多,比如mongous mongoskin等:(详见http://cnodejs.org/topic/4f4ca8e0940ce2e