6-1 JS编程接口(DOM简介、获取元素的API、节点的增删改查)

前置知识

  • 理解JS语法,如变量、if els、循环
  • 会背JS的七种数据类型
  • 会背JS的五个falsy值
  • 知道函数是对象,数组也是对象
  • 会用div和span标签
  • 会简单的CSS布局

一、DOM简介

1.网页其实是一棵树
也就是数据结构里面的树
注意:文字也是一个节点
在这里插入图片描述
在这里插入图片描述

2.JS如何操作这棵树

2.1 浏览器往window上加一个document即可

  • 有了这个document对象就可以操作这棵树了
  • window.document 就可以获取整个网页的所有元素
    当点中document时,整个网页都被选中了
    在这里插入图片描述

2.2 JS用document操作网页

这种思想叫做:Document Object Model 文档对象模型
意思是:把网页抽象成一个document对象,并对它进行操作的这么一种方式叫做DOM

2.3 DOM很难用
从来不会用DOM自带的功能来操作DOM,开始用JQuery来操作,后面会用vue和react来操作DOM

二、获取元素的API

什么是API?
它提供的所有函数都是API

1.获取元素,也叫标签
(div标签和span标签这些都叫做元素,Elemt:元素、Tag:标签)

  • 有很多API
  1. window.id 或者直接 id
    可以直接输入其id名(id是唯一的)
  2. document.getElementByld('id')——IE才用
    一般情况下都用1比较方便,但某些情况下,如id是parent这种在window上的全局属性时,只有用2才能找到
  3. document.getElementsByTagName('div')[0]——IE才用
    注意有个’s’,找到所有标签名为 div 的元素,找到的所有div是一个整体数组,想要操作其中一个必须加上下标
  4. document.getElementsByClassName('red')[0]——IE才用
    把所有 class 为 red 的标签都获取到,一个整体的数组,想要某一个加下标
  5. document.querySelector('#id')
    注意要加 # ,这个div可以写得很复杂
    如:document.querySelector(‘div>span:nth-child(2)’)
    找一个div中的span,并且这个span是div的第二个儿子,CSS怎么写,这里就可以写
  6. document.querySelectorAll('.red')[0]
    5是按照条件找到第一个,6是把满足条件的全部找到
  • 用哪一个
    工作中用querySelectorquerySelectorAll
    demo直接用id,千万别让人发现
    需要兼容IE的可怜虫才用document.getElementsByTagXXX
    在这里插入图片描述

2.获取特定元素

  • 获取 html 元素
    document.documentElement
    在这里插入图片描述
  • 获取 head 元素
    document.head
  • 获取 body 元素
    document.body
  • 获取窗口(窗口不是元素)
    window
    window虽然不是一个标签,但是有时候可以获取window然后添加一些全局的事件监听
    window.onclick = () =>{console.log('点击')}:点击页面监听
  • 获取所有元素
    document.all
    1.这个 document.all 是个奇葩,第6个falsy值(虽然是falsy值,但功能不受影响依旧能获取元素,只是可以用来区分IE)
    因为它是IE发明的,很多程序员就用 document.all 是否存在来检测当前页面是否是IE,如果是则运行只能在IE上运行的代码,后续其他浏览器也有了document.all,为了保证那些代码还是只能在IE上运行,则统一规定它为假值
    在这里插入图片描述
    2.当我们获取html标签的时候,实际上只获取了html元素,html里面的children(如:head、body等)没有获取到
    而获取所有标签则是:[html , head, body, div,…]
    document.all
    在这里插入图片描述

3.获取到的元素是个啥?

获取到的所有元素都是一个对象,我们需要搞清它的自身属性和原型

  • HTMLElment和Element的区别(HTML元素和元素)
    以前的网页要同时处理HTML元素和XML元素(AJAX里面的),Element是属于HTML元素、XML元素、SVG元素各种不同标准的元素

3.1 抓一只div对象来看看

  • console.dir(div1)看原型链(div1是给获取到的div对象命的名)
  • 自身属性:className、id、style等等
  • 第一层原型:HTMLDivElement.prototype
    这里面是所有div共有的属性,不用细看
  • 第二层原型:HTMLElement.prototype
    这里面是所有HTML标签共有的属性,不用细看
  • 第三层原型:Element.prototype
    这里面是所有 XML、HTML标签共有的属性,浏览器不止展示HTML
  • 第四层原型:Node.prototype
    这里面是所有节点共有的属性,节点包括 标签 和 文字
  • 第五层原型:EventTarget.prototype
    里面最重要的函数属性是:addEventListener、dispatchEvent、removeEventListener
  • 最后一层原型就是:Object.prototype
    根对象

3.2 div完整原型链

  • div是一个对象,一共有6层属性
  • 每一层构造函数都会往div上加东西
    在这里插入图片描述

4.1 节点Node包括以下几种节点

  • MDN有完整描述,在任何一个节点上输入 x.nodeType得到一个数字
    如:div.nodeType
  • 1 表示元素Element,也叫标签 Tag
  • 3 表示文本Text
  • 8 表示注释Comment
  • 9 表示文档Document
  • 11 表示文档片段DocumentFragment
  • 记住1和2即可,节点分为标签和文字

4.2 节点与元素的区别
在 HTML DOM (文档对象模型)中,每个部分都是节点:

  • 文档本身是文档节点
  • 所有 HTML 元素是元素节点
  • 所有 HTML 属性是属性节点
  • HTML 元素内的文本是文本节点 (包括回车符也是属于文本节点)
  • 注释是注释节点

Element 对象可以拥有类型为元素节点、文本节点、注释节点的子节点。
NodeList 对象表示节点列表,比如 HTML 元素的子节点集合。
元素也可以拥有属性。属性是属性节点。
总结:元素是元素节点,是节点中的一种,但元素节点中可以包含很多的节点。

节点的增删改查

1.增

  • 创建一个标签节点
    let div1 = document.createElement('div')
    document.createElement('style')
    document.createElement('script')
    document.createElement('li')
  • 创建一个文本节点
    document.createTextNode('你好')
    ‘你好’ 是一个字符串,文本节点是一个对象(有原型和函数)
  • 标签里面插入文本
    div1.appendChild(text1)
    div1.innerText = '你好' 或者 div1.tx=textContent = '你好'
    以上两个是不同的构造函数提供的属性,都可以用但不能混着用
    注意:不能用div1.appendChild('你好')
    在这里插入图片描述

1.1 增(续)

  • 插入页面中
  1. 创建的标签默认处于JS线程中,不会显示到页面上
  2. 必须把它插到 head(如:style和link元素) 或者 body 里面,它才会生效
  3. document.body.appendChild(div)
  4. 已在页面中的元素.appendChild(div)
    在这里插入图片描述

1.2 appendChild

  • 页面中有 div#test1 和 div#test1(id为test1和2)
let div = document.createElement('div')
test1.appendChild(div)
test2.appendChild(div)
  • 最终div会出现在 test2 中
    因为每个元素只能有一个爸爸(这是树结构的特点),除非复制一份(克隆)
    孩子先给了1,然后给了2,因此最后孩子在2哪里

2.删

  • 两种方法
    旧方法:div1.parentNode.removeChild(div1)只能找父亲删掉儿子
    新方法:div1.remove()不能兼容IE
  • 思考
    如何一个 node 被移出页面(DOM树)
    那么它还可以再次回到页面中吗?——可以
    答:因为移出之后还在内存中,并没有消失,用appendChild(div1)即可
    如何让它完全消失?
    答:先移除,然后让它为空,div2就和内存断开联系,垃圾回收了
    在这里插入图片描述

3.改

3.1 改写属性

  • 改 class:div.className = 'red bule'(全覆盖,会把之前的覆盖掉)后面加个name的原因是早期的JS对象不能用保留字(如class、if)作为它的key,因为后面用的时候会产生混淆
  • 改 class:div.classList.add('red'):不会覆盖之前的
  • 改 style:div.style = 'width: 100px; color:bule;'这个会把前面的所有属性都覆盖掉,不推荐
  • 改 style 的一部分:div.style.width='200px'
    大小写: div.style.backgroundColor='white'大写字母相当于background-color,就是把中划线用大写字母代替了
  • 改 data-* 属性:div.dataset.x = 'frank'
    在这里插入图片描述
    在这里插入图片描述
  • 读属性
    1.div.classList / a.href :这个有个bug,有些时候浏览器会默认添加一些前缀
    2.div.getAttribute(‘class’) / a.getAttribute(‘href’) :虽然更复杂,但想得到什么,就是什么
    3.两种方法都可以,但值稍微有些不同
<a id=test href="/xxx">/xxx</a>
console.log(test.href)
console.log(test.getAttribute('href'))

在这里插入图片描述

3.2 改事件处理函数

  • div.onclick 默认为 null
    1.默认点击 div 不会有任何事情发生
    2.但是如果你把 div.onclick 改为一个函数 fn
    3.那么点击 div 的时候,浏览器就会调用这个函数
    4.并且是这样调用的 fn.call(div,event):前面是触发元素的引用,后面接事件的所有详细信息
    5.div 会被当做 this
    6.event 则包含了点击事件的所有信息,是浏览器用call传进来的,如坐标(在哪点的)
  • div.addEventListener
    是上一个的升级版,onclick只能写一个函数,这个能写无数个
<div id="test">test</div>
test.onclick = function(x){
  console.log(this)
  console.log(x)
}

//test.onclick.call(test,evet)

3.3 改内容

  • 改文本内容
    div.innerText = 'xxx'
    div.textContent = 'xxx'
    两个几乎没区别
  • 改 HTML 内容
    div.innerHTML = '<strong>重要内容</strong>'
    如果里面的字符太多或者太复杂,容易把浏览器卡住
  • 改标签
    div.innerHTML = '' //先清空
    div.appendChild(div2)//再加内容

3.4 改爸爸

  • 想要找一个新的父级
    newParent.appendChild(div)
    直接这样就可以了,直接从原来的地方消失

  • 查爸爸
    node.parentNode或者node.parentElement
  • 查爷爷
    node.parentNode.parentNode
    在这里插入图片描述
  • 查子代
    node.childNodes或者node.children(优先使用children,不会算其他符号进去)
    当用childNodes查子代时,子代会包含文本节点:回车空格(不论多少个会合成1个空格)、标签
    中间没有空格就不算子代
  <ul id="test">//空格1,多个合成1个
    <li>1</li>//空格2
    <li>2</li>//空格3
    <li>3</li>//空格4
  </ul>
console.log(test.childNodes.length)
//答案是:7(包含了3个li和4个空格)

在这里插入图片描述

  • 查兄弟姐妹
    node.parentNode.childNodes,后面还需要遍历数组排除自己
    node.parentNode.children,后面还需要遍历数组排除自己
    在这里插入图片描述
  • 查看第一个儿子
    node.children[0]
    node.firstChild
  • 查看最后一个儿子
    node.lastChild
  • 查看上一个哥哥/姐姐
    node.previousSibling
  • 查看下一个弟弟/妹妹
    node.nextSibling
  • 注意:以上查询时会有node和Element,两个结果可能不同,node中还包含文档节点
    在这里插入图片描述
  • 遍历一个 div 里面的所有元素
  • 原理就和数据结构中遍历一棵树一样,这就是数据结构的大用处
travel = (node,fn) =>{
  fn(node)
  if(node.children){//判断是否存在子元素
     for(let i=0; i<node.children.length;i++){
       travel(node.children[i],fn)
     }
  }
}
travel(div1,(node)=>console.log(node))
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值