JavaScript学习记录

因为之前学过一点 就当作一个学习记录

JavaScript

是实现人机交互效果

  • 网络特效
  • 数据交互
  • 表单验证
  • 服务器编程

JS的组成

  • 基本语法ECMAscript
  • WebAPIS DOM(页面文档对象) BOM(浏览器对象模型)

输入输出语法

  • document.write() 在页面显示
  • alert() 弹出警示框
  • prompt() 弹出询问框
  • console.log() 在打印台上打印

字面量是指在计算机中描述事/物

变量

计算机存储数据的容器,可以让计算机变得有记忆

  • 声明变量:创建变量let/const+变量名
  • eg let a = 10
  • 更新变量:变量赋值后还可以通过简单地给她一个不同的值来更新
  • 多行变量

数组

可以存放多个变量 let arr = [] 

加号可以使字符串变成数据型

eg: let a = +prompt('‘)

添加元素: push() unshift() 一个是在末尾添加 一个是在开头添加 都是可以删除好几个元素

删除元素:pop() 删除最后一个元素 shift() 删除最前的一个元素  splice(index,length) 删除指定位置的元素 

排序sort:

默认是升序排序

降序排序:

arr.sort(function(a,b){

return b-a}

形参和实参

形参等于上述例子的a,b 是形式上的参数

实参就是实际的参数值 即对函数的赋值 eg add(10,2) 10和2就是实参

函数返回值

return

return和break的区别 return是结束函数 break是结束循环

作用域 

可用性的代码范围就是作用域

立即执行函数 在函数function前后加括号

例子一 时间转换(将秒数转换成xxhxxminxxs形式)

小时H = parseInt(sum/60/60%24)\

分钟M = parseInt(sum/60%60)

秒数S = parseInt(sum%60)

逻辑中断

&& 与 || 或 (3>5)&&0 如果前面为false后面的语句就不执行 

对象object

是一种数据类型 一种无序的数据集合,数组是有序的数据集合,其实就相当于java中的字典

成对出现,包括属性名和属性值

有增删改查四个基本操作 delete是删除指令 没有查询到时会返回NaN

遍历采用for(let k in obj){console.log(k) console.log(obj[k])

内置对象

js内部提供的对象包括各种属性的方法和开发者调用,最常用的就是Math(ceil/Pi/floor/max/min/round)

生成随机数:Math.floor(Math.random()*(M-N+1))+N

新生成的空间存放在栈里面 和new比较像吧

一个抽奖的练习:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <div class="wrapper">
    <strong>抽奖</strong>
    <h1>一等奖:<span id="one">???</span></h1>
    <h3>二等奖:<span id="two">???</span></h3>
    <h5>三等奖:<span id="three">???</span></h5>
  </div>
  <script>
    const arr = ['周杰伦', '刘德华', '周星驰', 'pink', '张学友']
    const random = Math.floor(Math.random() * arr.length)
    const one = document.querySelector('#one') //querySelector()寻找对象
    const two = document.querySelector('#two')
    const three = document.querySelector('#three')
    one.innerHTML = arr[random] //innerHTML() 修改对象里面的内容
    arr.splice(random, 1)
    const random2 = Math.floor(Math.random() * arr.length)
    two.innerHTML = arr[random]
    arr.splice(random2, 1)
    const random3 = Math.floor(Math.random() * arr.length)
    three.innerHTML = arr[random3]
  </script>
</body>

</html>

WebAPIS

DOM-文件对象模型

直观的体现了标签与标签之间的关系

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

用css选择器获取dom元素

document.querySelector('css选择器')

document.querySelectorAll()

nav.style.color = 'red' 可以修改颜色

操作元素内容

  • innerText:不解析标签
  • innerHTML:会解析标签

修改样式 是用style修改的

  • className
  • classList.add 添加样式 remove 删除样式 不加.

toggle 切换样式 有就删掉 没有就加上 

定时器

间歇函数 let 变量名 = setInterval(函数,间隔时间)

关闭定时器 clearInterval(变量名)

例子三 定时轮播图

<script>
    const sliderData = [
      { url: './images/slider01.jpg', title: '对人类来说会不会太超前了?', color: 'rgb(100, 67, 68)' },
      { url: './images/slider02.jpg', title: '开启剑与雪的黑暗传说!', color: 'rgb(43, 35, 26)' },
      { url: './images/slider03.jpg', title: '真正的jo厨出现了!', color: 'rgb(36, 31, 33)' },
      { url: './images/slider04.jpg', title: '李玉刚:让世界通过B站看到东方大国文化', color: 'rgb(139, 98, 66)' },
      { url: './images/slider05.jpg', title: '快来分享你的寒假日常吧~', color: 'rgb(67, 90, 92)' },
      { url: './images/slider06.jpg', title: '哔哩哔哩小年YEAH', color: 'rgb(166, 131, 143)' },
      { url: './images/slider07.jpg', title: '一站式解决你的电脑配置问题!!!', color: 'rgb(53, 29, 25)' },
      { url: './images/slider08.jpg', title: '谁不想和小猫咪贴贴呢!', color: 'rgb(99, 72, 114)' },
    ]
    const img = document.querySelector('.slider-wrapper img')
    const p = document.querySelector('.slider-footer p')
    const footer = document.querySelector('.slider-footer')
    let i = 0
    setInterval(function () {
      i++
      if (i == sliderData.length) {
        i = 0
      }
      img.src = sliderData[i].url
      p.innerHTML = sliderData[i].title
      footer.style.backgroundColor = sliderData[i].color
      document.querySelector(`.slider-indicator .active`).classList.remove('active')
      document.querySelector(`.slider-indicator li:nth-child(${i + 1})`).classList.add('active')

    }, 1000)
</script>

2024.5.22

事件监听

利用程序检测是否有事件产生,一旦有事件出发,就立即调用一个函数做出响应

三要素:

  • 事件源:谁被触发
  • 事件类型:用什么方式出发
  • 事件处理程序:要做什么事情

addEventListener(‘事件类型’,要执行的函数)

eg: btn.addEventListener('click',function(){

button.style.display = 'none'})

on方式会被覆盖 addel方法就可以绑定多个事件,拥有时间更多特性因此更适合使用

常用的事件类型:

  • click
  • mouseleave
  • mouseenter
  • focus
  • blur
  • keydown
  • keyup
  • input 用户输入事件 total.value.length(可以获取输入长度)

事件对象

也是个对象,这个对象里有时间触发时的相关信息

常见部分属性

  • type 当前事件类型
  • clientX/clientY 获取光标相对于浏览器可见窗口左上角的位置
  • offsetX/offsetY 获取光标相对于当前DOM元素左下角的位置
  • key 用户按下键盘的值

trim()

会去除左右的空格

环境对象

变量this 代表当前函数运行时所处的环境

谁调用this就指向谁 

回调函数

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

今天做的几个例子

1.随机点名 按下开始键时随机滚动 按下停止时显示一个名字,并从数组中删除。当数组只剩下最后一个值时冻结开始停止按钮

<script>
    const arr = ['马超', '黄忠', '赵云', '关羽', '张飞']
    //<!-- 开始按钮模块 -->
    const start = document.querySelector('.btns .start')
    const end = document.querySelector('.btns .end')
    const qs = document.querySelector('.qs')
    let n = 0
    let random = 0
    start.addEventListener('click', function () {
      n = setInterval(function () {
        random = Math.floor(Math.random() * arr.length)
        qs.innerHTML = arr[random]
      }, 100)
      //当数组只剩下一个元素时,禁止使用开始和结束按钮
      if (arr.length === 1) {
        start.disabled = true
        end.disabled = true
      }
    })
    //结束按钮模块
    end.addEventListener('click', function () {
      clearInterval(n)
      arr.splice(random, 1)
    })
 </script>

2.轮播图点击切换,在原先的基础上,划过页面暂停播放,离开页面继续播放,点击左键会切换到上一页,点击右键会切换到下一页

<script>
    const sliderData = [
      { url: './images/slider01.jpg', title: '对人类来说会不会太超前了?', color: 'rgb(100, 67, 68)' },
      { url: './images/slider02.jpg', title: '开启剑与雪的黑暗传说!', color: 'rgb(43, 35, 26)' },
      { url: './images/slider03.jpg', title: '真正的jo厨出现了!', color: 'rgb(36, 31, 33)' },
      { url: './images/slider04.jpg', title: '李玉刚:让世界通过B站看到东方大国文化', color: 'rgb(139, 98, 66)' },
      { url: './images/slider05.jpg', title: '快来分享你的寒假日常吧~', color: 'rgb(67, 90, 92)' },
      { url: './images/slider06.jpg', title: '哔哩哔哩小年YEAH', color: 'rgb(166, 131, 143)' },
      { url: './images/slider07.jpg', title: '一站式解决你的电脑配置问题!!!', color: 'rgb(53, 29, 25)' },
      { url: './images/slider08.jpg', title: '谁不想和小猫咪贴贴呢!', color: 'rgb(99, 72, 114)' },
    ]
    const all = document.querySelector('.slider')
    const left = document.querySelector('.prev')
    const right = document.querySelector('.next')
    const img = document.querySelector('.slider-wrapper img')
    const p = document.querySelector('.slider-footer p')
    const footer = document.querySelector('.slider-footer')
    let i = 0
    let timer = 0
    timer = setInterval(function () {
      right.click()
    }, 1000)
    //给左键点击添加事件
    left.addEventListener('click', function () {
      i--
      //如果小于0 则将i重新置于最大处
      if (i < 0) {
        i = sliderData.length - 1
      }
      img.src = sliderData[i].url
      p.innerHTML = sliderData[i].title
      footer.style.backgroundColor = sliderData[i].color
      document.querySelector(`.slider-indicator .active`).classList.remove('active')
      document.querySelector(`.slider-indicator li:nth-child(${i + 1})`).classList.add('active')
    })
    //右键点击事件
    right.addEventListener('click', function () {
      i++
      //如果i为最大值 则重新置于0
      if (i == sliderData.length) {
        i = 0
      }
      img.src = sliderData[i].url
      p.innerHTML = sliderData[i].title
      footer.style.backgroundColor = sliderData[i].color
      document.querySelector(`.slider-indicator .active`).classList.remove('active')
      document.querySelector(`.slider-indicator li:nth-child(${i + 1})`).classList.add('active')
    })
    //鼠标进入事件
    all.addEventListener('mouseenter', function () {
      clearInterval(timer)
    })
    //鼠标离开事件
    all.addEventListener('mouseleave', function () {
      timer = setInterval(function () {
        right.click()
      }, 1000)
    })
 </script>

3.小米搜索框 考察focus和blur 当focus定位是显示下拉列表 离开时不显示

 <script>
    const input = document.querySelector('[type=search]')
    const ul = document.querySelector('.result-list')
    //添加焦点
    input.addEventListener('focus', function () {
      ul.style.display = 'block'
      //添加带有颜色的边框
      input.classList.add('search')
    })
    //失去焦点
    input.addEventListener('blur', function () {
      ul.style.display = 'none'
      //删除边框属性
      input.classList.remove('search')
    })
 </script>

4.评论数字统计 考察input,keyup,trim()和tx.value.length

 <script>
    const tx = document.querySelector('#tx')
    const total = document.querySelector('.total')
    const list = document.querySelector('.list')
    const item = document.querySelector('.item')
    const text = document.querySelector('.text')
    //focus聚焦事件
    tx.addEventListener('focus', function () {
      total.style.opacity = 1
    })
    //blur事件
    tx.addEventListener('blur', function () {
      total.style.opacity = 0
    })
    //input事件
    tx.addEventListener('input', function () {
      //统计字数,实时更新
      total.innerHTML = `${tx.value.length}/200字`
    })
    //keyup事件
    tx.addEventListener('keyup', function (e) {
      //当输入的值为Enter时 触发事件
      if (e.key === 'Enter') {
        //去除左右两边空格
        if (tx.value.trim() !== '') {
          item.style.display = 'block'
          text.innerHTML = tx.value
        }
        //上传评论后清空value
        tx.value = ''
      }
    })
 </script>

5.综合案例

<script>
    //1. a模块制作
    //先选中所有a
    const as = document.querySelectorAll('.tab-nav a')
    //依次遍历添加事件
    for (let i = 0; i < as.length; i++) {
      as[i].addEventListener('mouseenter', function () {
        document.querySelector('.tab-nav .active').classList.remove('active')
        this.classList.add('active')
        document.querySelector('.tab-content .active').classList.remove('active')
        document.querySelector(`.tab-content .item:nth-child(${i + 1})`).classList.add('active')
      })
    }
</script>

2024.5.23

事件流 

指的是事件完整执行饿流动路径

捕获阶段

从DOM的根元素去执行对应的事件 从外到里

addEventListener

默认是false 要捕获就设置为true

点击儿子会执行父亲和爷爷

冒泡阶段

默认都是冒泡 会导致事件影响父级元素

阻止冒泡

前提:拿到事件对象

需求:阻止事件冒泡

stopPropagation()

preventDefault()

解绑事件

  • on事件
  • removeEventListener

mouseover mouseout会发生冒泡现象 最好用mouseenter mouseleave

事件委托

利用事件流特征解决一些开发需求的知识技巧

优点:减少注册次数 可以提高程序性能

原理 利用事件冒泡的特点

e.value.length

e.target 就是点击的对象

e.target.tagName 后面是字符串且必须大写

data-id 自定义属性

其他事件

事件解绑

两种方法

  • on 给on事件添加null属性

  • removeEventListener()

事件委托

e.target.tagName ==="大写" 这种事件才会被选中

案例

<script>
    //给li标签添加事件触发
    const ul = document.querySelector('ul')
    ul.addEventListener('click', function (e) {
      if (e.target.tagName === 'LI') {
        e.target.style.color = 'red'
      }
    })
</script>
页面加载事件 DOMContentLoaded
 <script>
    document.addEventListener('DOMContentLoaded', function () {
      const btn = document.querySelector('botton')
      btn.addEventListener('click', function () {
        alert(11)
      })
</script>
页面滚动事件 scroll
<script>
    //可以被读写
    document.documentElement.scrollTop = 800//不带单位
    const div = document.querySelector('div')
    window.addEventListener('scroll', function () {
      //可以得到向上滚动了多少
      console.log(document.documentElement.scrollTop)
      if (n >= 100) {
        div.style.display = 'block'
      } else {
        div.style.display = 'none'
      }
    })
</script>
页面尺寸事件 resize
<script>
    const div = document.querySelector('div')
    console.log(div.clientHeight)
    console.log(div.clientWidth)
    //resize 浏览器窗口大小发生变化的时候触发事件
    window.addEventListener('resize', function () {
    //
    })
</script>

今天的几个案例

案例一:点击全选按钮勾选所有按钮 点击全部子按钮则全选按钮被选上

<script>
    //id选择器
    const checkall = document.querySelector('#checkAll')
    const cks = document.querySelectorAll('.check')
    checkall.addEventListener('click', function () {
      for (let i = 0; i < cks.length; i++) {
        cks[i].checked = checkall.checked
      }
    })
    for (let i = 0; i < cks.length; i++) {
      cks[i].addEventListener('click', function () {
        //伪类选择器
        checkall.checked = document.querySelectorAll('.ck:checked').length === cks.length
      })
    }
</script>

案例二:页面切换 点击切换播放图片

  <script>
    const ul = document.querySelector('.tab-nav ul')
    //获取父亲
    ul.addEventListener('click', function (e) {
      if (e.target.tagName == 'A') {
        document.querySelector('.tab-nav .active').classList.remove('active')
        e.target.classList.add('active')
        document.querySelector('.tab-content .active').classList.remove('active')
        //这里要转换成数字类型
        const i = +e.target.dataset.id
        document.querySelector(`.tab-content .item:nth-child${i + 1}`).add('active')
      }
    })
 </script>

案例三:仿新浪固定头部 当滑到一定top值固定头部页面

  <script>
    const header = document.querySelector('.header')
    const sk = document.querySelector('.sk')
    window.addEventListener('scroll', function () {
      const n = document.documentElement.scrollTop
      if (n >= sk.offsetTop) {
        sk.style.top = 0
      } else {
        sk.style.top = '-80px'
      }
    })
  </script>

案例四:电梯导轨

  <script>
    //第一大模块 页面滑动可以显示和隐藏
    (function () {
      //获取元素
      const entry = document.querySelector('.xtx_entry')
      //当滚动距离大于300时显示
      const elevator = document.querySelector('.xtx-elevator')
      window.addEventListener('scroll', function () {
        const n = document.documentElement.scrollTop
        elevator.style.opacity = n >= entry.offsetTop ? 1 : 0
      })
      //点击返回页面顶部
      const backTop = document.querySelector('#backTop')
      backTop.addEventListener('click', function () {
        window.scrollTo(0, 0)
      })
    })();
    //第二大模块
    (function () {
      const list = document.querySelector('.xtx-elevator-list')
      list.addEventListener('click', function (e) {
        if (e.target.tagName === 'A' && e.target.dataset.name) {
          //document.querySelector('.xtx-elevator-list .active').classList.remove('active')
          //不能直接获取这个类
          const old = document.querySelector('.xtx-elevator-list .active')
          if (old) old.classList.remove('active')
          e.target.classList.add('active')
          const top = document.querySelector(`.xtx_goods_${e.target.dataset.name}`).offsetTop
          //让页面滚动
          document.documentElement.scrollTop = top
        }
      })
      window.addEventListener('scroll', function () {
        const old = document.querySelector('.xtx-elevator-list .active')
        if (old) old.classList.remove('active')
        //当在此区域时,侧边栏显示区域名称
        const news = document.querySelector('.xtx_goods_new')
        const populer = document.querySelector('.xtx_goods_popular')
        const brand = document.querySelector('.xtx_goods_brand')
        const topic = document.querySelector('.xtx_goods_topic')
        //获得当前滚动值
        const n = document.documentElement.scrollTop
        if (n >= news.offsetTop && n < populer.offsetTop) {
          document.querySelector('[data-name=new]').classList.add('active')
        } else if (n >= populer.offsetTop && n < brand.offsetTop) {
          document.querySelector('[data-name=popular]').classList.add('active')
        } else if (n >= brand.offsetTop && n < topic.offsetTop) {
          document.querySelector('[data-name=brand]').classList.add('active')
        } else if (n >= topic.offsetTop) {
          document.querySelector('[data-name=topic]').classList.add('active')
        }
      })
    })();
  </script>

2024.5.24

事件对象

const date = new Date()

日期对象方法

能够使用日期对象中的方法写出常见的日期格式

getMonth() 取值范围是0~11 getDay()获得星期 因此这两个都要加上一

时间表示格式的几种方式

  • date.toLocaleString() xxxx/xx/xx xx:xx:xx
  • date.toLocaleDateString() xxxx/xx/xx
  • date.toLocaleTimeString() xxxx/xx/xx

时间戳

能够获得当前时间戳

指的从1970年起到现在的毫秒数

三种方式

  • getTime()
  • **+new Date()**
  • Date.now() 只能获得当前的

节点操作

对标签进行增删改查

Dom节点 dom树里面的每一个内容

节点类型

  • - 元素节点 可以让我们理清标签元素之间的关系

所有的标签 body div

html是根节点

  • - 属性节点

所有的属性 href

  • - 文本节点

所有的文本

  • - 其他

查找节点

利用节点之间的关系

  • 父节点查找 son.parentNode
  • 子节点 ul.children
  • 兄弟节点 nextElementSibling previousElementSibling

添加节点

document.createElement('div')

fu.appendchild 插入到最后

fu.insertBefore(要插入的元素,在哪个元素之前)

克隆节点 ele.cloneElement

删除节点    fu.removeChild

M端事件 移动端事件

  • touchstart 
  • touchmove
  • touchend

今日案例

案例一:点击关闭案例,利用孩子对父亲进行操作 parentNode

  <script>
    /* const box1 = document.querySelector('.box1')
    box1.addEventListener('click', function () {
      this.parentNode.style.display = 'none'
    }) */
    const closeBtn = document.querySelectorAll('.box1')
    for (let i = 0; i < closeBtn.length; i++) {
      closeBtn[i].addEventListener('click', function () {
        //点击孩子,隐藏父亲模块
        this.parentNode.style.opacity = 0
      })
    }
  </script>

案例二:毕业倒计时效果 用+new Date() 获得时间戳

<script>
    //随机颜色函数
    function getRandomColor(flag = true) {
      if (flag) {
        let str = '#'
        let arr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f']
        for (let i = 1; i <= 6; i++) {
          let random = Math.floor(Math.random() * arr.length)
          str += arr[random]
        }
        return str
      } else {
        let r = Math.floor(Math.random() * 256)
        let b = Math.floor(Math.random() * 256)
        let g = Math.floor(Math.random() * 256)
        return `rgb(${r},${g},${b})`
      }
    }
    const countdown = document.querySelector('.countdown')
    countdown.style.backgroundColor = getRandomColor()
    //倒计时模块
    function getCountTime() {
      const hour = document.querySelector('#hour')
      const minutes = document.querySelector('#minutes')
      const second = document.querySelector('#scond')
      //得到当前的时间戳
      const now = +new Date()
      //得到将来的时间戳
      const last = +new Date('2024-05-25 18:30:00')
      //剩余的时间戳
      const count = (last - now) / 1000
      let h = parseInt(count / 60 / 60 % 24)
      let m = parseInt(count / 60 % 60)
      let s = parseInt(count % 60)
      h = h < 10 ? '0' + h : h
      m = m < 10 ? '0' + m : m
      s = s < 10 ? '0' + s : s
      hour.innerHTML = h
      minutes.innerHTML = m
      second.innerHTML = s
    }
    getCountTime()
    setInterval(getCountTime, 1000)
  </script>

案例三 学成在线案例 利用父亲添加孩子 createElement()

<script>
    // 1. 重构  
    let data = [
      {
        src: 'images/course01.png',
        title: 'Think PHP 5.0 博客系统实战项目演练',
        num: 1125
      },
      {
        src: 'images/course02.png',
        title: 'Android 网络动态图片加载实战',
        num: 357
      },
      {
        src: 'images/course03.png',
        title: 'Angular2 大前端商城实战项目演练',
        num: 22250
      },
      {
        src: 'images/course04.png',
        title: 'Android APP 实战项目演练',
        num: 389
      },
      {
        src: 'images/course05.png',
        title: 'UGUI 源码深度分析案例',
        num: 124
      },
      {
        src: 'images/course06.png',
        title: 'Kami2首页界面切换效果实战演练',
        num: 432
      },
      {
        src: 'images/course07.png',
        title: 'UNITY 从入门到精通实战案例',
        num: 888
      },
      {
        src: 'images/course08.png',
        title: 'Cocos 深度学习你不会错过的实战',
        num: 590
      },
    ]
    //获得父亲
    const ul = document.querySelector('.box-bd ul')
    for (let i = 0; i < data.length; i++) {
      //创建孩子
      const li = document.createElement('li')
      //
      li.innerHTML = `
      <a href="#">
        <img src = ${data[i].src}>
        <h4>
          ${data[i].title}
        </h4>
        <div class="info">
          <span>高级</span>·<span>${data[i].num}</span>人在学习
        </div>
      </a>
      `
      //父亲加入孩子到最后 insertBefore()是加在最前面
      ul.appendChild(li)
    }
  </script>

案例四:学生信息管理 综合案例

  <script>
    // 获取元素
    const uname = document.querySelector('.uname')
    const age = document.querySelector('.age')
    const gender = document.querySelector('.gender')
    const salary = document.querySelector('.salary')
    const city = document.querySelector('.city')
    const tbody = document.querySelector('tbody')
    // 获取所有带有name属性的元素
    const items = document.querySelectorAll('[name]')
    // 声明一个空的数组, 增加和删除都是对这个数组进行操作
    const arr = []

    // 1. 录入模块
    // 1.1 表单提交事件
    const info = document.querySelector('.info')
    info.addEventListener('submit', function (e) {
      // 阻止默认行为 不跳转
      e.preventDefault()
      // 这里进行表单验证  如果不通过,直接中断,不需要添加数据
      // 先遍历循环
      for (let i = 0; i < items.length; i++) {
        if (items[i].value === '') {
          return alert('输入内容不能为空')
        }
      }
      // 创建新的对象
      const obj = {
        stuId: arr.length + 1,
        uname: uname.value,
        age: age.value,
        gender: gender.value,
        salary: salary.value,
        city: city.value
      }
      // 追加给数组里面
      arr.push(obj)
      // 清空表单 重置 
      this.reset()
      // 调用渲染函数
      render()
    })

    // 2. 渲染函数 因为增加和删除都需要渲染
    function render() {
      // 先清空tbody 以前的行 ,把最新数组里面的数据渲染完毕 
      tbody.innerHTML = ''
      // 遍历arr数组
      for (let i = 0; i < arr.length; i++) {
        // 生成 tr 
        const tr = document.createElement('tr')
        tr.innerHTML = `
          <td>${arr[i].stuId}</td>
          <td>${arr[i].uname}</td>
          <td>${arr[i].age}</td>
          <td>${arr[i].gender}</td>
          <td>${arr[i].salary}</td>
          <td>${arr[i].city}</td>
          <td>
            <a href="javascript:" data-id=${i}>删除</a>
          </td>
        `
        // 追加元素  父元素.appendChild(子元素)
        tbody.appendChild(tr)
      }
    }

    // 3. 删除操作
    // 3.1 事件委托 tbody
    tbody.addEventListener('click', function (e) {
      if (e.target.tagName === 'A') {
        // 得到当前元素的自定义属性 data-id
        // 删除arr 数组里面对应的数据
        arr.splice(e.target.dataset.id, 1)
        // 重新渲染一次
        render()
      }
    })
  </script>

2024.5.26

BOM 浏览器对象模型windows

定时器-延时函数SetTimeout()

只执行一次,可以理解为把一段代码延迟执行

每次调用延时器都会产生一个新的延时器,返回是一个数字

js的执行机制

单线程:同一时间制作一件事情

利用多核CPU的计算能力,HTML5提出了web worker标准,用于js脚本创建多个线程,于是提出了同步和异步

  • 同步:前一个任务结束后再执行后一个任务,执行顺序和任务的排列顺序是一致的
  • 同步任务:都在主线程上执行,形成一个执行栈
  • 异步:在做一件事情的同时,可以去处理其他事情
  • 异步任务:通过回调函数实现的,异步任务相关条件到任务队列中(消息队列),eg:click resize load error setInterval setTimeout

事件循环(event loop):执行机制:(1)先执行执行栈中的同步任务 (2)异步任务放入任务队列中 (3)一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行。由于主线程不断的重复获得任务、执行任务、再获取任务、再执行这种机制被称为事件循环

都是132

location对象

location的数据类型是对象,它拆分并保存了URL地址的各个组成部分

  • location.search 返回?后面的属性
  • location.href :实现页面跳转
  • location.hash 获得#后面的部分
  • reload(true) 刷新当前的页面 是一个方法

navigator对象

<script>
    // 检测 userAgent(浏览器信息)
    !(function () {
      const userAgent = navigator.userAgent
      // 验证是否为Android或iPhone
      const android = userAgent.match(/(Android);?[\s\/]+([\d.]+)?/)
      const iphone = userAgent.match(/(iPhone\sOS)\s([\d_]+)/)
      // 如果是Android或iPhone,则跳转至移动站点
      if (android || iphone) {
        location.href = 'http://m.itcast.cn'
      }
    })();
    // !(function () { })();
    !function () { }()
  </script>

history对象

  • back()  后退
  • forward() 前进功能
  • go(参数)

本地存储

什么是本地存储:数据存储在用户浏览器中

本地存储分类

localstorage

能够使用localstorage把数据存储在浏览器中

作用:可以将数据永久存储在本地,除非手动删除,否则关闭页面也会存在

特性:多窗口共享 以键值对的形式存储

语法:

  • 存储数据:localStorage.setItem(key,value)
  • 得到数据:localStorage.getItem('uname')
  • 删除数据:localStorage.removeItem('uname')
  • 修改数据:localStorage.setItem('uname','red)

本地存储分类 sessionStorage

生命周期为关闭浏览器窗口 使用方法和localStorage基本相同

存储复杂数据类型

  • 无法直接使用,首先使用JSON.stringify(obj)
  • 再转回去JSON.parse(localStorage.getItem('obj'))

拼接map()  join() 一般两个连用

map有返回值,但是foreach没有返回值、

join将数组中的所有元素转换一个字符串

今日案例

案例一:五秒之后广告自动消失 考察setTimeout()

<script>
    let img = document.querySelector('img')
    let n = setTimeout(function () {
      img.style.display = 'none'
    }, 5000)
</script>

案例二:五秒自动跳转网站 考察setInverval location.href

<script>
    const a = document.querySelector('a')
    let num = 5
    let n = setInterval(function () {
      num--
      a.innerHTML = `支付成功<span>${num}</span>秒后跳转网页`
      if (num == 0) {
        //停止计时器
        clearInterval(n)
        //完成自动跳转
        location.href = 'http://www.baidu.com'
      }
    }, 1000)
</script>

案例三:综合案例 学生信息表 考察localStorage.setItem map join confirm arr[arr.length-1].stuId+1

 <script>
    // 参考数据
    //const initData = [
    //  {
    //    stuId: 1001,
    //    uname: '欧阳霸天',
    //    age: 19,
    //    gender: '男',
    //    salary: '20000',
    //    city: '北京',
    //    time: '2024/5/26'
    //  }
    //] 
    //localStorage.setItem('data', JSON.stringify(initData)) 
    const arr = JSON.parse(localStorage.getItem('data')) || []
    const tbody = document.querySelector('tbody')
    function render() {
      let trArr = arr.map(function (ele, index) {
        //添加自定义属性方便后续处理
        return `
        <tr>
          <td>${ele.stuId}</td>
          <td>${ele.uname}</td>
          <td>${ele.age}</td>
          <td>${ele.gender}</td>
          <td>${ele.salary}</td>
          <td>${ele.city}</td>
          <td>${ele.time}</td>
          <td>
            <a href="javascript:" data-id = "${index}">删除</a>
          </td>
        </tr> `
      })
      tbody.innerHTML = trArr.join('')
      document.querySelector('.title span').innerHTML = arr.length
    }
    //重新渲染
    render()
    //进行元素添加
    const info = document.querySelector('.info')
    const uname = document.querySelector('.uname')
    const age = document.querySelector('.age')
    const salary = document.querySelector('.salary')
    const gender = document.querySelector('.gender')
    const city = document.querySelector('.city')
    info.addEventListener('submit', function (e) {
      e.preventDefault()
      if (!uname.value || !age.value || !salary.value) {
        return alert('输入内容不能为空')
      }
      arr.push({
        stuId: arr.length ? [arr.length - 1].stuId + 1 : 1,
        uname: uname.value,
        age: age.value,
        gender: gender.value,
        salary: salary.value,
        city: city.value,
        time: new Date().toLocaleString()
      })
      this.reset()
      render()
      localStorage.setItem('data', JSON.stringify(arr))
    })
    tbody.addEventListener('click', function (e) {
      if (e.target.tagName === 'A') {
        console.log(e.target.dataset.id)
        if (confirm('您确定要删除这条数据吗?')) {
          arr.splice(e.target.dataset.id, 1)
          render()
          localStorage.setItem('data', JSON.stringify(arr))
        }
      }
    })
  </script>
  • 13
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值