小兔鲜注册页面验证、阶段案例(登录、首页页面)(重点)、小兔鲜放大镜效果——DOM

news2024/11/24 4:06:07

目录

1. 小兔鲜注册页面验证

2. 阶段案例(登录、首页页面)(重点)

 3. 小兔鲜放大镜效果

1. 小兔鲜注册页面验证

 验证码模块有个小问题:

      连续点击获取验证码会导致触发多次计时器,会导致计时出现问题,为了解决这个问题,可以设置一个变量来控制。如 flag = true  当触发点击事件时,首先判断 flag,为真则进入函数,否则不执行,进入函数后首先将 flag取反,然后当计时结束时,再设置 flag = true.

 侦听使用 change 事件,当鼠标离开了表单,并且表单值发生了变化时触发

对于同意模块使用的是小图标,而不是单选多选框,勾选的话应该为 i标签再添加一个类icon-queren2

classList.contains( )  看看有没有包含某个类,如果有则返回 true,没有则返回false

  <script>
    // 使用立即执行函数,避免变量污染
    (function(){
      // 1.发送短信验证码模块
      const code = document.querySelector('.xtx-form a.code')
      let flag = true //通过一个变量来控制
      // 1.1 点击事件
      code.addEventListener('click', function(){
        if (flag) {
          // 取反了,不能马上第二次点击
          flag = false
          let i = 5
          code.innerHTML = `0${i}s后重新获取`
          let timer = setInterval(function(){
            i--
            code.innerHTML = `0${i}s后重新获取`
            if (i === 0) {
              clearInterval(timer)
              code.innerHTML = `重新获取`
              // 到时间了,可以开启 flag了
              flag = true
            }        
          }, 1000)
        }
      })
    })();


    // 2. 验证用户名
    // 2.1 获取用户名表单
    const username = document.querySelector('.xtx-form [name=username]')
    // 2.2 使用change 事件  值发生变化的时候
    username.addEventListener('change', verifyName)
   
    // 2.3 封装函数
    function verifyName() {
      // console.log(00);
      const span =  username.nextElementSibling
      // 2.4 定规则 用户名
      const reg = /^[a-zA-Z0-9-_]{6,10}$/
      if (!reg.test(username.value)) {
        span.innerHTML = '用户名输入有误,请输入6~10位'
        return false
      }
      // 2.5 合法的   就清空 span
      username.nextElementSibling.innerHTML = ''
      return true
    }

    // 3. 验证手机号
    // 3.1 获取手机号表单
    const phone = document.querySelector('.xtx-form [name=phone]')
    // 3.2 使用change 事件  值发生变化的时候
    phone.addEventListener('change', verifyPhone)
    // 3.3 封装函数
    function verifyPhone() {
      // console.log(00);
      const span =  phone.nextElementSibling
      // 3.4 定规则 手机号
      const reg = /^1(3\d|4[5-9]|5[0-35-9]|6[567]|7[0-8]|8\d|9[0-35-9])\d{8}$/
      if (!reg.test(phone.value)) {
        span.innerHTML = '输入有误,请输入正确的手机号'
        return false
      }
      // 3.5 合法的   就清空 span
      phone.nextElementSibling.innerHTML = ''
      return true
    }

    // 4. 验证验证码
    // 4.1 获取验证码表单
    const code = document.querySelector('.xtx-form [name=code]')
    // 4.2 使用change 事件  值发生变化的时候
    code.addEventListener('change', verifyCode)
    // 4.3 封装函数
    function verifyCode() {
      // console.log(00);
      const span =  code.nextElementSibling
      // 4.4 定规则 验证码
      const reg = /^\d{6}$/
      if (!reg.test(code.value)) {
        span.innerHTML = '输入有误,请输入正确的验证码'
        return false
      }
      // 4.5 合法的   就清空 span
      code.nextElementSibling.innerHTML = ''
      return true
    }


    // 5. 验证密码
    // 5.1 获取密码表单
    const password = document.querySelector('.xtx-form [name=password]')
    // 5.2 使用change 事件  值发生变化的时候
    password.addEventListener('change', verifyPassword)
    // 5.3 封装函数
    function verifyPassword() {
      // console.log(00);
      const span =  password.nextElementSibling
      // 5.4 定规则 密码
      const reg = /^[a-zA-Z0-9-_]{6,20}$/
      if (!reg.test(password.value)) {
        span.innerHTML = '输入有误,6~20位数字字母符号组成'
        return false
      }
      // 5.5 合法的   就清空 span
      password.nextElementSibling.innerHTML = ''
      return true
    }

    // 6. 密码的再次验证
    // 6.1 获取再次验证密码表单
    const confirm = document.querySelector('.xtx-form [name=confirm]')
    // 6.2 使用change 事件  值发生变化的时候
    confirm.addEventListener('change', verifyConfirm)
    // 6.3 封装函数
    function verifyConfirm() {
      // console.log(00);
      const span =  confirm.nextElementSibling
      // 当前表单的值不等于密码框的值就是错误的
      if (confirm.value !== password.value) {
        span.innerHTML = '两次输入密码不一致'
        return false
      }
      // 6.4 合法的   就清空 span
      confirm.nextElementSibling.innerHTML = ''
      return true
    }

    // 7. 我同意模块
    const agree = document.querySelector('.xtx-form-item .icon-queren')
    agree.addEventListener('click', function(){
      // 切换类,原来有就删掉,原来没有就添加
      this.classList.toggle('icon-queren2')
    })

    // 8. 表单提交模块
    const form = document.querySelector('form')
    form.addEventListener('submit', function(e){
      // 判断是否勾选我同意模块,如果有 icon-queren2 说明就勾选了,否则就没勾选
      if(!agree.classList.contains('icon-queren2')) {
        alert('请勾选同意协议')
        // 阻止提交
        e.preventDefault()
      }
      // 依次判断上面的每个框框是否通过, 只要有一个没有通过的就阻止
      // console.log(verifyName());
      if (!verifyName()) e.preventDefault()
      if (!verifyPhone()) e.preventDefault()
      if (!verifyCode()) e.preventDefault()
      if (!verifyPassword()) e.preventDefault()
      if (!verifyConfirm()) e.preventDefault()
    })
  </script>

2. 阶段案例(登录、首页页面)(重点)

小兔鲜登录页面

tab栏切换时,由于对应的 .tab-pane两个盒子没有设置 active类,所以最好不要为其设置active类,不能使用排他思想,故可将所有的 .tab-pane获得,将其隐藏起来(for循环),然后再为对应的盒子设置显示。

h5新属性 required属性 表示不能为空

  <script>
    // 1.tab栏切换
    const tab_nav = document.querySelector('.tab-nav')
    const pane = document.querySelectorAll('.tab-pane')
    // 1.1事件监听,使用事件委托
    tab_nav.addEventListener('click', function(e){
      if (e.target.tagName === 'A') {
        // 排他思想,去掉上一个active
        tab_nav.querySelector('.active').classList.remove('active')
        // 当前元素添加active
        e.target.classList.add('active')
        // 先干掉所有人,for循环
        for(let i = 0; i < pane.length; i++) {
          pane[i].style.display = 'none'
        }
        // 让对应序号的 大pane显示
        pane[e.target.dataset.id].style.display = 'block'
      }
    })

    // 2. 点击登录跳转页面
    const form = document.querySelector('form')
    const agree = form.querySelector('[name=agree]')
    const username = form.querySelector('[name=username]')
    form.addEventListener('submit', function(e){
      e.preventDefault()
      // 判断是否勾选同意协议
      if(!agree.checked){       
        return alert('请勾选同意协议')
      }
      // 将用户名记录到本地存储中
      localStorage.setItem('xtx-uname', username.value)
      // 跳转到首页
      location.href = 'index.html'
    })
  </script>

小兔鲜首页页面

 注意在渲染的时候渲染的是小 li 而不是 a ,因为当显示用户名时会切换链接地址和添加小图标,同时对于第二个是退出登录还是请先注册的链接地址也不一样,故给 li 的innerHTML渲染。

  <script>
    // 1. 获取li 元素
    const li1 = document.querySelector('.xtx_navs li:first-child')
    const li2 = li1.nextElementSibling
    // 2.最好做个渲染函数
    function render() {
      // 2.1 读取本地存储的用户名
      const uname = localStorage.getItem('xtx-uname')
      if(uname) {
        li1.innerHTML = `<a href="javascript:;"><i class="iconfont icon-user">${uname}</i></a>`
        li2.innerHTML = `<a href="javascript:;">退出登录</a>`
      } else {
        li1.innerHTML = `<a href="./login.html">请先登录</a>`
        li2.innerHTML = `<a href="./register.html">免费注册</a>`
      }
    }
    render()  //调用函数
    // 2. 点击退出登录
    li2.addEventListener('click', function(){
      // 删除本地存储的数据
      localStorage.removeItem('xtx-uname')
      // 重新渲染
      render()
    })
  </script>

 3. 小兔鲜放大镜效果

业务分析:

①:鼠标经过对应小盒子,左侧中等盒子显示对应中等图片

②: 鼠标经过中盒子,右侧会显示放大镜效果的大盒子

③: 黑色遮罩盒子跟着鼠标来移动

④: 鼠标在中等盒子上移动,大盒子的图片跟着显示对应位置

思路分析:

①:鼠标经过小盒子,左侧中等盒子显示对应中等图片

1. 获取对应的元素
2. 采取事件委托的形式,监听鼠标经过小盒子里面的图片, 注意此时需要使用 `mouseover` 事件,因为需要事件冒泡触发small,所以以后对于鼠标经过事件想用事件委托时使用 mouseover
3. 让鼠标经过小图片的爸爸li盒子,添加类,其余的li移除类(注意先移除,后添加)
4. 鼠标经过小图片,可以拿到小图片的src, 可以做两件事
   - 让中等盒子的图片换成这个 这个小图片的src
   - 让大盒子的背景图片,也换成这个小图片的 src (稍后做)

②: 鼠标经过中等盒子,右侧大盒子显示

1. 用到鼠标经过和离开,鼠标经过中盒子,大盒子 利用 display 来显示和隐藏

2. 鼠标离开不会立马消失,而是有200ms的延时,用户体验更好,所以尽量使用定时器做个延时 setTimeout

3. 显示和隐藏也尽量定义一个函数,因为鼠标经过离开中等盒子,会显示隐藏,同时,鼠标经过大盒子,也会显示和隐藏

4. 给大盒子里面的背景图片一个默认的第一张图片(去CSS样式中添加,因为在JS中写的大盒子背景是鼠标移入点击事件时把小盒子的图片地址给大盒子,但当页面一打开时,大盒子没有背景图片,此时移入中等盒子不会出现背景图片,有bug,所以我们应该给大盒子一个默认的第一张图片)

    function hide() {
      //  鼠标离开不会立马消失,而是有200ms的延时,使用setTimeout函数
      setTimeout(function(){
        large.style.display = 'none'
      }, 250)
    }

如果我们采用上面代码,会出现问题:鼠标一离开就开启一个定时器,所以当我们快速离开进入中等盒子时,会开启多个定时器,导致鼠标即使移入了中等盒子,但是由于定时器的隐藏效果会导致图片不显示。

因此,我们应该当鼠标进入中等盒子时,关掉定时器,采用如下写法:

    let timer = null
    function show() {
      // 先清除定时器
      clearTimeout(timer)
      large.style.display = 'block'
    }
    // 隐藏函数 隐藏大盒子
    function hide() {
      //  鼠标离开不会立马消失,而是有200ms的延时,使用setTimeout函数
      timer = setTimeout(function(){
        large.style.display = 'none'
      }, 250)
    }

③: 黑色遮罩盒子跟着鼠标来移动

1.  先做鼠标经过 中等盒子,显示隐藏 黑色遮罩 的盒子

2.  让黑色遮罩跟着鼠标来走, 需要用到鼠标移动事件  mousemove  

3. 让黑色盒子的移动的核心思想:不断把鼠标在中等盒子内坐标给黑色遮罩层 let  top 值,这样遮罩层就可以跟着移动了

   - 需求

     - 我们要的是 鼠标在 中等盒子内的坐标, 没有办法直接得到
     - 得到1:  鼠标在页面中的坐标
     - 得到2:  中等盒子在页面中的坐标

   - 算法

     - 得到鼠标在页面中的坐标    利用事件对象的  pageX  
     - 得到middle中等盒子在页面中的坐标   middle.getBoundingClientRect()
     - 鼠标在middle 盒子里面的坐标   =   鼠标在页面中的坐标  -   middle 中等盒子的坐标
     - 黑色遮罩层不断得到       鼠标在middle 盒子中的坐标 就可以移动起来了

     >注意 y坐标特殊,需要减去 页面被卷去的头部 ,因为getBoundingClientRect()获取的是相对于可视窗口的坐标,当页面滚动时,会出现问题
     >为什么不用 box.offsetLeft 和 box.offsetTop  因为这俩属性跟带有定位的父级有关系,很容被父级影响,而getBoundingClientRect() 不受定位的父元素的影响

   - 限定遮罩的盒子只能在middle 内部移动,需要添加判断

     - 限定水平方向 大于等于0 并且小于等于 400
     - 限定垂直方向 大于等于0 并且小于等于 400

通过console.log(middle.getBoundingClientRect());得到中等盒子的坐标如下图

  - 遮罩盒子移动的坐标: 

     - 声明一个 mx 作为移动的距离
     - 水平坐标 x 如果 小于等于100 ,则移动的距离 mx 就是  0  不应该移动
     - 水平坐标 如果 大于等于100 并且小于300,移动的距离 mx就是 x  - 100 (100是遮罩盒子自身宽度的一半)
     - 水平坐标 如果 大于等于300,移动的距离就是  mx   就是200  不应该在移动了
     - 其实我们发现水平移动, 就在 100 ~ 200 之间移动的
     - 垂直同理

        // 声明两个变量, 黑色盒子移动的距离
        let mx = 0
        let my = 0
        if (x <= 100) mx = 0
        if (x > 100 && x < 300) mx = x - 100
        if(x >= 300) mx = 200
        if (y <= 100) my = 0
        if (y > 100 && y < 300) my = y - 100
        if(y >= 300) my = 200


   - 大盒子图片移动的计算方法:
     - 中等盒子是 400px  大盒子 是 800px 的
     - 中等盒子移动1px, 大盒子就应该移动2px, 只不过是负值

   ~~~JavaScript
   large.style.backgroundPositionX = - 2 * mx + 'px'
   large.style.backgroundPositionY = - 2 * my + 'px'

 

  <script>

    // 顶部导航栏自动滑出
    (function(){
      const sticky = document.querySelector('.sticky')
      const header = document.querySelector('.xtx_header .wrapper')
      const headerTop = header.offsetTop
      const headerHeight = header.clientHeight
      const top = headerTop + headerHeight
      window.addEventListener('scroll', function(){
        const n = document.documentElement.scrollTop
        if (n >= top) {
          sticky.style.top = '0px'
        } else {
          sticky.style.top = '-80px'
        }
      })
    })();

    // 三个盒子的故事,放大镜效果
    // 1. 获取三个盒子
    const small = document.querySelector('.small')
    const middle = document.querySelector('.middle')
    const large = document.querySelector('.large')

    // 2. 鼠标经过对应的小盒子,左侧中等盒子显示对应的图片
    // 事件委托,注意必须使用mouseover,因为事件委托利用的是冒泡原理,而mouseenter不能冒泡
    small.addEventListener('mouseover', function(e){
      if (e.target.tagName === 'IMG') {

        // 排他思想 干掉以前的 active  li 上面
        this.querySelector('.active').classList.remove('active')
        // 当前元素的爸爸li 添加 active
        e.target.parentNode.classList.add('active')
        // console.log(middle.children[0]);
        // 让中等盒子里面的图片,src 更换为   小图片src
        middle.querySelector('img').src = e.target.src
        // 大盒子更换背景图片,注意图片背景的属性值为 url()
        large.style.backgroundImage = `url(${e.target.src})`
      }
    })

    // 3. 鼠标经过中等盒子,显示隐藏大盒子
    middle.addEventListener('mouseenter', show)
    middle.addEventListener('mouseleave', hide)

    // 显示函数 显示大盒子
    let timer = null
    function show() {
      // 先清除定时器
      clearTimeout(timer)
      large.style.display = 'block'
    }
    // 隐藏函数 隐藏大盒子
    function hide() {
      //  鼠标离开不会立马消失,而是有200ms的延时,使用setTimeout函数
      timer = setTimeout(function(){
        large.style.display = 'none'
      }, 250)
    }

    // 4. 鼠标经过大盒子,显示隐藏大盒子
    large.addEventListener('mouseenter', show)
    large.addEventListener('mouseleave', hide)

    // 5. 做鼠标经过 中等盒子,显示隐藏 黑色遮罩 的盒子
    const layer = document.querySelector('.layer')
    middle.addEventListener('mouseenter', function(){
      layer.style.display = 'block'
    })
    middle.addEventListener('mouseleave', function(){
      layer.style.display = 'none'
    })

    // 6. 移动黑色遮罩盒子
    middle.addEventListener('mousemove', function(e){
      // 鼠标在中等盒子的坐标 = 鼠标在页面的坐标 - middle 盒子的坐标
      // console.log(middle.getBoundingClientRect().x);
      // console.log(middle.getBoundingClientRect().left);
      let x = e.pageX - middle.getBoundingClientRect().left
      let y = e.pageY - middle.getBoundingClientRect().top - document.documentElement.scrollTop
      // 黑色遮罩移动 在middle 盒子内 限定移动距离
      if (x >= 0 && x <= 400 && y >= 0 && y <= 400) {
        // 黑色盒子不是一直移动的
        // 声明两个变量, 黑色盒子移动的距离
        let mx = 0
        let my = 0
        if (x <= 100) mx = 0
        if (x > 100 && x < 300) mx = x - 100
        if(x >= 300) mx = 200

        if (y <= 100) my = 0
        if (y > 100 && y < 300) my = y - 100
        if(y >= 300) my = 200
        
        layer.style.left = mx + 'px'
        layer.style.top = my + 'px'
        // 大盒子的背景图片要跟随 中等盒子移动 存在的关系是 2倍
        large.style.backgroundPositionX = -2 * mx + 'px'
        large.style.backgroundPositionY = -2 * my + 'px'
      }
    })

     //商品详情和商品评价切换
     const tabHead = document.querySelector('.tab-head')
     tabHead.addEventListener('click', function(e){
      if(e.target.tagName === 'A') {
        const active = document.querySelector('.tab-head .active')
        if (active) active.classList.remove('active')
        e.target.classList.add('active')

        const id = e.target.dataset.id
        const a = id == 2 ? 3 : 2
        document.querySelector(`.main .cont>div:nth-child(${id})`).style.display = 'block'
        document.querySelector(`.main .cont>div:nth-child(${a})`).style.display = 'none'
      }
     })

/* 
 
    //点击尺寸
    (function () {
      const dd = document.querySelector('.item #size');
      dd.addEventListener('click', function (e) {
        if (e.target.tagName == 'SPAN') {
          const active = document.querySelector('.item #size .active');
          if (active) active.classList.remove('active');
          e.target.classList.add('active');
        }
      });
    })();


    //点击颜色
    (function () {
      const dd = document.querySelector('.item #color');
      dd.addEventListener('click', function (e) {
        if (e.target.tagName == 'IMG') {
          const active = document.querySelector('.item  #color img.active');
          if (active) active.classList.remove('active');
          e.target.classList.add('active');
        }
      });
    })(); */

  </script>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/374099.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Stata】从入门到精通.零基础小白必学的教程,一学就fei

视频教程移步&#xff1a;https://www.bilibili.com/video/BV1hK4y1d714/?p4&spm_id_frompageDriver&vd_sourcecc8074e9c81a225f214226065db53d32P3 第二讲 Stata处理数据全流程&#xff08;上&#xff09; P3 - 01:37&#xfeff;内置数据 file example datasets使用…

FastDFS - 分布式文件存储系统

目录一、分布式文件存储1.分布式文件存储的由来2.常见的分布式存储框架二、FastDFS介绍三、FastDFS安装1.拉取镜像文件2.构建Tracker服务3.构建Storage服务4.测试图片上传四、客户端操作1.Fastdfs-java-client1.1 文件上传1.2 文件下载2.SpringBoot整合一、分布式文件存储 1.分…

【MySQL】什么是意向锁 IS IX 及值得学习的思想

文章目录前言行锁和表锁使用意向锁意向锁的算法意向锁的思想JDK 中相似的思想前言 之前看 MySQL 都刻意忽略掉了 IS 和 IX 锁&#xff0c;今天看 《MySQL 是怎样运行的》&#xff0c;把意向锁讲的很通透&#xff0c;本篇博文提炼一下思想。 I: Intention Lock&#xff08;意向…

自建服务器系列-0元搭建linux服务器(windows笔记本)

0元搭建linux服务器一.windows装Centos71.1 centos7 iso镜像1.2 准备U盘1.3 UltraISO 启动盘制作工具安装1.4 准备一台windows 机器1.5 安装过程二 、连接无线wifi三、固定wifi ip3.1 查看网络状态3.2 查看DNS3.3 查看GATEWAY3.4 设置静态IP四、一键快速安装单机版k8s五、申请域…

游戏高度可配置化:通用数据引擎(data-e)及其在模块化游戏开发中的应用构想图解

游戏高度可配置化&#xff1a;通数据引擎在模块化游戏开发中的应用构想图解 ygluu 码客 卢益贵 目录 一、前言 二、模块化与插件 1、常规模块化 2、插件式模块化&#xff08;插件开发&#xff09; 三、通用数据引擎理论与构成 1、名字系统&#xff08;数据类型&#xf…

数据结构与算法之树结构基础

目录为什么要使用树结构树结构基本概念树的种类树的存储与表示常见的一些树的应用场景为什么要使用树结构 线性结构中不论是数组还是链表&#xff0c;他们都存在着诟病&#xff1b;比如查找某个数必须从头开始查&#xff0c;消耗较多的时间。使用树结构&#xff0c;在插入和查…

58-59-60 - 动态内存分配的实现

---- 整理自狄泰软件唐佐林老师课程 文章目录1. 讨论2. 动态内存管理2.1 动态内存管理的关键2.2 动态内存管理的分类3. 定长内存管理的设计与实现3.1 空间划分3.2 内存申请和归还3.3 关键数据类型3.4 思考4. 变长内存管理的设计与实现4.1 空间划分4.2 内存申请和归还4.3 关键数…

802.11 MCS 的最低SNR分析

常常看到这样的表格: 那么这个SNR如何而来? 看看RSSI和SNR的关系,它们之间隔了一个noise floor。从表格看得出,这个底噪在-80~-90之间。 而SNR的核心,也有类似的原因,它和BER有关。

tkinter界面的TCP通信/开启线程等待接收数据

前言 用简洁的语言写一个可以与TCP客户端实时通信的界面。之前做了一个项目是要与PLC进行信息交互的界面&#xff0c;在测试的时候就利用TCP客户端来实验&#xff0c;文末会附上TCP客户端。本文分为三部分&#xff0c;第一部分是在界面向TCP发送数据&#xff0c;第二部分是接收…

【Python从入门到进阶】9、流程控制语句-条件语句(if-else)

接上篇《8、Python的输入输出》 上一篇我们学习了Python的输入和输出相关内容。本篇我们来学习Python的控制流语句。 一、流程控制语句的含义 之前我们分别学习过“变量及数据类型”、“运算符”&#xff0c;其中“变量及数据类型”相当于我们学习自然语言中的“字”&#xf…

【数据库系统概论】基础知识总结

&#x1f339;作者:云小逸 &#x1f4dd;个人主页:云小逸的主页 &#x1f4dd;Github:云小逸的Github &#x1f91f;motto:要敢于一个人默默的面对自己&#xff0c;强大自己才是核心。不要等到什么都没有了&#xff0c;才下定决心去做。种一颗树&#xff0c;最好的时间是十年前…

Linux基础命令和工具使用详解

Linux基础命令和工具使用详解一、grep搜索字符二、find查找文件三、ls 显示文件四、wc命令计算字数五、uptime机器启动时间负载六、ulimit用户资源七、curl http八、scp远程拷贝九、dos2unix和unix2dos十、sed 行处理10.1、简单模式10.2、替换模式十一、awk 列处理11.1、打印某…

【C++从入门到放弃】类和对象(上)

&#x1f9d1;‍&#x1f4bb;作者&#xff1a; 情话0.0 &#x1f4dd;专栏&#xff1a;《C从入门到放弃》 &#x1f466;个人简介&#xff1a;一名双非编程菜鸟&#xff0c;在这里分享自己的编程学习笔记&#xff0c;欢迎大家的指正与点赞&#xff0c;谢谢&#xff01; 类和对…

JavaScript 高级1 :面向对象

JavaScript 高级1 &#xff1a;面向对象 Date: January 16, 2023 Text: 面向对象、ES6中类和对象、类的继承、面向对象案例 目标&#xff1a; 能够说出什么是面向对象 能够说出类和对象的关系 能够使用 class 创建自定义类型 能够说出什么是继承 面向对象编程介绍 面向过…

JDK安装指导

Oracle官网地址https://www.oracle.com/java版本查询这里仅标识了java19和java17java archived 查看更多随便进入一个&#xff0c;根据后缀提示下载对应包即可Linux安装&#xff08;示例 java 1.8版本&#xff09;https://www.oracle.com/java/technologies/javase/javase8u211…

基于MaixBit(K210芯片)的图像识别猜拳手势博弈装置

本文介绍了一种基于嵌入式平台开发的图像识别部署装置&#xff0c;其主要功能包括实现机器与人的“猜拳博弈”&#xff0c;其组成分为三个部分&#xff1a;手势检测数据集图像识别模型训练模型格式部署maixbit开发板部署手势检测数据集&#xff1a;本项目的数据集包括三种标签&…

2023自动化测试岗位需求的 7 项必备技能 (最新版)

目录&#xff1a;导读 一、自动化测试员技能——编程语言 二、自动化测试员技能–出色的手动测试技能 三、.自动化测试员技能–自动化工具专业知识 四、自动化测试员技能–了解业务需求 五、自动化测试员技能–自动化工具故障排除 六、自动化测试员技能–具有测试管理工具…

Android 网络框架——Retrofit源码精析

众所周知&#xff0c;Retrofit是OkHttp的封装&#xff0c;APP对网络交互部分的实现基本上都是RxJavaRetrofitOkHttp架构&#xff08;或协程RetrofitOkHttp&#xff09;&#xff0c;可以说&#xff0c;Retrofit已经广为人知。本文主要介绍Retrofit主线源码实现机制&#xff0c;及…

二叉树的前序遍历-java两种方式-力扣144

一、题目描述给你二叉树的根节点 root &#xff0c;返回它节点值的 前序 遍历。示例 1&#xff1a;输入&#xff1a;root [1,null,2,3]输出&#xff1a;[1,2,3]示例 2&#xff1a;输入&#xff1a;root []输出&#xff1a;[]示例 3&#xff1a;输入&#xff1a;root [1]输出…

MySQL进阶(二)

目录 1、视图 1、检查选项 2、视图的更新 3、视图作用 2、存储过程 1、语法 2、变量 1、系统变量 2、用户定义变量 3、局部变量 3、if 4、参数 5、case 6、循环 1、while 2、repeat 3、loop 7、游标、条件处理程序 8、存储函数 3、触发器 4、锁 1、全局锁 2、表级锁 …