js --dom

1.获取属性

var div=document.getElementById("roboth"); 
alert(div.attributes.getNamedItem("id").nodeValue); 
alert(div.attributes.item(0).nodeValue); 
alert(div.getAttributeNode("id").nodeValue); 
alert(div.getAttribute("id"));

2.获取子元素

在Javascript中,可以通过 children 来获取所有子节点
children只返回HTML节点,甚至不返回文本节点,虽然不是标准的DOM属性,但是得到了几乎所有浏览器的支持。

另外,在W3C规范中,是通过 childNodes 来获取子节点的,它是一个标准属性,返回指定元素的子节点的集合,包括HTML节点、文本节点、注释节点等,比 children 返回的节点类型更加广泛。

Paste_Image.png
var getChildNodes=function(ele){
   var childArr=ele.children || ele.childNodes,
         childArrTem=new Array();  //  临时数组,用来存储符合条件的节点
    for(var i=0,len=childArr.length;i<len;i++){
        if(childArr[i].nodeType==1){
            childArrTem.push(childArr[i]);
        }
    }
    return childArrTem;
}

在Javascript中,可以通过 firstChild 来获取第一个子节点。语法: nodeObject.firstChild其中,nodeObject 为节点对象(元素节点)。

"第一个子节点:"+this.firstChild+"\n"+
"第一个子节点的类型是:"+this.firstChild.nodeType+"\n"+
"第一个子节点的名称是:"+this.firstChild.nodeName
在IE8.0及其以下版本的浏览器中,显示: 
   第一个子节点:[object HTMLDivElement]  
   第一个子节点的类型是:1   
   第一个子节点的名称是:DIV
在Chrome、Opera、Safari、FireFox下,显示:  
  第一个子节点:[object text]    
  第一个子节点的类型是:3  
  第一个子节点的名称是:#text

在Javascript中,可以通过 lastChild 来获取最后一个子节点。
在Javascript中,可以通过 hasChildNodes() 方法来判断是否存在子节点。

2.3previousSibling 获取兄弟元素

通过 nextSibling 来获取下一个节点。
在IE下,会忽略节点间的空白节点(空格、回车和Tab键);在遵循W3C规范的浏览器(Chrome、FireFox、Safari等)下则不会。

3.获取父节点

获取已知节点的父节点请使用 parentNode 。
语法:   
 nodeObject.parentNode其中,nodeObject 为节点对象(元素节点)。

4.JavaScript获取节点类型、节点名称和节点值

DOM节点信息包括节点类型(nodeType)、节点名称(nodeName)和节点值(nodeValue)。
W3C规范中常用的 DOM节点类型有以下几种:

Paste_Image.png

节点名称

Paste_Image.png

对于文本节点,节点值为文本内容;
对于属性节点,节点值为属性的值。
节点值对于文档节点和元素节点是不可用的。

5.Javascript获取DOM节点

1)getElementById( )方法
2)getElementsByTagName( )方法

6.改变css样式

<script type="text/javascript">
document.getElementById("demo").onclick=function(){
this.style.height = " 70px ";
this.style.lineHeight = " 70px ";
this.style.backgroundColor = " #000 ";
this.style.color=" #fff ";
}
</script>

7.根据类名获取元素

// 根据类名获取元素
function getElementsByClass(oParent,sClass){
    var aResult = [];
    var aNode = oParent.getElementsByTagName("*");
    for(var i=0; i<aNode.length; i++){
        if(aNode[i].className == sClass){
            aResult.push(aNode[i]);
        }
    }
    return aResult;
}

8. removeChild():删除节点

<div id="demo">
    <div id="thisNode">点击删除我</div>
</div>
<script type="text/javascript">
document.getElementById("thisNode").onclick=function(){
    this.parentNode.removeChild(this);
}
</script>

9. 克隆节点 nodeObject.cloneNode(boolean)

Paste_Image.png
<div id="demo">
    <div>点击这里进行克隆</div>
    <div>节点</div>
    <div>节点</div>
</div>
<script type="text/javascript">
document.getElementById("demo").onclick=function(){
    alert(this.cloneNode(true).children.length);
}
</script>

10.**createDocumentFragment() **方法用来创建一个文档碎片节点。

每一次DOM节点的添加、删除和移动操作都会引起浏览器重新渲染HTML文档,如果这样的操作过多,不仅会浪费资源,可能还会出现“闪屏” 的现象。

<div id="demo">
    <div>点击这里添加新节点</div>
</div>
<script type="text/javascript">
document.getElementById("demo").onclick=function(){
    var divFragment=document.createDocumentFragment(),
        div1=document.createElement("div"),
        div2=document.createElement("div"),
        div3=document.createElement("div");
    div1.appendChild(document.createTextNode("这是新节点 1"));
    div2.appendChild(document.createTextNode("这是新节点 2"));
    div3.appendChild(document.createTextNode("这是新节点 3"));
    divFragment.appendChild(div1);
    divFragment.appendChild(div2);
    divFragment.appendChild(div3);
   
    this.appendChild(divFragment);
}
</script>

11.innerHTML

( 1 ) innerHTML可以向指定的节点直接插入HTML代码。
( 2 ) 另外,也可以通过 innerHTML 来获取指定节点内部的HTML代码。

12.添加节点

insertBefore()
在指定节点的前面插入新节点
appendChild()
在指定节点的最后插入新的子节点(原来的子节点不变)
语法: parentNode.insertBefore(newNode , thisNode)
js没有提供在指定节点的后面插入节点

/**
  * func    insertAfert    在指定节点的后面插入节点
  * pram    newNode    要添加的新节点
  * pram    thisNode    当前节点(指定节点)
**/
function insertAfter(newNode, thisNode){
    var parent = thisNode.parentNode;
    if (parent.lastChild == thisNode) {
        // 如果父节点的最后一个节点是指定节点,则直接添加
        parent.appendChild(newNode);
    }else {
        parent.insertBefore(newNode , thisNode.nextSibling);
        //如果不是,则在指定节点的下一个节点前面插入
    }
}

/**
  * func    appendChildPre    在指定节点的前面插入子节点
  * pram    parent    父节点
  * pram    newNode    要添加的新节点
**/
function appendChildPre(parent , newNode){
    if(parent.length>=1){
        // 如果存在子节点,则在第一个子节点的前面添加
        parent.insertBefore(newNode , parent.firstNode);
    }else{
        // 如果不存在,则在最后添加
        parent.appendChild(newNode);
    }
}

13.创建节点

createElement() 创建一个元素节点
createTextNode()    创建一个文本节点
createComment() 创建一个文本节点
createDocumentFragment()    创建文档碎片节点

createElement()
createElement()用来创建一个元素节点,即 nodeType=1 的节点。

var ele_div=document.createElement("div");
var ele_p=document.createElement("p");

createComment()
reateComment()用来创建一个注释节点,即 nodeType=8 的节点。语法: document.createComment(comment)其中,comment 为注释的内容,并将返回一个节点对象。

var ele_comment=document.createComment(" 这是一个注释节点 ");

获取元素的尺寸

1.元素尺寸与位置

1. clientHeight和clientWidth用于描述元素内尺寸,是指 元素内容
    +内边距 大小,不包括边框(IE下实际包括)、外边距、滚动条部分
2. offsetHeight和offsetWidth用于描述元素外尺寸,是指 元素内容
    +内边距+边框,不包括外边距和滚动条部分
3. clientTop和clientLeft返回内边距的边缘和边框的外边缘之间的水
   平和垂直距离,也就是左,上边框宽度
4. offsetTop和offsetLeft表示该元素的左上角(边框外边缘)与已定
    位的父容器(offsetParent对象)左上角的距离
5. offsetParent对象是指元素最近的定位(relative,absolute)祖先元
    素,递归上溯,如果没有祖先元素是定位的话,会返回null
```
```
<div id="divParent" style="padding: 8px; background-color: #aaa; position: relative;">
        <div id="divDisplay" style="background-color: #0f0; margin: 30px; padding: 10px;
            height: 200px; width: 200px; border: solid 3px #f00;">
        </div>
    </div>
```
```
<script type="text/javascript">
        var div = document.getElementById('divDisplay');

        var clientHeight = div.clientHeight;
        var clientWidth = div.clientWidth;
        div.innerHTML += 'clientHeight: ' + clientHeight + '<br/>';
        div.innerHTML += 'clientWidth: ' + clientWidth + '<br/>';

        var clientLeft = div.clientLeft;
        var clientTop = div.clientTop;
        div.innerHTML += 'clientLeft: ' + clientLeft + '<br/>';
        div.innerHTML += 'clientTop: ' + clientTop + '<br/>';

        var offsetHeight = div.offsetHeight;
        var offsetWidth = div.offsetWidth;
        div.innerHTML += 'offsetHeight: ' + offsetHeight + '<br/>';
        div.innerHTML += 'offsetWidth: ' + offsetWidth + '<br/>';

        var offsetLeft = div.offsetLeft;
        var offsetTop = div.offsetTop;
        div.innerHTML += 'offsetLeft: ' + offsetLeft + '<br/>';
        div.innerHTML += 'offsetTop: ' + offsetTop + '<br/>';

        var offsetParent = div.offsetParent;
        div.innerHTML += 'offsetParent: ' + offsetParent.id + '<br/>';
    </script>
```

![Paste_Image.png](http://upload-images.jianshu.io/upload_images/2061490-cd9ff23bfa380f99.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

![Paste_Image.png](http://upload-images.jianshu.io/upload_images/2061490-4aa6e531a2e2b3cf.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
####2.当我们计算一个DOM元素位置也就是坐标的时候,会涉及到两种坐标系,**文档坐标**和**视口坐标**。
为了在坐标系之间进行转换,我们需要判定浏览器窗口的滚动条位置。window对象的pageXoffset和pageYoffset提供这些值,IE 8及更早版本除外。也可以通过scrollLeft和scrollTop属性获得滚动条位置,**正常情况下通过查询文档根节点(document.documentElement)来获得这些属性值,但在怪异模式下必须通过文档的body上查询。**
```
function getScrollOffsets(w) {
            var w = w || window;
            if (w.pageXoffset != null) {
                return { x: w.pageXoffset, y: pageYoffset };
            }
            var d = w.document;
            if (document.compatMode == "CSS1Compat")
                return { x: d.documentElement.scrollLeft, y: d.documentElement.scrollTop };
            return { x: d.body.scrollLeft, y: d.body.scrollTop };
        }
```
有时候能够判断视口的尺寸也是非常有用的
```
function getViewPortSize(w) {
            var w = w || window;
            if (w.innerWidth != null)
                return { w: w.innerWidth, h: w.innerHeight };
            var d = w.document;
            if (document.compatMode == "CSS1Compat")
                return { w: d.documentElement.clientWidth, h: d.documentElement.clientHeight };
            return { w: d.body.clientWidth, h: d.body.clientHeight };
        }
```
**文档坐标**
```
function getElementPosition(e) {
            var x = 0, y = 0;
            while (e != null) {
                x += e.offsetLeft;
                y += e.offsetTop;
                e = e.offsetParent;
            }
            return { x: x, y: y };
        }
```
这个函数也不总是计算正确的值,当文档中含有滚动条的时候这个方法就不能正常工作了,我们只能在没有滚动条的情况下使用这个方法,不过我们用这个原理算出一些元素相对于某个父元素的坐标

**视口坐标**
计算**视口坐标**就相对简单了很多,可以通过调用**元素**的**getBoundingClientRect**方法。方法返回一个有left、right、top、bottom属性的对象,分别表示元素四个位置的相对于视口的坐标。**getBoundingClientRect所返回的坐标包含元素的内边距和边框**,不包含外边距。兼容性很好,非常好用
**元素尺寸**
由上面计算坐标方法,我们可以方便得出元素尺寸。在符合W3C标准的浏览器中getBoundingClientRect返回的对象还包括width和height,但在原始IE中未实现,但是通过返回对象的right-left和bottom-top可以方便计算出。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容

  • 翻译自:高性能Javascript 第三章Dom操作是昂贵的,它通常是web应用的性能瓶颈。这篇文章讨论Dom操作...
    Addy_Zhou阅读 2,953评论 0 5
  • 原文地址:https://www.sitepoint.com/dom-manipulation-vanilla-j...
    杜伊特阅读 1,107评论 1 8
  • DOM(文档对象模型)是针对HTML和XML文档的一个API。其描述的是一种层次化的节点树。为基本的文档结构和查询...
    FeRookie阅读 354评论 0 1
  • 关于DOM的内容实在是太丰富了,前面我们简单的介绍了DOM中关于DOM特性和内容还有DOM节点相关的知识点。其实主...
    FeRookie阅读 331评论 0 2
  • 青岛没有北京上海等大都市气派和经济飞速的发展; 青岛没有西安古都的历史悠久记载人类文明的进步; 青岛没有成都火锅和...
    读娘阅读 650评论 0 0