DOM基础操作

134 阅读10分钟

DOM

获取的DOM元素命名规范

前缀 o only 获取单一节点对象

querySelector getElmentById

前缀 a all DOM节点集和 NodeList集和 v view 临时

DOM节点

DOM API 节点对象选择器

通过以下方法可以获取DOM节点对象

var oHeader = document.getElementById('header');
//获取ID名称为 header 的标签 返回对应的节点对象(单个) 如果文档内有多个 ID名称为 header 的标签 只获取第一个var aP = document.getElementsByTagName('p');
//获取文档内的所有 p 标签 返回一个 DOM集合(NodeList) 类数组对象 哪怕没有找到只有一个也返回类数组集合var aDes = document.getElementsByClassName('des'); //IE9
//获取文档内的所有类名为 des 的标签 返回一个 DOM集合(NodeList) 类数组对象 哪怕没有找到只有一个也返回类数组集合// 输入的值 需要区分id class 和标签 . #
var oHeader = document.querySelector('#header'); 
//querySelector是H5 新增的DOM API 参数使用合法的css选择器即可  返回复合条件的第一个元素 (唯一)var aDes = document.querySelectorAll('.des');
//querySelectorAll是H5 新增的DOM API 参数使用合法的css选择器即可  返回复合条件的节点集合 类数组对象(非唯一)
​
​
var html =document.documentElement -> html标签
var head =document.head ->head标签
var body = document.body; //直接获取body节点对象

DOM API 获取节点内容

获取节点内容主要掌握 获取节点文本内容 获取实际内容两种

  1. innerHTML

    获取元素内部的HTML结构

    可以直接给这个属性重新赋值,达到修改页面的效果

  2. innerText

获取元素内的文本(只能获取到文本,获取不到html结构)

可以直接给这个属性赋值,达到修改页面的效果

console.log(oHeader.innerHTML); //获取标签内的实际内容(包括标签)
//更改内容oHeader.innerHTML = '<p><span>innerHTML</span></p>'//可以识别标签console.log(oHeader.innerText);  //设置标签中间的文本内容,应该使用innerText属性,谷歌火狐支持,ie8支持  
只能识别内容,不能识别标签
box.innerText = '<p><span>innerHTML</span></p>' //无法识别标签console.log(oHeader.textContent); //设置标签中间的文本内容,应该使用textContent属性,谷歌火狐支持,ie8不支持
​
​
//textContent 与 innerText兼容处理
function getInnerText(element) {
    if(typeof element.textContent=="undefined"){
        return element.innerText;
    }else{
        return element.textContent;
    }
}
​

获取元素属性

DOM API 获取标签属性

通过以下方法可以获取DOM元素的属性(不包括样式(style)

方式一

1.获取元素的某些属性

语法: 元素.getAttibute('要查询的属性名')

2.修改元素属性

语法:元素.setAttribute('对应属性名',’对应的属性值)

如果修的属性没有 默认新增一个

3.删除元素的某些属性

语法:元素.removerAttribute('属性名')

4.节点属性对象 拥有长度属性 可以获取节点全部属性名

语法:元素.attributes

5.判断节点对象是否含有 某个 属性

console.log(aImg.hasAttribute('src'));

方式二

元素.属性名

两者区别

//getAttribute拿到的是标签的属性值 未处理的 是多少就是多少

//元素.属性 拿到的是元素对象的属性值 处理过的 (比如图片位置 相对路径变成了网址) 不可以操作自定义属性

//  var box = document.querySelector('.box')
var box = document.getElementsByClassName('box')[0]//输出的是伪数组
//document.getElementsByClassName('box')[0] 这才是拿到第一个标签 通过下标console.log(box2)
/*
  1.获取元素的某些属性
  语法: 元素.getAttibute('要查询的属性名')
*/
console.log(box.getAttribute('a'))//100
console.log(box.getAttribute('class'))//boxconsole.log(box.getAttribute('b'))//没有显示null 
/*
 2.修改元素属性
 语法:元素.setAttribute('对应属性名',’对应的属性值)
 如果修的属性没有 默认新增一个
 */
box.setAttribute('a','99999')
console.log(box.getAttribute('a'))//9999
box.setAttribute('b','99999')
 console.log(box.getAttribute('b'))
​
/*
 3.删除元素的某些属性
 语法:元素.removerAttribute('属性名')
 */
var oHeader = document.getElementById('header');
var aImg = document.getElementsByTagName('img');
方法一 .语法
console.log(oHeader.attributes); //节点属性对象 拥有长度属性console.log(oHeader.id); //指定属性获取console.log(aImg[0].src);//指定属性获取
​
consol.log(oHeader.className)//类名特殊 需要用className
​
方法二 查看 修改 添加 删除  
//查看
console.log(aImg.getAttribute('src')); //通过 getAttribute方法获取实际 属性值
​
修改添加元素属性
    语法:元素.setAttribute('对应属性名',’对应的属性值)
    如果修的属性没有 默认新增一个
删除元素的某些属性
    语法:元素.removerAttribute('属性名')
​
console.log(aImg.hasAttribute('src')); // 判断节点对象是否含有 某个 属性

自定义属性data

h5 自定义属性

data- 表示属性是一个自定义属性

data- 后边的内容才是属性名 data-a a才是属性名

= 后边的内容是属性值

每一个 元素/DOM节点 天生自带一个属性,叫做dataset,是一个类似对象的数据结构 (页面做了一些运算)

//DOM
    var oDiv = document.querySelector('div')
​
    //1.访问元素的dataset
    console.log(oDiv.dataset)
    //查询
    console.log(oDiv.dataset.a)//100
​
    //2.增加一个H5自定义属性
    oDiv.dataset.age='100'//标签中没有 算新增
​
    //如果属性已经有了 算修改
    oDiv.dataset.a = 666
​
    // //3.删除
    // delete oDiv.dataset.a

DOM API获取元素样式style

DOM样式获取分为获取 行内style样式 和 实际计算后样式两种

//行内样式
console.log(oImg.style); //CSSOM对象
console.log(aImg.style.outline); //标签行内样式 style属性中存在的样式的值

//实际样式  只读属性 不能更改 不区分行内和非行内
//语法:元素.getComputedStyle(obox)(元素名).属性名
console.log(window.getComputedStyle(oImg, null)['border']); 
console.log(window.getComputedStyle(obox).width)

//主流浏览器 
console.log(oImg.currentStyle['border']); //老版本IE(了解即可)

//兼容函数写法
function getStyle(obj, attr) {
    return obj.currentStyle ? obj.currentStyle[attr] : getComputedStyle(obj, false)[attr];
}

语法:元素.style.某个属性

注意:

1.我们也可以给这个语法重新赋值,达到修改元素样式的效果

2.这种语法获取到的元素样式,只能获取到行内样式

获取元素 获取的是行内样式的

console.log(obox.style.width)
console.log(obox.style.height)
​
////有-的属性 在js中需要改变写法
console.log(obox.style['backgroundColor']) 
console.log(obox.style.backgroundColor)

修改 也是行内样式

obox.style.width = 200+'px'

获取类名className

专门用来操作元素的类名

语法:元素.className

也可以重新给他赋值,但会覆盖前边的类名

 obox.className = 'box1'
​
 console.log(obox.className)

获取非行内样式getComputedStyle

语法:元素.getComputedStyle(obox)(元素名).属性名

不仅可以获取非行内 还可以获取行内

获取到的值 只能读 不能修改

  window.getComputedStyle(obox).width
  //语法:元素.getComputedStyle(obox)(元素名).属性名
  console.log(window.getComputedStyle(obox).width)

获取元素类名classList

专门用来操作元素的类名

语法:元素.className

可以重新赋值,会把原有的类名全都覆盖掉

2.classlist

获取 元素.classList

追加 元素.classlist.add('类名')

删除 元素.classlist.remove('类名')

切换 元素.classlist.toggle('类名')

//获取元素
    var obox = document.querySelector('.box')
    console.log(obox)
​
    //classlist
    //获取
    console.log(obox.classList)
    //追加
    // obox.classList.add('new2box')
    //删除
    obox.classList.remove('box')
    //切换 没有就加上 有就删除
    obox.classList.toggle('new2box')
    obox.classList.toggle('newbox')

DOM API 获取节点相关节点

我们可以通过方法获取节点的相关联节点 后代 父亲 兄弟等

element 元素

Node 节点

var oHeader = document.querySelector('div')
语法:元素.方法
​
console.log(oHeader.children); //获取子元素 只有标签
console.log(oHeader.childNodes); //获取子节点 包含文本节点与标签节点
​
console.log(oHeader.firstChild); //获取第一个子节点(包含文本)
console.log(oHeader.firstElementChild); //获取第一个子标签节点
​
​
console.log(oHeader.lastChild); //获取最后一个子节点(包含文本)
console.log(oHeader.lastElementChild); //获取最后一个子标签节点
​
console.log(aP[0].parentElement); //父元素
console.log(aP[0].parentNode); //父节点 都不多 用node就可以
​
console.log(aP[1].nextElementSibling); //下一个兄弟标签节点
console.log(aP[1].nextSibling); //下一个兄弟节点(计算文本节点)
​
​
console.log(aP[2].previousElementSibling); //上一个兄弟标签节点
console.log(aP[2].previousSibling); //上一个兄弟节点(计算文本节点)
​
​
//获取元素的所有属性节点 **(属性节点 属性  节点)
//attributes
oHeader.attributes

DOM节点分类

一般来说我们分为三个大类

元素节点(标签) / 文本节点(标签内的文字) / 属性节点(标签上的属性)

  • 元素节点

    通过 getElementBy... 获取到的都是元素节点

  • 属性节点

    通过 getAttribute 获取到的都是属性节点

  • 文本节点

    通过 innerText 获取到的就是元素的文本节点

DOM节点属性(类型名称值)

元素节点(标签) / 文本节点(标签内的文字) / 属性节点(标签上的属性)

  • nodeType 节点类型

元素.nodeType

节点中的一个属性 nodeType 能够区分当前节点是什么类型

1-> 元素节点

2-> 属性节点

3-> 文本节点

  • nodeName 节点名称

元素节点->大写的标签名 (LI / UL / DIV)

属性节点->text (属性名)

文本节点->#text(对于所有文本节点nodeName都是固定的)

  • nodeValue 节点的值

    元素节点->没有nodeValue 会输出null

    属性节点->对应的属性值

    文本节点->对应的文本内容

 <table>  
    <tr>  
      <td id="Jackie" name="myname">Jackie Z</td>   
    </tr>  
  </table>  
<script>  
//元素节点
    //var d = document.getElementById("Jackie");  //id属性获取
    var d = document.querySelector('#Jackie')
​
    console.log(d.nodeType);
    console.log(d.nodeName);  
    console.log(d.nodeValue) ;  
    /*
     运行结果为:
      nodeType:1
      nodeName:TD
      nodeValue:null
    */
//属性节点
    var d1 = document.getElementById("Jackie").attributes[1]  
    //attributes获取节点全部属性名 类似对象 但有下标
    console.log(d1.nodeType);
    console.log(d1.nodeName);  
    console.log(d1.nodeValue) ; 
    /*
      nodeType:2
      nodeName:name
      nodeValue:myname
    */
//文本节点
    var d2 = document.getElementsByTagName("td")[0].firstChild
    console.log(d2.nodeType);
    console.log(d2.nodeName);  
    console.log(d2.nodeValue) ; 
    /*
      nodeType:3
      nodeName:#text(对于所有文本节点nodeName都是固定的)
      nodeValue:Jackie
    */
 </script>  

DOM API 创建与添加、插入节点标签

通过相关方法可以创建节点 添加节点到HTML文档中

方法- 方法添加

create 创造

createElement 创建

document.createElement('')创建标签节点

appendChild添加

元素.appendChild('新增节点')

append也可以实现h5新增

//创建节点
    var oDiv = document.createElement('div')
    oDiv.innerText = '我是新节点'
    //添加一些样式属性
    oDiv.style.color = 'red'
    oDiv.style.fontSize = '30px'
    //添加节点
    document.body.appendChild(oDiv)
    document.body.append(oDiv); //append 是H5 WEB API    新增方法

方法二 字符串添加(innerHTML)

//方法二 通过innerHTML 添加
//创建
var odivv = '<div class="wrap"><p style = "color:red">我是innerhtml添加</p></div>'
//添加
document.body.innerHTML = odivv

insertBefore()插入

insert插入

在父节点ELE里面的节点A前面添加 新的节点B

//在父节点ELE里面的节点A前面添加 新的节点B
ELE.insertBefore(B,A);
var cP = document.createElement("p"); //创建标签节点
var content = document.createTextNode("你好"); //创建文本节点
cP.appendChild(content); //添加content到cP节点中
document.body.appendChild(cP); //添加cP到body标签中进行渲染
document.body.append(cP); //append 是H5 WEB API 新增方法
---------------------------------------
//通过文本标签方式添加节点
var htmlTxt = '<p>哈哈哈</p>';
document.body.innerHTML += htmlTxt;
//HTML输出流 直接覆盖body中的内容
document.write('<p>123</p>');
​
----------------------------------------
//在父节点ELE里面的节点A前面添加 新的节点B
ELE.insertBefore(B,A);

注意

插入和添加会互相覆盖 尽量不要用两个方法操作同一个节点

DOM API 节点替换拷贝

通过相关方法可以实现 节点拷贝 节点

复制拷贝cloneNode

元素.cloneNode(参数)

传参true代表包括该节点的后代节点 不传参数表示只复制该节点本身

节点替换replaceChild

元素.replaceChild(a,b);

用a替换元素内的b

注意两种情况

直接用已存在的替换另一个存在的 是剪切操作

复制或重新声明的就是单纯的替换

//复制拷贝
var oWrap = document.getElementById('wrap');
//cloneNode方法会对调用它的节点对象进行复制 传参true代表包括该节点的后代节点 不传参数表示只复制该节点本身
var cloneWrap = oWrap.cloneNode(true);
document.body.appendChild(cloneWrap);
-------------------------------------------------------
//替换
var oWrap = document.querySelector('#wrap');
var oDes = oWrap.querySelector('#wrap .des');
var newDes = document.createElement('p');
newDes.innerHTML = '我会替换掉你';
oWrap.replaceChild(newDes,oDes);
​
// 用newDes替换oWrap内部的oDes

DOM API 节点删除

通过如下方法可以实现DOM节点的删除

element.removeChild(element.children[1]); //element删除了element内的下标为1的子元素
element.remove(); //H5 DOM API 自己删自己

DOM API 节点检查

document.hasFocus(); //返回布尔值,检测文档或元素是否获取焦点(不常用)
element.hasChildNodes(); //返回布尔值,检测节点对象是否包含任何子节点(不常用)
element.isEqualNode(element2); //返回布尔值,判断element与element2是否是同一个节点
​
element.hasAttributes(); //返回布尔值,判断当前节点对象是否包含属性 只要写了就显示true 一个都没有false
element.hasAttribute(property); //返回布尔值, 判断该节点是否拥有指定的 property 属性

回流重绘

任何改变页面的操作都会导致重绘

减少重绘回流

当添加节点的时候,为了节省重绘事件 不进行依次添加

方法:就是把添加的节点 先存入一个容器 再将容器存入页面这样就相当于只进行了一次添加(也就是一次重绘)

语法:doucment.createDocumentFragment()

文档片段 文档气泡 临时容器

DocumentFragment 不支持 innerHTML

往里面放任何的节点元素 元素列表等等

 <script>
    //向页面存入三个div
    //createDocumentFragment
    function fn(num,tagname){
      var vDOM
      //创建一个容器 把新建的节点存到一个容器中 再一起添加到页面
      var rongqi = document.createDocumentFragment()
      for(var i = 0;i<num;i++){
        //每新建一次 添加一次 就重绘一次 
        // vDOM = document.createElement(tagname)
        // document.body.appendChild(vDOM)
​
        vDOM = document.createElement(tagname)
        //先存入容器
        rongqi.appendChild(vDOM)
      }
      document.body.appendChild(rongqi)
    }
    fn(3,'div')
  </script>