JS高级程序设计-第十二章:DOM2和DOM3

DOM1级主要定义的是HTML和XML文档的底层结构。2和3在此基础上引入了更多的交互能力,支持更高级的XML特性。
样式
HTML中有三种定义样式的方法:通过link元素包含外部样式文件,style元素定义嵌入式,style特性定义特定元素的样式。

var div = document.getElementById('mydiv');
        //通过div的style属性设置背景颜色
        div.style.backgroundColor = 'pink';
        //改变div的大小
        div.style.width = '200px';
        div.style.height = '100px';
        //指定边框
        div.style.border = "1px solid black";

        //通过访问cssText属性可以访问style特性中的CSS代码,也可以通过它重写样式
        div.style.cssText = "width: 400px; height: 200px; background-color: green";
        // console.log(div.style.cssText);
        //迭代取出元素中定义的css属性名和值
        for (let i = 0, len = div.style.length; i < len; i++) {
            // console.log(div.style[i]);
            prop = div.style[i];
            value = div.style.getPropertyValue(prop);
            console.log(prop + ": " + value);
        }

样式的计算
当同时使用多种CSS样式定义方式时,比如,style元素定义嵌入式和style属性同时使用,需要计算出最终执行的CSS样式,DOM2级提供了getComputedStyle的方法,

       var computedStyle = document.defaultView.getComputedStyle(div, null);
        console.log(computedStyle.backgroundColor);
        console.log(computedStyle.width);

操作样式标
文档的所有样式表都可以通过document.styleSheets集合来获取,可以通过length属性获得文档中样式表的数量,href属性获得link标签中的url,
在这里插入图片描述
CSSRule对象表示样式表中的每一条规则, 该对象中最常用的三种属性为:cssText属性,返回整条规则对应的文本,只读;selectorText返回当前规则的选择符文本;style 可以通过设置它取得规则中特定的样式。
在这里插入图片描述
还可以向样式表中添加新规则,使用insertRule方法,使用deleteRule删除规则。
offsetHeight, offsetWidth, offsetLeft, offsetTop四个属性可以用来确定元素的大小。
遍历DOM
NodeIterator 和 TreeWalker 两种方法都可以遍历DOM结构。前者较为简单,只允许以一个节点的步幅前后移动,后者为前者的高级版本,支持在DOM结构的各个方向上移动,包括父节点,同辈节点和子节点。

      //想要遍历div标签中的所有元素
        let div = document.getElementById('div1');
        let iterator = document.createNodeIterator(div, NodeFilter.SHOW_ELEMENT, 
                        null, false);
        let node = iterator.nextNode();
        while (node !== null) {
            console.log(node.tagName);
            node = iterator.nextNode();  
        }

        //只返回遇到的Li元素,设置filter函数,判断tagName是否是li来判断接受还是拒绝
        let filter = function(node) {
            return node.tagName.toLowerCase() == "li" ? 
                   NodeFilter.FILTER_ACCEPT:
                   NodeFilter.FILTER_SKIP;
        }
        let iterator1 = document.createNodeIterator(div, NodeFilter.SHOW_ELEMENT,
                        filter, false);
        let node1 = iterator1.nextNode();
        while (node1 !== null) {
            console.log(node1.tagName);
            node1 = iterator1.nextNode();
        }

范围
DOM2级还定义了范围接口,Document类型中的createRange()方法,可以自由选取文档中的一个区域,有简单选择和复杂选择两种方式。selectNode和selectNodeContents实现范围的简单选取,setStart和setEnd实现范围的复杂选取。

        //selectNode 和 selectNodeContents方法实现范围的简单选取
        let range1 = document.createRange(),
            range2 = document.createRange(),
            p1 = document.getElementById('p1');
        range1.selectNode(p1),
        range2.selectNodeContents(p1);
        console.log(range1);
        
        //setStart和setEnd实现复杂选取
        let range1 = document.createRange(),
            range2 = document.createRange(),
            p1 = document.getElementById('p1'),
            p1Index = -1,
            i, len;
        // console.log(p1.parentNode.childNodes);
        //找到p1元素在父节点上所在的顺序
        for (i = 0, len = p1.parentNode.childNodes.length; i < len; i++) {
            if (p1.parentNode.childNodes[i] == p1) {
                p1Index = i;
                break
            }
        }  
        //选择这个节点  
        range1.setStart(p1.parentNode, p1Index);
        range1.setEnd(p1.parentNode, p1Index + 1);
        //选择
        range2.setStart(p1, 0);
        range2.setEnd(p1, p1.childNodes.length); 
        
        //选择 hello 的 llo 到 world 中的 o
        //p1元素子节点b元素的子节点  文本节点
        let helloNode = p1.firstChild.firstChild;
        // console.log(helloNode);
        let worldNode = p1.lastChild;
        //p1元素最后一个子节点  文本节点
        // console.log(worldNode);
        let range3 = document.createRange();
        //hello文本节点的第二位
        range3.setStart(helloNode, 2);
        //world文本节点的第三位
        range3.setEnd(worldNode, 3);
        // console.log(range3);

操作DOM范围中的内容
还可以操作DOM范围中的内容,比如deletContents(删除),extractContents(选取), insertNode(插入节点)

        //操作DOM范围中的内容
        let fragment = range3.extractContents();
        console.log(fragment);  //返回一个文档片段
        // range3.deleteContents();  //页面显示会改变
        //还可以将返回的文档片段插入到文档中的其他地方
        p1.parentNode.appendChild(fragment)

       //还可以向DOM范围中插入内容,比如在此插入span标签
       let span = document.createElement("span");
       span.style.color = 'red';
       //向span标签中插入文本节点
       span.appendChild(document.createTextNode("Inserted text"));
       //span节点插入到range3范围开始的地方
       range3.insertNode(span);
       //还可以选择环绕范围插入一些内容,使用surroundContents方法
       //以下例子给所选范围添加黄色背景
       let range4 = document.createRange();
       range4.selectNode(helloNode);
       let span1 = document.createElement('span');
       span1.style.backgroundColor = 'yellow';
       range4.surroundContents(span1)

折叠DOM范围
折叠范围,指范围中未选择文档的任何部分。一般使用collapse方法来折叠范围。检测某个范围是否处于折叠状态,可以帮助确认范围中的两个节点是否紧密相连:

    //确定两个节点是否紧密相连
    let p1 = document.getElementById('p1'),
        p2 = document.getElementById('p2'),
        range = document.createRange();
    range.setStartAfter(p1);
    range.setEndBefore(p2);
    console.log(range.collapsed);   //true 两个节点紧密相连

除此之外还可以比较,复制,清理DOM范围。在IE8及更早的版本不支持range对象,但是有类似的概念,即文本范围 textrange,也可以实现范围的选择,操作,折叠,复制,比较。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值