API(Application Programming Intertace ,应用程序接口),预先定义的接口(一般是函数)

一、 DOM —一套操作网页内容的函数

DOM(Document Object Mode)一般指文档对象模型,文档对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展置标语言的标准编程接口(api)。

  1. 什么是DOM树

将html文档以树状结构表现出来
作用:体现了标签与标签之间的关系

  1. 什么是DOM对象

浏览器内存在以 js对象(dom对象) 的形式存储
DOM工作原理

1.浏览器将html文件读取到内存中 2.生成dom树 3.根据dom树渲染到页面

image.png网页所有内容都在document里面

1.获取页面元素

  1. document.querySelector(‘选择器’) 标签、类、id

功能: 根据选择器获取满足条件的第一个元素
参数: string css选择器字符串
返回值: DOM对象 | null
选择器存在返回第一个元素
选择器不存在会获取null

  1. let box = document.querySelector('.box') //变量名尽量与选择器一样
  2. box.style.color = 'red'
  1. document.querySelectorAll(‘选择器’)

    1.功能: 根据选择器获取满足条件所有的元素
    2.参数: string css选择器字符串
    3.返回值: 一定会得到数组(伪数组),不能使用数组的方法—[DOM对象1,DOM对象2]

    1. let boxList = document.querySelectorAll('.box') //变量名加List后缀
    2. boxList[1].style.color = 'green'

    区别 document.querySelector(‘选择器’) 的到对象,可以直接操作、修改 document. querySelectorAll(‘选择器’) 得到的是数组,不可以直接操作、修改, 数组[下标].属性

document.body 可以直接获取body body具有唯一性

2.操作元素属性

2.1 操作元素内容—元素.innerText && 元素.innerHTML

操作内容之前,首先得获取元素 — document.querySelector(‘选择器’)
1.元素.innerText:获取元素所有的文本
2.元素.innerHTML:获取元素内容(文本+标签)—能解析标签
两者的异同点:
相同点:都获取的是字符串
不同点: 获取的内容不同
innerText:获取文本,重新赋值后无法解析字符串的标签,

innerHTML:获取文本,重新赋值后可以解析字符串的标签,

  1. // 获取元素里面的文本(字符串) 元素.innerText
  2. box.innerText = '<a href="http://jd.com">京东</a><strong>我是强壮的标签</strong>'
  3. // 获取元素里面的文本+标签 元素.innerHTML
  4. box.innerHTML = '<a href="http://jd.com">京东</a><strong>我是强壮的标签</strong>'

2.2 操作元素属性(HTML属性)

首先得拿到元素—document.querySelector(‘选择器’)
语法:
元素.href ==>a标签的herf
元素.src ==>img标签的src

  1. <a href="http://www.baidu.com">百度</a>
  2. <br>
  3. <img src="./images/hmewm.jpg" alt="">
  4. <script>
  5. //获取元素
  6. let a = document.querySelector('a')
  7. let img = document.querySelector('img')
  8. //查看元素属性
  9. console.log(a.href)
  10. console.log(img.src)
  11. //更改属性内容
  12. a.href = 'http://taobao.com' //更改过后再次点击,跳到淘宝网站(本身自带点击事件)
  13. img.src = './images/bgs.png' //因没有添加事件,直接更改了
  14. </script>

2.3操作元素样式—CSS

1.3.1 style操作样式
修改一个样式
首先得拿到元素—document.querySelector(‘选择器’)
语法:
查看:元素.style.样式名
style是对象
修改:元素.style.样式名 = ‘’
如果有这个样式,重新赋值,如果没有,添加新的样式

  1. <div class="box" style="width: 200px; height: 200px; background-color: green;">
  2. </div>
  3. <script>
  4. //获取元素
  5. let box = document.querySelector('.box')
  6. //查看元素的样式
  7. console.log(box.style);
  8. //修改元素的样式
  9. box.style.backgroundColor = 'orange'
  10. //自动转成rgb格式
  11. </script>

注意:样式有 margin- border- font- bgc- ,在dom语法中都需要转成驼峰命名backroundColor,因为 - 不符合js语法规范
1.3.2 className操作样式
语法:
元素.className=’类名’ 会覆盖原先的类 —-不用(out)

  1. <style>
  2. .one {
  3. height: 200px !important;
  4. }
  5. </style>
  6. <div class="box" style="width: 200px; height: 100px;background-color: green;"></div>
  7. <script>
  8. let div = document.querySelector('div')
  9. console.log(div);
  10. div.className = 'one'
  11. </script>

1.3.3 classList操作样式 —获取类名
修改多个样式
首先得拿到元素—document.querySelector(‘选择器’)
语法:
操作类名,不会覆盖原来的类名
新增类名:元素.classList.add(‘类名’)
移除类名:元素.classList.remove(‘类名’)
切换类名:元素.classList.toggle(‘类名’)
包含类名:元素.classList.contains(‘类名’)
有这个类名,就删掉,没有的话,就增加

一次可以写多个类名 元素.classList.add(‘类名1’,’类名2’,’类名3’···)

  1. <style>
  2. .box {
  3. background-color: red;
  4. margin: 0 auto;
  5. }
  6. .rad {
  7. border-radius: 50%;
  8. border: 1px solid #000;
  9. }
  10. .bor {
  11. width: 200px;
  12. height: 200px;
  13. }
  14. </style>
  15. <body>
  16. <div></div>
  17. <script>
  18. //1.获取元素
  19. let div = document.querySelector('div')
  20. // 新增类名:元素.classList.add('类名')
  21. div.classList.add('box', 'rad', 'bor')//<div class="box rad bor"></div>
  22. // 移除类名:元素.classList.remove('类名')
  23. div.classList.remove('box')//<div class="rad bor"></div>
  24. // 切换类名:元素.classList.toggle('类名')
  25. div.classList.toggle('box')//此时没有box类名,就增加<div class="box rad bor"></div>
  26. div.classList.toggle('box')//此时有box类名,就移除 <div class="rad bor"></div>
  27. </script>
  28. </body>

1.3.4 操作表单元素属性

1.表单获取文本用 元素.value —常用
2.表单中的布尔类型属性有
disabled; 是否禁用 0
checked : 默认选中(单选框和多选框)
selected : 默认选中

  1. <script>
  2. //1.获取元素
  3. let inputList = document.querySelectorAll('input')
  4. let optionList = document.querySelectorAll('option')
  5. console.dir(inputList) //伪数组
  6. console.dir(optionList) //伪数组
  7. //2.获取表单的文本 元素.value
  8. // console.log(inputList[0].value);
  9. inputList[0].value = '你好呀' //更改表单文本
  10. //3.更改表单属性
  11. inputList[0].disabled = 'true' //禁用表单
  12. inputList[0].disabled = '' //可用表单
  13. inputList[4].checked = ''
  14. inputList[5].checked = 'true' //默认选中
  15. //3.1更改下拉列表属性
  16. optionList[0].selected = 'true'
  17. </script>

2.4attribute语法操作自定义属性

1 标准属性: W3C中的标准属性,浏览器可以识别 2 自定义属性: 浏览器不能识别样式的属性,用户自定义添加(用于存储一些数据)

attribute语法场景 : 操作元素行内自定义属性
获取属性: 元素.get Attribute(‘属性名’)
设置属性: 元素.setAttribute(‘属性名’,属性值)
移除属性: 元素.removeAttribute(‘属性名’)

  1. <script>
  2. /*
  3. 1. 隔行变色,单行是绿色 双行是黄色
  4. 2.移入li li变红
  5. 3.移除li li变回原来的颜色
  6. */
  7. let liList = document.querySelectorAll('ul li')
  8. console.log(liList);
  9. for (let i = 0; i < liList.length; i++) {
  10. if (i % 2 == 0) {
  11. liList[i].style.backgroundColor = 'green'
  12. } else {
  13. liList[i].style.backgroundColor = 'orange'
  14. }
  15. //2.移入事件
  16. liList[i].onmouseenter = function () {
  17. //背包思想 。 给每一个li元素添加一个自定义属性用于存储自己原先的颜色
  18. this.setAttribute('aaa', this.style.backgroundColor)
  19. this.style.backgroundColor = 'red'
  20. }
  21. //3.移出事件
  22. liList[i].onmouseleave = function () {
  23. this.style.backgroundColor = this.getAttribute('aaa')
  24. }
  25. }
  26. </script>

案例排他思想案例

  1. <script>
  2. //排他思想
  3. /*
  4. 都需要有点击事件 ,点击任意一个所有的样式清空 ,再给点击的按钮添加属性
  5. */
  6. //获取元素
  7. let btnList = document.querySelectorAll('button')
  8. console.log(btnList);
  9. /* btnList[0].onclick = function () {
  10. btnList[0].style.backgroundColor = 'pink'
  11. } */
  12. //注册5个事件
  13. btnList[0].style.backgroundColor = 'pink'
  14. for (let i = 0; i < btnList.length; i++) {
  15. btnList[i].onclick = function () {
  16. //1.无论点击谁所有的样式为空
  17. for (let j = 0; j < btnList.length; j++) {
  18. btnList[j].style.backgroundColor = ''
  19. console.log(j);
  20. }
  21. //2.再吧被点击的增加样式
  22. this.style.backgroundColor = 'pink'
  23. }
  24. }
  25. //给按钮添加移入事件
  26. for (let i = 0; i < btnList.length; i++) {
  27. btnList[i].onmouseenter = function () {
  28. btnList[i].style.color = 'green'
  29. }
  30. btnList[i].onmouseleave = function () {
  31. btnList[i].style.color = ''
  32. }
  33. }
  34. </script>

案例:开关思想

  1. <script>
  2. /*
  3. 1.点击全选/全部选 列表选项为全选/全部选的checked属性
  4. 2.单击列表选项时,只要有一个checked为false all的值为false
  5. */
  6. //获取元素
  7. let checkAll = document.querySelector('#checkAll')
  8. let inputList = document.querySelectorAll('.check')
  9. console.log(checkAll);
  10. console.log(inputList);
  11. //1.点击全选/全部选 列表选项为全选/全部选的checked属性
  12. checkAll.onclick = function () {
  13. //列表选项为全选/全部选的checked属性
  14. for (let i = 0; i < inputList.length; i++) {
  15. inputList[i].checked = this.checked
  16. }
  17. }
  18. //2.累加inputList[i]为true的和 与 inputList[i]的长度相等 则checkAll为true 否则 为false
  19. for (let i = 0; i < inputList.length; i++) {
  20. inputList[i].onclick = function () {
  21. /* let sum = 0
  22. for (let j = 0; j < inputList.length; j++) {
  23. if (inputList[j].checked) {
  24. sum++
  25. }
  26. }
  27. checkAll.checked = inputList.length == sum ? true : false */
  28. // 3.单击列表选项时,只要有一个input的checked值为false all的值为false
  29. let flag = true
  30. for (let j = 0; j < inputList.length; j++) {
  31. if (inputList[j].checked == false) { //inputList[j].checked == false返回的是true
  32. flag = false
  33. break
  34. }
  35. }
  36. checkAll.checked = flag
  37. }
  38. }
  39. </script>

3.操作节点

网页的内容由节点组成(node) 元素节点,属性节点,文本节点,注释节点
dom节点操作语法:元素节点

3.1 查找节点

1.查找元素子节点: 父元素.children| 父元素.children[下标]
2.查找父节点 : 元素.parentNode(常用) | 元素.parentElement
3.查找兄弟节点
3.1上一个兄弟元素 : 元素.preveiousElementSibling
3.2下一个兄弟元素 : 元素.nextElementSibling

  1. <script>
  2. let ul = document.querySelector('ul')
  3. let liT = document.querySelector('#li2')
  4. //1.查找子节点
  5. console.log(ul.children);
  6. //2.查找父节点
  7. console.log(liT.parentNode);
  8. //3.查找兄弟节点
  9. //3.1查找前一个元素节点
  10. console.log(liT.previousElementSibling);
  11. //3.2查找后一个兄弟元素节点
  12. console.log(liT.nextElementSibling);
  13. </script>

3.2新增节点

1.创建节点 let li= document.createElement(‘标签名’)
2.设置节点内容 根据需求添加内容
3.追加到页面
3.1追加到ul父元素里的最后面 : 父元素.appendChild(子元素)
3.2追加到指定位置 : 父元素.insertBefore(创建的子元素子元素,要添加到哪个元素的前面) 例如 : ul.insertBefore(li,li2.nextElementSibling)

  1. <script>
  2. let ul = document.querySelector('ul')
  3. let liList = document.querySelectorAll('li')
  4. //1 创建节点
  5. let h4 = document.createElement('h4')
  6. //2 设置内容
  7. h4.innerText = '我是标题'
  8. //3 追加到页面
  9. ul.appendChild(h4)
  10. ul.insertBefore(h4, liList[0])
  11. </script>

3.3 克隆节点

克隆节点 又叫 复制节点
元素.cloneNode(布尔类型)
false:不克隆后代元素
ture:克隆所有后代后代 包括自己

  1. <script>
  2. document.querySelector('.btn').onclick = function () {
  3. //1.克隆节点
  4. let copyBox = document.querySelector('.box').cloneNode(true)
  5. //2.追加到页面
  6. document.body.insertBefore(copyBox, document.body.children[1])
  7. }
  8. </script>

3.4 删除节点

父元素.removeChild(子元素)

只能删除自己的子元素

  1. <script>
  2. let ul = document.querySelector('ul')
  3. let li2 = document.querySelector('#li2')
  4. document.querySelector('.btn').onclick = function () {
  5. ul.removeChild(li2)
  6. ul.removeChild(ul.children[3])
  7. }
  8. </script>

3.5日期对象Date

  1. <script>
  2. /*
  3. 1.js内置对象Date :
  4. 内置对象 : 由js作者提前写好的,我们直接拿来使用即可。
  5. */
  6. //1.创建日期对象
  7. let d=new Date()
  8. console.log(d)
  9. //2.1 转换日期格式
  10. console.log(d.toLocaleString()) //2021/12/15 下午4:46:16
  11. console.log(d.toLocaleDateString()) //2021/12/15
  12. console.log(d.toLocaleTimeString()) //下午4:46:16
  13. //2.2 获取年月日时分秒
  14. console.log(d.getFullYear()) //2021
  15. // 1-12月对应0-11下标
  16. console.log(d.getMonth()) //11下标, 12月
  17. console.log(d.getDate()) //15
  18. // 星期天 - 星期六 0-6
  19. console.log(d.getDay()) //3
  20. console.log(d.getHours()) //16
  21. console.log(d.getMinutes()) //47
  22. console.log(d.getSeconds()) //48
  23. //2.3 获取时间戳
  24. /*
  25. 1.时间戳 : 从1970年1月1日格林威治 到现在 秒数
  26. 2.时间戳作用 : 兼容世界时区
  27. */
  28. console.log(+d) // 日期对象转数字
  29. console.log(Date.now()) // 时间戳
  30. </script>

案例:微信发布

  1. <script>
  2. // maxlength 是一个表单属性, 作用是给表单设置一个最大长度
  3. // 模拟数据
  4. let dataArr = [{
  5. uname: '司马懿',
  6. imgSrc: './images/9.5/01.jpg'
  7. },
  8. {
  9. uname: '女娲',
  10. imgSrc: './images/9.5/02.jpg'
  11. },
  12. {
  13. uname: '百里守约',
  14. imgSrc: './images/9.5/03.jpg'
  15. }
  16. ]
  17. /*需求分析:找交互
  18. 1.文本框输入事件: 获取用户输入文本长度 赋值给 span标签
  19. 2.发布按钮点击事件:
  20. (1) 检测内容是否为空, 为空则不添加内容
  21. (2) 根据用户输入内容,生成li元素
  22. (3) 将新生成的li元素追加到最前面
  23. (4) 重置输入框: 文本 和 数量都要重置
  24. 3.删除按钮点击事件: 点删除,移除自身所在的li元素
  25. * 本案例难点: 动态添加的元素不能直接注册事件
  26. * 分析原因: 删除按钮一开始页面是没有的,因此无法获取。 只有用户点击发送按钮,才会动态新增。
  27. * 解决方案:
  28. * 1.在新增li元素的后面,获取删除按钮并注册事件
  29. * 2.事件委托技术(实际开发解决方案,明天学习)
  30. */
  31. let area = document.querySelector('#area') //文本框
  32. let useCount = document.querySelector('#useCount') //字数
  33. let send = document.querySelector('#send')
  34. let ul = document.querySelector('#list')
  35. let del = document.querySelector('.the_del')
  36. // 1.文本框输入事件: 获取用户输入文本长度 赋值给 span标签
  37. area.oninput = function () {
  38. useCount.innerText = this.value.length
  39. }
  40. //2.发布按钮点击事件:
  41. // (1) 检测内容是否为空, 为空则不添加内容
  42. // (2) 根据用户输入内容,生成li元素
  43. // (3) 将新生成的li元素追加到最前面
  44. send.onclick = function () {
  45. // console.log(1)
  46. // (1) 检测内容是否为空, 为空则不添加内容
  47. if (area.value.trim() == '') {
  48. alert('请输入内容哟')
  49. return
  50. }
  51. // (2) 根据用户输入内容,生成li元素
  52. // 创建节点
  53. let li = document.createElement('li')
  54. //设置内容
  55. //设置下标为一个随机数
  56. let i = parseInt(Math.random() * dataArr.length - 1)
  57. console.log(i);
  58. li.innerHTML = `
  59. <div class="info">
  60. <img class="userpic" src=${dataArr[i].imgSrc} />
  61. <span class="username">${dataArr[i].uname}</span>
  62. <p class="send-time">${new Date().toLocaleString()}</p>
  63. </div>
  64. <div class="content">${area.value}</div>
  65. <span class="the_del">X</span>
  66. `
  67. //追加到页面 父元素.insertBefore(追加的元素,追加到哪个元素的前面)
  68. ul.insertBefore(li, ul.children[0])
  69. //文本域的内容为空 span标签的文本变0
  70. area.value = ''
  71. useCount.innerText = 0
  72. }
  73. // 3.删除按钮点击事件: 点删除,移除自身所在的li元素
  74. //事件委托
  75. // (1) 给父元素添加点击事件
  76. ul.onclick = function (e) {
  77. console.log(e.target);
  78. if (e.target) {
  79. ul.removeChild(e.target.parentNode)
  80. }
  81. }
  82. </script>

案例:图片切换

  1. <script>
  2. /*
  3. 1.点击上一张 跳转到前一张
  4. 2.点击下一张 跳转到后一张
  5. */
  6. let img = document.querySelector('img')
  7. let prev = document.querySelector('#prev')
  8. let next = document.querySelector('#next')
  9. //1.声明个数组,保存图片的路径
  10. let imgArr = [
  11. "./images/01.jpg",
  12. "./images/02.jpg",
  13. "./images/03.jpg",
  14. "./images/04.jpg",
  15. "./images/05.jpg"
  16. ]
  17. //2.声明一个变量来存储此时显示的图片(数组的下标)
  18. let index = 0
  19. //3点击上一张 跳转到前一张
  20. prev.onclick = function () {
  21. // 如果此时是第一张, 再次点击上一张则跳到最后一张
  22. index == 0 ? index = imgArr.length - 1 : index--
  23. img.src = imgArr[index]
  24. console.log(index)
  25. }
  26. // 4.点击下一张 跳转到后一张
  27. next.onclick = function () {
  28. // 如果此时是最后一张, 再次点击下一张则跳到第一张
  29. index == imgArr.length - 1 ? index = 0 : index++
  30. img.src = imgArr[index]
  31. console.log(index)
  32. }
  33. </script>

二、 事件

实现交互功能 只要是是标签都能注册事件,一个标签可以注册多个事件

1.事件三要素

事件三要素:
事件源:哪个元素
事件类型:当干什么的时候 例如:单击 双击 移入 移除
事件处理函数:做什么事情 或者说发生什么变化

2.注册事件

dom注册事件有两种语法

注册事件:给元素添加交互功能 事件源.事件类型 = 事件处理函数 box.onclick = function (){} 事件工作原理: 注册事件:其本质就是给对象添加方法,函数在声明的时候不会立即执行——相当于声明函数 触发事件:点击元素的时候,浏览器会自动捕捉到交互,主动帮我们调用这个方法——相当于调用函数

2.1 . 点语法不能注册”同名”事件

1.1注册 box.onclick = function(){ alert(1)}
box.onclick = function(){ alert(2)}
上面的会被覆盖
1.2移除 :box.onclick = null

2.2 addEventListener 可以注册多个”同名“事件

2.1注册 事件源.addEventListener(‘事件类型’,事件处理函数)—没有’on‘
box.addEventListener(‘click’,function(){})
2.2移除 box.removeEventListener(‘click’,fn)
只能移除具名事件

  1. <script>
  2. let box = document.querySelector('#box')
  3. //注册事件
  4. /* box.onclick = function () {
  5. alert('好好学习')
  6. alert('天天向上')
  7. } */
  8. // fn:函数堆地址 fn():函数返回值
  9. let fn = function () {
  10. alert('好好学习')
  11. }
  12. box.addEventListener('click', fn)
  13. box.addEventListener('click', function () {
  14. alert('天天向上')
  15. })
  16. box.removeEven
  17. </script>

3.事件类型

3.1鼠标事件

鼠标单击:onclick
鼠标双击:ondblclick
鼠标移入和移出:onmouseenter | onmouseleave 推荐
onmouseover | onmouseout 000000….

鼠标移动:onmousemove

3.2键盘事件

键盘输入:oninput
成为焦点:onfocus
失去焦点:onblur
键盘按下:onkeydown
键盘松开:onkeyup

3.3网页事件window

网页鼠标移动:window.onmousemove
网页滚动:window.onscroll
网页尺寸变化:window.onresize

4.事件对象

存储与事件(鼠标、键盘)相关数据

4.1获取事件对象

1.事件对象 : 存储与事件相关的数据。 当我们触发事件的时候,浏览器会自动捕捉触发时的鼠标(坐标点)和键盘信息(按键),存入一个对象中,称之为事件对象。
事件对象: 存储与事件触发相关的数据
事件对象是浏览器自动存储的,我们只需要获取即可
2.获取事件对象 : 给事件处理函数添加形参 event | ev | e

  1. <script>
  2. /*
  3. 1.复习鼠标事件
  4. onclick : 鼠标单击
  5. ondblclick : 鼠标双击
  6. onmouseenter: 鼠标移入
  7. onmouseleave: 鼠标移出
  8. onmousemove : 鼠标移动
  9. 2.页面鼠标移动 : window.onmousemove
  10. */
  11. //给页面注册鼠标移动
  12. window.onmousemove = function(e){
  13. console.log(e.pageX,e.pageY)
  14. let img = document.querySelector('img')
  15. //获取事件对象的page坐标, 赋值给图片的定位属性即可(需要注意left有单位px)
  16. img.style.left = e.pageX + 'px'
  17. img.style.top = e.pageY + 'px'
  18. }
  19. </script>

4.2事件对象常用属性或方法

获取鼠标出发点到页面左上角距离 e.pageX / e.pageY
获取案件字符串 ’Enter‘ e.key
获取键盘ASCII码 enter键13 e.keyCode
阻止默认事件(行为) e.preventDefault()
应用场景:
a : 点击默认跳转到href属性链接
form : 点击默认跳转到action属性对应的链接
事件触发源。 获取真正触发事件的子元素,用于事件委托 e.target
阻止事件流 (冒泡 + 捕获都能阻止) e.stopPropagation()

5.事件冒泡

事件冒泡 : 触发子元素事件,所有的父级元素‘同名事件’会被依次触发 元素->父元素->body->html->document->window

  1. <script>
  2. /*
  3. 1.事件冒泡 : 当触发子元素的事件的时候, 所有的父级元素‘同名事件’都会被依次触发
  4. 元素->父元素->body->html->document->window
  5. 2.事件委托 :
  6. 事件委托原理 :事件冒泡
  7. */
  8. //子元素
  9. document.querySelector('.son').onclick = function(){
  10. alert('我是子元素')
  11. }
  12. //父元素
  13. document.querySelector('.father').onclick = function(){
  14. alert('我是父元素')
  15. }
  16. //body
  17. document.body.onclick = function(){
  18. alert('我是body')
  19. }
  20. //html
  21. document.documentElement.onclick = function(){
  22. alert('我是html')
  23. }
  24. //document
  25. document.onclick = function(){
  26. alert('我是document')
  27. }
  28. //window
  29. window.onclick = function(){
  30. alert('我是window')
  31. }
  32. </script>

6.事件委托

给父元素注册事件,委托子元素处理

事件委托的原理就是事件冒泡

事件委托应用场景 :
(1)实际开发最多: 给动态新增的子元素注册事件
(2)性能优化 : 如果所有的子元素都需要注册同名事件,只需要给父元素注册
事件委托注意点 :
(1)事件委托不能通过this找到子元素。 (this指向父元素)
(2)事件委托需要通过什么属性找到子元素: e.target

  1. //需求:给每一个li元素注册点击事件
  2. let ul = document.querySelector('ul')
  3. //2.事件委托 : 给父元素注册事件,委托给子元素处理
  4. ul.onclick = function(e){
  5. /* this : 事件源,父元素ul
  6. e.target : 真正点击的子元素
  7. */
  8. alert(e.target.innerText)
  9. console.log(e)
  10. }
  11. /* 如果一个元素是动态新增的 : 一开始没有,页面加载后使用dom新增语法添加的 */
  12. document.querySelector('.btn').onclick = function(){
  13. let li = document.createElement('li')
  14. li.innerText = '我是新来的'
  15. ul.appendChild(li)
  16. }

案例:DOM综合表格案例

  1. <script>
  2. /* 思路分析
  3. 1.点击录入 :(注意点form表单中的按钮需要阻止默认事件)
  4. 1.1 非空判断 : 姓名、年龄、薪资不能为空
  5. 1.2 新增tr元素
  6. * (1)创建tr (2)设置内容 (3)添加到table>tbody
  7. 1.3 清空form表单
  8. 2.点击删除 : 使用事件委托技术
  9. 2.1 点击删除, 删除tr标签 ( 删除按钮的父元素的td, td的父元素是tr)
  10. 3.上移
  11. 4.下移
  12. */
  13. //1.获取元素
  14. let uname = document.querySelector('.uname')
  15. let age = document.querySelector('.age')
  16. let gender = document.querySelector('.gender')
  17. let salary = document.querySelector('.salary')
  18. let city = document.querySelector('.city')
  19. let add = document.querySelector('.add')
  20. //2.1 点击录入
  21. add.onclick = function(e){
  22. /* 注意点:form表单元素中的按钮需要阻止默认条件 */
  23. e.preventDefault()
  24. //3.1 非空判断 : 姓名、年龄、薪资不能为空
  25. if( uname.value.trim() == '' || age.value.trim() == '' || salary.value.trim() == ''){
  26. alert('输入框不能为空')
  27. }else{
  28. //3.2 新增元素
  29. //(1)创建空tr标签
  30. let tr = document.createElement('tr')
  31. //(2)设置内容
  32. tr.innerHTML = `
  33. <td>1001</td>
  34. <td>${ uname.value }</td>
  35. <td>${ age.value }</td>
  36. <td>${ gender.value }</td>
  37. <td>${ salary.value }</td>
  38. <td>${ city.value }</td>
  39. <td>
  40. <a href="javascript:" class="up">上移</a>
  41. <a href="javascript:" class="down">下移</a>
  42. <a href="javascript:" class="delete">删除</a>
  43. </td>
  44. `
  45. //(3)添加到tbody
  46. document.querySelector('tbody').appendChild(tr)
  47. }
  48. //3.3 表单清空 form.reset()
  49. document.querySelector('form').reset()
  50. }
  51. //2.2 使用事件委托给删除按钮注册点击事件
  52. document.querySelector('tbody').onclick = function(e){
  53. //点击tbody任意区域都会触发点击事件, 真正委托的是删除按钮
  54. let tr = e.target.parentNode.parentNode
  55. //3.1 多分支判断到底是哪一个按钮: 删除、上移、下移
  56. if( e.target.classList.contains('delete') ){
  57. //(1)删除
  58. this.removeChild( tr )
  59. }else if( e.target.classList.contains('up') ){
  60. //(2)上移
  61. //判断tr是不是第一个儿子
  62. if( tr.previousElementSibling ){//有哥哥可以上移
  63. //上移:移到tr哥哥的前面
  64. this.insertBefore(tr,tr.previousElementSibling)
  65. }else{
  66. alert('已经是第一个了')
  67. }
  68. }else if( e.target.classList.contains('down') ){
  69. //(3)下移
  70. //判断tr是不是最后一个儿子
  71. if( tr.nextElementSibling ){
  72. //下移: 移到 弟弟的弟弟的前面
  73. this.insertBefore( tr, tr.nextElementSibling.nextElementSibling )
  74. }else{
  75. alert('已经是最后一个了')
  76. }
  77. }
  78. }
  79. </script>

事件流三个阶段

  1. 事件流三个阶段 e.eventPhase<br /> 1-捕获阶段<br /> 2-目标阶段<br /> 3-冒泡阶段

三、 网页特效(尺寸、定时器)

1.定时器

定时器语法 :

setInterval永久定时器
setInterval : 永久定时器。 一旦开启永久重复执行,只能手动清除
开启: let timeID = setInterval( function(){}, 间隔时间 )
清除: clearInterval( timeID )

setTimeout一次定时器
setTimeout() : 一次定时器。 间隔时间只会执行一次,之后自动清除
开启: let timeID = setTimeout( function(){}, 间隔时间 )
清除: clearTimeout( timeID )

案例 :倒计时秒杀

  1. <script>
  2. /* 秒杀思路
  3. 1.页面一加载,开启间隔 1s 的永久定时器
  4. 1.1 获取当前页面span标签的文本 h m s (转number)
  5. 1.2 s--
  6. 1.3 如果 s < 0,s = 59,m--
  7. 1.4 如果 m < 0, m = 59,h--
  8. 1.5 如果h m s < 10 , 则需要补0
  9. 1.6 将计算之后的结果重新赋值给元素的innerText
  10. //只是修改h m s的值,并没有修改页面元素的内容
  11. 1.7 清除定时器:h == 0 && m == 0 && s == 0
  12. */
  13. let timeID = setInterval( function(){
  14. //1.1 获取当前页面span标签的文本 h m s (转number)
  15. let h = +document.querySelector('#hour').innerText
  16. let m = +document.querySelector('#minute').innerText
  17. let s = +document.querySelector('#second').innerText
  18. //1.2 s--
  19. s--
  20. //1.3 如果 s < 0,s = 59,m--
  21. if(s < 0 ){
  22. s = 59
  23. m--
  24. }
  25. //1.4 如果 m < 0, m = 59,h--
  26. if(m < 0 ){
  27. m = 59
  28. h--
  29. }
  30. //1.5 如果h m s < 10 , 则需要补0
  31. h = h < 10 ? '0' + h : h
  32. m = m < 10 ? '0' + m : m
  33. s = s < 10 ? '0' + s : s
  34. //1.6 将计算之后的结果重新赋值给元素的innerText
  35. document.querySelector('#hour').innerText = h
  36. document.querySelector('#minute').innerText = m
  37. document.querySelector('#second').innerText = s
  38. //1.7 清除定时器:h == 0 && m == 0 && s == 0
  39. if( h == 0 && m == 0 && s == 0){
  40. clearInterval(timeID)
  41. }
  42. },1000)
  43. </script>

2.三大家族—offset scroll clinet

特点: 1.获取的是数字类型(number) 2.只能获取,不能设置 (scrollTop | scrollLeft可以设置)

2.1 offset 获取’元素自身’的真是宽高与位置
offsetWidth/Height —获取’自身’宽高
offsetLeft/Top —获取’自身’位置
2.2 scroll 获取’元素内容’的真实宽高与位置
scrollWidth/Height —获取元素’内容’的宽高
scrollLeft/Top —元素内容滚动出去的距离
2.3 client 获取元素’可视区域’的宽高与位置
clientWidth/Height
clientLeft/Top

获取网页滚动距离

document.documentElement.scrollTop = 400

  1. <script>
  2. /* 学习目标:获取网页滚动距离
  3. 1.给网页注册滚动事件 : window.onscroll
  4. 2.获取网页滚动距离 : document.documentElement.scrollLeft
  5. document.documentElement.scrollTop
  6. */
  7. //1.给页面注册滚动条事件
  8. window.onscroll = function(){
  9. //2.获取页面滚动距离 : html标签
  10. console.log( document.documentElement.scrollLeft,document.documentElement.scrollTop );
  11. };
  12. </script>

案例:电梯导航

  1. <script>
  2. let asideList = document.querySelectorAll('.aside>.item')
  3. let conList = document.querySelectorAll('.content>div')
  4. console.log(asideList, conList);
  5. // 1.点击左边侧边栏
  6. for (let i = 0; i < conList.length; i++) {
  7. asideList[i].onclick = function () {
  8. console.log(i);
  9. //清除类名有active的元素 ,给点击的元素添加active
  10. document.querySelector('.active').classList.remove('active')
  11. this.classList.add('active')
  12. //并让网页跳转到对应的图片
  13. document.documentElement.scrollTop = conList[i].offsetTop
  14. console.log(conList[i].offsetTop);
  15. }
  16. }
  17. //2.网页滚动事件
  18. window.onscroll = function () {
  19. console.log(document.documentElement.scrollTop)
  20. for (let i = 0; i < conList.length; i++) {
  21. console.log(conList[i].offsetTop);
  22. if (conList[i].offsetTop >= document.documentElement.scrollTop) {
  23. document.querySelector('.item.active').classList.remove('active')
  24. asideList[i].classList.add('active')
  25. break
  26. }
  27. }
  28. }
  29. </script>

案例:轮播图

  1. <script>
  2. //获取元素
  3. let indicatorList = document.querySelectorAll('.indicator li') //导航列表
  4. let slidesList = document.querySelectorAll('.slides li') //大图片
  5. let h3 = document.querySelector('.extra h3')
  6. let next = document.querySelector('.extra .next') //下一页
  7. let prev = document.querySelector('.extra .prev') //上一页
  8. let n = 0 //保存图片下标
  9. let main = document.querySelector('.main')
  10. console.log(indicatorList)
  11. console.log(slidesList)
  12. console.log(h3, next, prev)
  13. //鼠标移入indicator里的li
  14. for (let i = 0; i < indicatorList.length; i++) {
  15. indicatorList[i].onmouseenter = function () {
  16. lunbo(i)
  17. //点击和移动事件的下标要一致
  18. n = i
  19. }
  20. }
  21. //鼠标点击下一页
  22. next.onclick = function () {
  23. // 如果下标等于数组的最后一个 否则i++
  24. n == slidesList.length - 1 ? n = 0 : n++
  25. lunbo(n)
  26. }
  27. //鼠标点击上一页
  28. prev.onclick = function () {
  29. // 如果下标等于第一个的时候 变到左后一个 否则i--
  30. n == 0 ? n = slidesList.length - 1 : n--
  31. lunbo(n)
  32. }
  33. //封装函数--排他思想
  34. function lunbo(index) {
  35. //1.修改自身的样式
  36. document.querySelector('.indicator .active').classList.remove('active')
  37. indicatorList[index].classList.add('active')
  38. //2。修改对应的图片
  39. document.querySelector('.slides .active').classList.remove('active')
  40. slidesList[index].classList.add('active')
  41. h3.innerHTML = `
  42. ${index+1}张图的描述信息
  43. `
  44. }
  45. // 定时器
  46. let timeID = setInterval(function () {
  47. //调用下一页,定时器会触发
  48. next.onclick()
  49. }, 500)
  50. //鼠标移入盒子 清除定时器
  51. main.onmouseenter = function () {
  52. clearInterval(timeID)
  53. }
  54. //鼠标移出盒子 恢复定时器
  55. main.onmouseleave = function () {
  56. timeID = setInterval(function () {
  57. //调用下一页
  58. next.onclick()
  59. }, 500)
  60. }
  61. </script>

四、BOM —一套操作浏览器窗口的函数

BOM(Browser Object Model) 是指浏览器对象模型,是用于描述这种对象与对象之间层次关系的模型,浏览器对象模型提供了独立于内容的、可以与浏览器窗口进行互动的对象结构。

1.五个对象

1.1 window浏览器窗口

  1. 1. window特点
  2. 1. JS中的顶级对象,所有的全局函数和全局对象都是window的成员
  3. 1. window对象的成员在使用时可以省略window
  4. 2. window对象方法
  5. 1. 打开新窗口:window.open():可以四个参数

window.open(‘http://www.baidu.com','_blank','left=300,top=100,width=500,height=500‘)

  1. 2. 关闭窗口: window.close()
  2. 3. window对象事件
  3. 1. **window.onload() -->DOM树+外部资源 加载完毕后执行**
  4. 1. window.onbeforeunload():页面关闭前

1.2location:浏览器地址栏

  1. 跳转网页:可以回退

location.href =’url’ —属性
location.assign(‘url) —方法

  1. 替换网页:不能回退

location.replace(url)

  1. 刷新网页

location.reload()

1.3history:历史记录

history三个方法:
history.back() : 返回上一页 等价于 history.go(-1)
history.forward() : 前进下一页 等价于 history.go(1)
history.go( 数字 ) : 到历史记录的具体哪一页
正数: 前进 1:前进1页 2:前进2页
0 :刷新页面
负数: 回退 -1:回退1页 -2:回退2页

1.4navigator:浏览器信息

console.log( navigator.userAgent )//用户代理: 浏览器型号,内核。 计算机操作系

1,5screen:屏幕分辨率

2.存储对象localStorage与sessionStroage

1.localStorage硬盘存储(存储在本地)

1.localStorage对象作用 : 存储数据
经典应用: 免登录
2.localStorage语法 :
存数据: localStorage.setItem(‘属性名’,属性值)
取数据: localStorage.getItem(‘属性名’)
删数据: localStorage.removeItem(‘属性名’)
* 清空数据: localStorage.clear()
3.localStorage注意点 :
3.1 永久存储 : 除非手动清除,否则一直存在
3.2 只能存储字符串类型,如果存储其他类型,编译器会自动toString()转成字符串来存储

2.sessionStroage 内存存储(临时存储)

  1. 1.sessionStorage对象作用 : 存储数据<br /> 2.sessionStorage语法 :<br /> * 存数据: sessionStorage.setItem('属性名',属性值)<br /> * 取数据: sessionStorage.getItem('属性名')<br /> * 删数据: sessionStorage.removeItem('属性名')<br /> * 清空数据: sessionStorage.clear()<br /> 3.sessionStorage注意点 : <br /> 3.1 临时存储 只要页面关闭了,就自动清除了<br /> 3.2 只能存储字符串类型,如果存储其他类型,编译器会自动toString()转成字符串来存储

3.localStorage和sessionStorage的注意点

1.localStorage和sessionStorage的区别?
相同点: 作用相同,都是存储数据
不同点:存储方式不同
localStorage : 硬盘存储(永久存储)
应用场景: 免登录
sessionStorage : 内存存储 (临时存储)
应用场景: 页面间传值
2.localStorage和sessionStorage在用的时候有什么注意点吗?
只能存储字符串类型数据, 如果存储其他类型则编译器自动调用toString()转成字符串
3.如何解决storage存储对象只能存储字符串问题? (如何存储引用类型)
使用json格式存储

3,JSON格式数据介绍

1.json是什么? : json是一种数据格式,本质是字符串类型
实际开发中,网页中的数据都是来源于网络服务器。 而服务器不是js语言开发,而是其他编程语言 : java、c++、python、go、c#、.net …. 而且后台也不是只为前端服务,也要为安卓端和ios 端服务器。
不同的编程语言,数据类型不同。他们是不互通的。后来人们就发明了一种通用的数据格式,让所有的编程语言都支持。这就是json格式。
2.json作用 ? : 数据跨平台传输问题
3.json语法 ? : 本质是字符串
3.1 json转js : let js对象 = JSON.parse(json格式)
3.2 js转json : let json格式 = JSON.stringify(js对象)

  1. <script>
  2. /*
  3. json转js 返回js对象 let obj = JSON.parse(json格式)
  4. js转json 返回JSON格式 let objJSON = JSON.stringify(js对象)
  5. */
  6. // js对象
  7. let obj = {
  8. name: 'pengyuyan',
  9. age: 18
  10. }
  11. // 1.js转JSON
  12. let JSON1 = JSON.stringify(obj)
  13. // JSON格式 本质是字符串
  14. let objJSON = '{"name":"zhang","age":"80"}'
  15. // 2.JSON转js
  16. let js = JSON.parse(objJSON)
  17. </script>

案例:保存用户信息

  1. <script>
  2. /*
  3. 1.分析需求(交互):
  4. 点击登录按钮 : (1)判断用户名密码长度 : 全部大于6 登录成功
  5. (2)如果登录成功
  6. (2.1)将用户名和密码写入本地存储,下一次登录时直接显示用户名和密码
  7. (2.2)跳转网页 http://www.itheima.com
  8. 2.思路分析(事件三要素)
  9. 获取元素:事件源:
  10. 注册事件:事件类型
  11. 事件处理:
  12. */
  13. let login = document.querySelector('.input_sub') //登录
  14. let text = document.querySelector('.input_txt') //账号
  15. let pass = document.querySelector('.input_pass') //密码
  16. console.log(login, text, pass)
  17. login.onclick = function () {
  18. if (text.value.length <= 6 || pass.value.length <= 6) {
  19. alert('请输入正确的账号和密码')
  20. text.value = ''
  21. pass.value = ''
  22. return
  23. }
  24. //存入本地
  25. localStorage.setItem('txt', text.value)
  26. localStorage.setItem('pass', pass.value)
  27. //跳转网页
  28. location.href = 'http://www.itheima.com'
  29. }
  30. window.onload = function () {
  31. //页面加载完成后,把在本地的账号和密码赋值给文本框的文本
  32. text.value = localStorage.getItem('txt')
  33. pass.value = localStorage.getItem('pass')
  34. }
  35. </script>