js_DOM学习

原生DOM学习笔记

一、基本认知

1. 什么是DOM?

DOM (Document Object Model)——文档对象模型。是浏览器提供的一套专门用来操作网页内容的 API 。

2. DOM 树

3. DOM 对象(重要)

  • 浏览器根据html标签生成的 js 对象,所有的标签属性都能在这个对象上找到,所以修改这个对象的属性会自动映射到标签身上。

  • DOM的核心思想:把网页内容当作对象来处理。

  • document对象 是DOM提供的一个对象,网页的所有内容都在document里


二、获取DOM对象

两种方式,更推荐第一种

  • 根据CSS选择器获取DOM元素(主)

  • 其他方式

1. 根据CSS选择器获取DOM元素(主要)

(1)document.querySelector()

选择匹配到的第一个元素:

const box = document.querySelector('div')

注意:括号里一定要有引号,然后里面写的是css选择器,css里咋写,引号里就咋写,返回值是匹配的第一个元素对象

(2)document.querySelectorAll()

选择匹配的多个元素:

const lis = document.querySelectorAll('ul li')

返回值是一个伪数组,里面是所有匹配到的对象的集合。

​ 伪数组:

  • 有长度有索引号
  • 但是没有pop,push等方法

那么如果想要得到里面的每一个对象就采用遍历方式获取。

2. 其他方式

这些都是早期的写法,现在基本不怎么用了。

//(1)根据id获取元素.
document.getElementById('nav')

//(2)根据标签获取某一类元素
document.getElementByTagName('div')

//(3)根据类名获取元素
document.getElementByClassName('main')

三、操作DOM内容

1. innerText 属性

  • 将文本元素添加/更新到任意标签位置(表单除外)

  • 显示纯文本,不会解析标签

    const box = document.querySelector('.box')
    box.innerText = '你好'
    
    //  这个属性不会解析标签,也就是说,如果你这么写: box.innerText = '<a>xxxx</a>',是不会把里面内容当成超链接的,只是纯文本。
    

2. innerHTML属性

与innertext 的区别就是,这个属性会解析标签,那么当多标签的时候建议使用模板字符串(``)。

用法没啥区别。


四、操作元素属性

1. 操作元素-常用属性

**比如:**src href title…等等,下面是进行修改的例子:

//例子:
const pic  = document.querySelector('img')
pic.src = './imgs/02.jpg'
pic.title = 'laosan'

2.操作元素-样式属性

用到操控样式的情况还是非常多的,比如:

  • 轮播图小圆点自动更换颜色演示
  • 点击按钮滚动图片…
(1)通过 style 属性操作 CSS

该方法在修改样式比较少的情况下有优势。并且生成的是行内样式表,权重高,会覆盖掉之前的样式。

const box = document.querySelector('.box')

box.style.width = '300px'  //注意要写引号,因为需要跟单位
box.style.backgroundColor = 'pink' //这个里面是不可以写成background-color的,会识别成减法,所以要用小驼峰命名法。

**案例:**随机更换body的背景图片。

//定义一个函数,取到N-M之间的随机整数,复制粘贴就行了,感兴趣就当做数学题研究一下
function getRandom(N,M){
    return Math.floor(Math.random()*(M-N+1))+N
}

const random = getRandom(1,10)
document.body.style.backgroundImage=`url(./images/desktop_${random}.jpg`
(2)通过类名className修改 CSS

过程就是现在css里面写一个类,给这个类设定一个样式,当需要修改成这样的样式时候,直接赋给这个元素。

但是需要注意一下,这个会替换掉之前的class类名

const div = document.querySelector('djv')
div.className = 'mean'
//那么如果还想保留之前的class类,可以这样写,就即保存了当前的,也添加了新的
div.className = 'mean  navicate'
(3)通过classList修改CSS (常用)

为了解决className容易覆盖掉之前的类名这个问题,我们是可以通过classList的方式来追加和删除类。

const div = document.querySelector('djv')
// 类名不加点,并且是字符串
// 追加一个类
div.classList.add('nav')

// 删除一个类
div.classList.remove('nav')

// 切换一个类,有就删掉,没有就加上
div.classList.toggle('nav')

3.操作表单元素属性

文本框/单选按钮/多选按钮…

表单在很多情况下也需要修改属性,比如点击眼睛,显示或隐藏密码。

<input type='text' value='电脑'>
<script>
	const uname = document.querySelector('input')
    //获取表单里的值,innerHTML是得不到值的。
    console.log(uname.value)
    uname.type='password'
</script>

表单属性中添加就有效果,移除就没有效果,一律使用布尔值表示,比如:disabled、checked、selected

<input type='text' value='电脑'>
<script>
	const uname = document.querySelector('input')
	unmae.checked = true
</script>

4.自定义属性(h5新增)

(以前的getAttribute设置自定义属性不用了,可读性太差了)

  • 在html5中推出专门的data- 自定义属性
  • 在标签上一律以data开头
  • 在DOM对象上一律以dataset对象方式获取
<div data-id="1" data-spm='x'>1</div>
<div data-id="2">2</div>
<div data-id="3">3</div>
<div data-id="4">4</div>
<script>
	const one = document.querySelector('div')
	console.log(one.dataset) //data属性集合
    console.log(one.dataset.id) // 1
</script>

五、定时器-间歇函数

使用场景:

  • 功能:每间隔一段时间需要自动执行一段代码,不需要手动去触发。
  • 定时器有两种,此处介绍的是间歇函数。

1.开启定时器

语法:

setInterval(函数,间隔时间)

作用:每间隔一段时间就会调用一下这个函数(间隔时间的单位是毫秒)eg:

setInterval(function(){
    console.log('你好')
},1000)

//或者分开写:
function fn(){
    console.log('你好')
}
setInterval(fn,1000)

定时器一旦开启不会自己停下来,如果不用匿名函数,那么调用的时候括号里直接写函数名,后面不用加小括号。

定时器返回的是一个数字id(数字型)(定时器排号)。

2.关闭定时器

// 得先拿到定时器的id,存到n里
let n = setInterval(fn,1000)

//关闭定时器
clearInterval(n)

六、事件

1. 事件监听

事件监听就是让程序检测是否有事件的发生,一旦有事件触发,就立即调用一个函数做出响应,也称为绑定事件注册事件

事件监听三要素:

  1. 事件源:获取过来dom元素。
  2. 事件类型:比如click,mouseover…
  3. 事件调用函数:要做的事
<button>按钮</button>
<script>
	const btn = document.querySelector('button')
    btn.addEventListener('click',function(){	// 事件类型要用字符串
        alert('点击了')
    })
</script>

拓展——事件监听版本

以前的事件监听版本:

DOM L0: xxx.on事件 = function(){}

我们现在用的是L2,以前的L0会出现事件被覆盖的问题,L2不会。还有L0做不了事件捕获。

两种事件监听区别:

在这里插入图片描述

2. 事件类型

在这里插入图片描述

3. 事件对象

事件对象里有事件触发时的相关信息,比如当鼠标点击的时候,事件对象就存了鼠标点在哪个位置等信息。

应用场景:

  • 可以判断用户按下了哪个按键。
  • 可以判断鼠标点击了哪个元素,从而做出相应操作。
(1)如何获取事件对象

在事件绑定的回调函数的第一个参数就是事件对象,一般起名叫event或者e。

const btn = document.querySelector('button')
btn.addEventListen('click',function(e){
    console.log(e)
})
(2)事件对象的常用属性
  • type 获取当前的事件类型
  • target 获取触发事件的对象——它的一个属性 tagName 可获取真正触发事件的元素名(大写,如“LI”,“P”)
  • clientX / clientY 获取光标相对于浏览器可见窗口左上角的位置
  • offsetX / offsetY 获取光标相对于当前DOM元素左上角的位置
  • key 用户按下的键盘键的值(以前用keycode,已经废弃了,现在不用了)

4. 事件流

事件流指的是事件完整执行过程中的流动路径,第一阶段是捕获阶段(从大到小),第二阶段是冒泡阶段(从小到大)

在这里插入图片描述

实际开发中大多数都是冒泡,很少用捕获。

(1)事件捕获

事件捕获需要写相应的代码,就是在之前提过的事件监听的基础之上,加一个参数:

DOM.addEventListener(事件类型,事件处理函数,是否使用捕获机制)
// addEventListener的第三个参数传入  true  代表的是捕获阶段去触发(很少使用)
// 若传入false 代表的就是冒泡阶段触发,如果不写第三个参数,默认就是冒泡。

ps:如果是DOM L0,则只有冒泡阶段,没有捕获。

(2)事件冒泡

当一个元素的事件被触发,会依次向上调用所有父级元素的同名事件

事件冒泡是默认存在的,但是在很多情况下要阻止冒泡,阻止冒泡前提需要拿到事件对象。stopPropagation()

阻止冒泡方法
事件对象.stopPropagation()

这个方法可以阻断事件流的传播,在捕获阶段也有效。

div.addEventListener('click',function(e){
	alert('你好')
	// 阻止事件流传播
	e.stopPropagation()
})
阻止元素默认行为

比如阻止链接的跳转,表单域的跳转等等。

事件对象.preventDefault()
<form action = "http://www.....">
    <input type = 'submit' value = '免费注册'>
</form>
<script>
    // 当信息有误的时候就要阻止提交
    const form = document.querySelector('form')
	form.addEventListen('submit',function(e){
    	e.preventDefault()		// 阻止默认行为
	})
</script>

5. 解绑事件(用的少)

对addEventListener解绑,需要使用removeEventListener(事件类型,事件处理函数,是否使用捕获机制)

需要注意的是,匿名函数是无法

function fn(){
    console.log('你好')
}
// 绑定事件
btn.addEventListener('click',fn)
//解绑
btn.removeEventListener('click',fn)
扩展:鼠标经过事件
  • mouseover 和 mouseout 会有冒泡效果。
  • mouseenter 和mouseleave 没有冒泡效果(推荐)

6. 事件委托

事件委托是一种技巧,同时给多个元素注册事件

原理是利用事件冒泡的特征解决的,优点是可以减少注册次数

  • 给父元素注册事件,当触发子元素时候,会冒泡到父元素,从而触发父元素的事件。
<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
</ul>

<script>
	//要求点击li,当前的li文字变为红色,按事件委托方式
    const ul = document.querySelector('ul')
    ul.addEventListener('click',function(event){
        if(event.target.tagName === 'LI'){
            e.target.style.color = 'red'
        }
    })
    // 一般都这么写,实在没懂先记下来。
</script>

7.其他事件

1.页面加载事件
(1) ‘load’

这个是等外部资源加载完毕时触发的事件(如图片、外联CSS、和 JavaScript)

window.addEventListener('load',function(){
		............
})

不光可以监听整个页面资源加载完,也可以针对某个资源绑定加载事件,比如:

img.addEventListener('load',function(){
		............
})
(2)‘DOMContentLoaded’

给document添加这个事件。这个是等DOM元素加载完就执行。

document.addEventListener('DOMContentLoaded',function(){
		............
})
2.元素滚动事件

在滚动条滚动的时候触发。’scroll‘

// 监听整个页面滚动
window.addEventListener('scroll',function(){   
		............
})

如何知道页面滚动的距离?通过两个属性。

在这里插入图片描述

const div = document.querySelector('div')
div.addEventListen('scroll',function(){
    console.log(div.scrollTop) // 查看被卷曲的头部距离,得到的是数字型的数据,不带单位。并且可读写
})

想知道整个页面滚动多少的话,需要找到html标签滚动距离

window.addEventListen('scroll',function(){
    console.log(document.documentElement.scrollTop)  
    //这是一种固定语法,document.documentElement可以获取html标签。
})
3.页面尺寸事件
(1)'resize’事件

在浏览器窗口尺寸发生变化的时候触发事件。(了解即可)

window.addEventListen('resize',function(){
    .......
})
(2)'client’属性

获取盒子可见部分的宽高(不包含边框、外边距和滚动条)clientWidthclientHeight

在这里插入图片描述

const div = document.querySelector('div')
const.log(div.clientWidth)
(3)'offset’属性

offsetWidthoffsetHeight,和上面的client基本上一样。

二者区别:

  • 这个offset获取的是包含边框的宽高(可视宽高,盒子隐藏了的话获取的是零)
  • 这个offset是只读属性,不能改。

这个属性使用的时候有个前提,它获取的是自己定位父级的左、上距离。也就是说受父元素的影响。


七、环境对象this(重点)与回调函数

1. this

指的是函数内部的特殊变量 this ,它代表着当前函数运行时所处的环境。每个函数里面都有this。

粗俗一点理解,this指向的是函数的调用者,函数的调用方式不同,this指代的对象也不同。

2. 回调函数

如果将函数A作为参数传递给函数B时,我们就称A为回调函数。

例子:

function fn(){
    console.log('我是回调函数')
}

setInterval(fn, 1000)

一般用匿名函数做回调函数比较常见。


八、节点操作

DOM树里的每个内容都称之为节点,包括元素节点、属性节点、文本节点

1.查找节点

站在关系的角度去查找。

(1)父节点

parentNode 属性,返回的是最近一级的父节点(对象),(亲爸爸)

const div = document.querySelector('div')
console.log(div.parentNode)
(2)子节点

childNodes属性, 能获得所有的字节点,包括文本节点和注释节点(开发中很少用,了解即可)

children属性(重点),仅获得所有的元素节点(亲儿子)。

用法同上。

(3)兄弟节点

下一个兄弟节点: nextElementSibling属性

上一个兄弟节点:previousElementSibling属性

用法同上。

2.增加节点(重点)

很多情况下,需要在页面中增加元素,比如:点击发布按钮,可以新增一条信息。

那么新增节点一般分两步:

  • 创建一个新节点。
  • 把创建的新节点放入到指定的元素内部。

第一步创建节点

document.createElement('div')

第二步、插入节点

  • 插入到父元素的最后一个子元素:
父元素.appendChild(要插入的元素)

eg:

const li = document.createElement('li')
const ul = document.querySelector('ul')
li.innerHTML = '我是li'
ul.appendChild(li)

这样就把 li 塞进 ul 里了

  • 插入到父元素中某个子元素的前面:
父元素.insetBefore(要插入的元素,在哪个元素前面)

eg:

const li = document.createElement('li')
const ul = document.querySelector('ul')
li.innerHTML = '我是li'

ul.insertBefore(li, ul.children[0])   //永远放在ul里的最前面,保证每次放入都在最前面

3.克隆节点

克隆一个已有的元素节点

元素.cloneNode(布尔值)

这个方法会克隆出一个跟原标签一样的元素,括号里放布尔值(默认是false)

当布尔值是 true 时,代表克隆的时候会包含后代节点一起克隆。(深克隆)

当布尔值是 false 时,代表克隆的时候不包含后代节点。

eg:

const ul = document.querySelector('ul')
const li1 = ul.children[0].cloneNode(true)   // 把ul下的第一个li克隆出一份,然后传给li1

ul.appendChild(li1)  //在ul最后面加上

4.删除节点

在js的原生DOM中,要删除元素必须通过父元素去删除!

如果父子关系不存在则删除不了,

删除和隐藏是不一样的,删除是在html中删除节点

父元素.removeChild(要删除的元素)
const ul = document.querySelector('ul')
ul.removeChild(ul.children[0])  //把ul下面的第一个li 给删了

九、移动端事件

在这里插入图片描述

主要是根据黑马pink老师的讲解和文档查询到的,说实话,不总用原生忘得太快了,忘记的时候查一下叭。

  • 28
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值