WebApis知识总结以及案例(续3)

综合案例

小兔鲜页面注册

分析业务模块

  • 发送验证码模块

用户点击之后,显示05 秒后重新获取

时间到了,自动改为重新获取

    //1.发送短信验证码模块const code=document.querySelector('.code')let flag=true//通过一个变量来控制 节流阀 // 1.1 点击事件code.addEventListener('click',function(){if(flag){flag=false//时间未到点击之后不可触发事件let i=5// 点击完毕之后立马触发code.innerHTML=`0${i}秒后重新获取`let timerID=setInterval(function(){i--code.innerHTML=`0${i}秒后重新获取`if(i===0){clearInterval(timerID)flag=true//时间结束 点击之后可以触发事件// 重新获取code.innerHTML=`重新获取`}},1000)}})
  • 各个表单验证模块

用户名验证(注意封装函数 verifyxxx),失去焦点触发这个函数

  • 正则/^[a-zA-Z0-9-_]$/{6,16}
  • 如果不符合要求,则出现提示信息 并return false中断程序
  • 否则 则返回return true
  • 之所以返回布尔值 是为了最后的提交按钮做准备
  • 侦听使用change事件,当鼠标离开了表单,并且表单值发生了变化时触发(类似京东效果)
    const input =document.querySelector('input')input.addEventListener('change',function(){console.log(11);})
    // 2.验证用户名// 2.1获取用户名表单const username=document.querySelector('[name=username]')username.addEventListener('change',verfiyName)//函数名不加括号// 2.3封装vertifyName函数function verfiyName(){const span=username.nextElementSibling// console.log(11)// 2.4 定规则const reg=/^[a-zA-Z0-9-_]{6,16}$/if(!reg.test(username.value)){// console.log(11)span.innerText='输入不合法,请输入6~16位'return false}// 合法的 就清空spanspan.innerText=''return true}

手机号验证 

正则:/^1(3\d|4[5-9]|5[0-35-9]|6[567]|7[0-8]|8\d|9[0-35-9])\d{8}$/

其余同上

验证码验证

正则:/^\d{6}$/

其余同上

密码验证

正则:/^[a-zA-Z0-9-_]{6,20}$/

其余同上

再次密码验证

如果本次密码不等于上面输入的密码则返回错误信息

其余同上

我同意模块

添加类 .icon-queren2 则是默认选中样式,可以使用toggle切换类

表单提交模块

使用submit提交事件

  • 勾选已经阅读统一模块

如果没有勾选同意协议,则提示需要勾选

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

  • 下一步验证全部模块

只要上面有一个input验证不通过就不同意提交

如果上面input表单 只要有模块返回的是false 则阻止提交

    (function(){//1.发送短信验证码模块const code=document.querySelector('.code')let flag=true//通过一个变量来控制 节流阀 // 1.1 点击事件code.addEventListener('click',function(){if(flag){flag=false//时间未到点击之后不可触发事件let i=5// 点击完毕之后立马触发code.innerHTML=`0${i}秒后重新获取`let timerID=setInterval(function(){i--code.innerHTML=`0${i}秒后重新获取`if(i===0){clearInterval(timerID)flag=true//时间结束 点击之后可以触发事件// 重新获取code.innerHTML=`重新获取`}},1000)}})});// 2.验证用户名// 2.1获取用户名表单const username=document.querySelector('[name=username]')username.addEventListener('change',verfiyName)//函数名不加括号// 2.3封装vertifyName函数function verfiyName(){const span=username.nextElementSibling// console.log(11)// 2.4 定规则const reg=/^[a-zA-Z0-9-_]{6,16}$/if(!reg.test(username.value)){// console.log(11)span.innerText='输入不合法,请输入6~16位'return false}// 合法的 就清空spanspan.innerText=''return true}// 3.验证手机号// 2.1获取手机表单const phone=document.querySelector('[name=phone]')phone.addEventListener('change',verfiyPhone)//函数名不加括号// 2.3封装verfiyPhone函数function verfiyPhone(){const span=phone.nextElementSibling// console.log(11)// 2.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)){// console.log(11)span.innerText='输入不合法,请输入正确的手机号码'return false}// 合法的 就清空spanspan.innerText=''return true}// 4.验证验证码// 2.1获取验证码表单const code=document.querySelector('[name=code]')code.addEventListener('change',verfiyCode)//函数名不加括号// 2.3封装verfiycode函数function verfiyCode(){const span=code.nextElementSibling// console.log(11)// 2.4 定规则const reg=/^\d{6}$/if(!reg.test(code.value)){// console.log(11)span.innerText='输入不合法,请输入6位数字'return false}// 合法的 就清空spanspan.innerText=''return true}// 5.验证密码框// 2.1获取密码表单const password=document.querySelector('[name=password]')password.addEventListener('change',verfiypassword)//函数名不加括号// 2.3封装verfiypassword函数function verfiypassword(){const span=password.nextElementSibling// console.log(11)// 2.4 定规则const reg=/^[a-zA-Z0-9-_]{6,20}$/if(!reg.test(password.value)){// console.log(11)span.innerText='输入不合法,6~20位数字字母符号组成'return false}// 合法的 就清空spanspan.innerText=''return true}// 6.密码的再次验证// 2.1获取再次验证表单const confirm=document.querySelector('[name=confirm]')confirm.addEventListener('change',verfiyconfirm)//函数名不加括号// 2.3封装verfiyconfirm函数function verfiyconfirm(){const span=confirm.nextElementSibling// console.log(11)// 当前表单的值不等于密码框的值就是错误的if(confirm.value!==password.value){// console.log(11)span.innerText='两次密码输入不一致'return false}// 合法的 就清空spanspan.innerText=''return true}// 7.我同意const queren=document.querySelector('.icon-queren')queren.addEventListener('click',function(){// 原来有的就删掉 原来没有的就添加this.classList.toggle('icon-queren2')})// 8.提交模块const form=document.querySelector('form')form.addEventListener('submit',function(e){// 判断是否勾选我同意模块 如果有icon-queren2说明就勾选了 否则没勾选\if(!queren.classList.contains('icon-queren2')){e.preventDefault()return alert('请勾选同意协议')}//依次判断上面的每个input是否通过,只要有一个没通过就阻止if(!(verfiyName()&verfiyCode()&verfiyPhone()&verfiyconfirm()&verfiypassword())){e.preventDefault()}})

登录页

点击切换盒子

使用事件委托时,尽量不要在盒子套的很复杂的时候用,如果li标签里包了一个a元素,a元素里又包了个img元素,此时若给a标签设置事件委托,就不容易实现,因为点击的时候点击的是img元素。

    // 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//当前元素添加activetab_nav.querySelector('.active').classList.remove('active')e.target.classList.add('active')for(let i=0;i<pane.length;i++){// 先干掉所有人 for循环pane[i].style.display='none'}// 让对应序号的大pane 显示pane[e.target.dataset.id].style.display='block'}})

点击登陆可以跳转页面

  • 先阻止默认行为
  • 如果没有勾选同意,则提示要勾选
  • required属性不能为空
  • 假设登陆成功
  • 把用户名记录到本地存储当中
  • 同时跳转首页 location.href
    // 点击提交模块const form=document.querySelector('form')const agree=document.querySelector('[name=agree]')const username=document.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'})

小兔鲜首页页面

步骤:

最好写个渲染函数,因为一会退出还要用到

1.如果本地存储有记录的用户名,读取本地存储数据

需要把用户名写到第一个li里面

格式:<a href="javascript:;"><i class="iconfont icon-user">用户名</i></a>

因为登陆了,所以第二个里面的文字变为:退出登录

格式:<a href="javascript:;">退出登录</a>

2.如果本地没有数据,则复原为默认的结构

3,点击退出登录,删除本地数据,并重新渲染函数

    // 1.获取第一个小liconst li1=document.querySelector('.xtx_navs li:first-child')const li2=li1.nextElementSibling// 2.最好做个渲染函数 因为退出登录需要重新渲染function render(){// 2.1读取本地存储的用户名const uname=localStorage.getItem('xtx-uname')// console.log(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()
})

放大镜效果

业务分析:

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

1.获取对应的元素

2.采取事件委托的形式,监听鼠标经过小盒子里面扽图片,注意此时需要使用mouseover事件,因为需要事件冒泡触发small

3.让鼠标经过小图片,可以拿到小图片的src,可以做两件事

  • 让中等盒子的图片换成这个小图片的src
  • 让大盒子的背景图片,也换成这个小图片的src
    // 1. 获取三个盒子// 2. 小盒子 图片切换效果const small = document.querySelector('.small')//  中盒子const middle = document.querySelector('.middle')//  大盒子const large = document.querySelector('.large')// 2. 事件委托small.addEventListener('mouseover', function (e) {//事件冒泡if (e.target.tagName === 'IMG') {// console.log(111)// 排他 干掉以前的 active  li 上面this.querySelector('.active').classList.remove('active')// 当前元素的爸爸添加 activee.target.parentNode.classList.add('active')// 拿到当前小图片的 src// console.log(e.target.src)// 让中等盒子里面的图片,src 更换为   小图片srcmiddle.querySelector('img').src = e.target.src// 大盒子更换背景图片large.style.backgroundImage = `url(${e.target.src})`}})
  • 鼠标经过中盒子,右侧会显示放大镜效果的大盒子

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

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

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

4,给大盒子里面的背景图片一个默认的第一张图片

 

    // 3. 鼠标经过中等盒子, 显示隐藏 大盒子middle.addEventListener('mouseenter', show)middle.addEventListener('mouseleave', hide)let timeId = null// 显示函数 显示大盒子function show() {// 先清除定时器clearTimeout(timeId)large.style.display = 'block'}// 隐藏函数 隐藏大盒子function hide() {timeId = setTimeout(function () {large.style.display = 'none'}, 200)}// 4. 鼠标经过大盒子, 显示隐藏 大盒子large.addEventListener('mouseenter', show)large.addEventListener('mouseleave', hide)
  • 黑色遮罩盒子跟着鼠标来移动
  1. 先做鼠标经过小盒子small盒子,显示隐藏黑色遮罩的盒子
  2. 让黑色遮罩跟着鼠标来走,需要用到鼠标移动事件 mousermove
  3. 让黑色盒子移动的核心思想:不断把鼠标在中等盒子内的坐标给遮罩层left top,这样遮罩层就可以跟着移动了

算法

  • 得到鼠标在页面中的坐标,利用事件对象的pageX
  • 得到中等盒子在页面中的坐标 middle.getBoundingClientRect()
  • 鼠标在中等盒子中的坐标=鼠标在页面中的坐标-middle中等盒子的坐标
  • 黑色遮罩层不断得到 鼠标在中等盒子中的坐标 就可以移动起来了
  • 注意y坐标特殊,需要减去页面被卷去的头部
  • 不用offsetLeft和offsetTop的原因:因为这两个属性跟带有定位的父级有关系,很容易被父级影响,而getBoundingClientRect()不受定位父元素的影响

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

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

遮罩盒子移动的坐标:

  • 声明一个mx作为移动的距离
  • 水平坐标x如果小于等于100,则移动的距离mx就是0,不应该移动
  • 水平坐标如果大于等于100并且小于300,移动的距离就是mx-100(100)是遮罩层盒子自身宽度的一半
  • 水平坐标如果大于等于300,移动的距离就是mx=200不用再移动了
  • 其实水平移动就是在100~200之间移动的
  • 鼠标在中等盒子上移动,大盒子的图片跟着显示对应位置
    // 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) {// let x = 10, y = 20// console.log(11)// 鼠标在middle 盒子里面的坐标 = 鼠标在页面中的坐标 - middle 中等盒子的坐标// console.log(e.pageX)鼠标在页面中的坐标// middle 中等盒子的坐标// console.log(middle.getBoundingClientRect().left)let x = e.pageX - middle.getBoundingClientRect().leftlet y = e.pageY - middle.getBoundingClientRect().top - document.documentElement.scrollTop//解决页面滚动时框下移的问题,减去被卷去的头部// console.log(x, y)// 黑色遮罩移动 在 middle 盒子内 限定移动的距离if (x >= 0 && x <= 400 && y >= 0 && y <= 400) {// 黑色盒子不是一直移动的// 声明2个变量 黑色盒子移动的 mx my变量 let mx = 0, my = 0if (x < 100) mx = 0if (x >= 100 && x <= 300) mx = x - 100if (x > 300) mx = 200if (y < 100) my = 0if (y >= 100 && y <= 300) my = y - 100if (y > 300) my = 200layer.style.left = mx + 'px'layer.style.top = my + 'px'// 大盒子的背景图片要跟随 中等盒子移动  存在的关系是 2倍   large.style.backgroundPositionX = -2 * mx + 'px'large.style.backgroundPositionY = -2 * my + 'px'}})

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

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

相关文章

Unity URP 2021 Release-Notes

&#x1f308;Unity URP 2021 Release-Notes 版本更新内容2021.3.32URP: Vulkan URP will use MSAA samples count fallback from player settings. Prior to this x2 fallback would have been to upgrade to x4.(UUM-741)2021.3.29URP: 2D - Fix additional draw call when F…

【MATLAB源码-第51期】基于matlab的粒子群算法(PSO)的栅格地图路径规划。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 粒子群算法&#xff08;Particle Swarm Optimization&#xff0c;简称PSO&#xff09;是一种模拟鸟群觅食行为的启发式优化方法。以下是其详细描述&#xff1a; 基本思想&#xff1a; 鸟群在寻找食物时&#xff0c;每只鸟都…

盲人专用软件定制开发:突破出行壁垒,点亮生活之路

身为一名资深记者&#xff0c;我始终关注着各类社会群体面临的挑战与应对策略。今天&#xff0c;我将目光投向了一个特殊群体——盲人&#xff0c;以及一款旨在破解他们独立出行难题的盲人专用软件。这款应用叫做蝙蝠避障&#xff0c;它通过定制开发&#xff0c;以先进的技术手…

前端H5实现视频上传,并截取第一帧作为封面。解决微信内ios系统无法上传视频的问题,解决ios截取视频作为封面的问题。

前端H5实现视频上传&#xff0c;并截取封面 前端实现视频上传&#xff0c;并截取第一帧作为封面。 写的过程中出现的问题&#xff1a; 在微信内ios系统无法上传视频&#xff0c;无法触发addEventListener的loadedmetadata解决完1问题后&#xff0c;ios截取视频第一帧作为封面…

git设置ssh秘钥远程连接

文章目录 1、生成rsa秘钥2、将rsa秘钥添加到远程仓库平台 我们在往github上push项目的时候&#xff0c;使用SSH&#xff08;安全外壳协议&#xff09;代替HTTPS来推送和拉取Git仓库的内容是一个更为方便和安全的方式&#xff0c;特别是在频繁与远程仓库交互的情况下。通过配置S…

第九届少儿模特明星盛典 全球赛首席体验官『韩嘉滢』精彩回顾

2024年1月30日-2月1日&#xff0c;魔都上海迎来了龙年第一场“少儿形体行业美育春晚”&#xff01;由IPA模特委员会主办的第九届少儿模特明星盛典全球总决赛圆满收官&#xff01;近2000名少儿模特选手从五湖四海而来&#xff0c;决战寒假这场高水准&#xff0c;高人气&#xff…

【算法】删除链表中重复元素

本题来源---《删除链表中重复元素》。 题目描述 给定一个已排序的链表的头 head &#xff0c; 删除所有重复的元素&#xff0c;使每个元素只出现一次 。返回已排序的链表 。 示例 1&#xff1a; 输入&#xff1a;head [1,1,2] 输出&#xff1a;[1,2]示例 2&#xff1a; 输入…

46.HarmonyOS鸿蒙系统 App(ArkUI)网格布局

Grid(){GridItem(){Button(按钮1).fontSize(28)}.backgroundColor(Color.Blue)GridItem(){Text(数学).fontSize(28)}.backgroundColor(Color.Yellow)GridItem(){Text(语文).fontSize(28)}.backgroundColor(Color.Green)GridItem(){Text(英语).fontSize(28)}.backgroundColor(Co…

如何监控tomcat的性能

关键指标 tomcat的关键指标有吞吐量、响应时间、错误数、线程池、cpu以及JVM内存。其中前三3个指标是最值得我们关注的业务指标。 部署和管理Web应用程序时&#xff0c;监控Tomcat的性能是至关重要的。Tomcat是一个流行的开源Servlet容器&#xff0c;用于托管Java Web应用程序。…

极速充电!一键解决苹果手机充电慢的问题

现如今&#xff0c;手机是我们日常生活中不可或缺的一部分&#xff0c;我们经常会使用它来刷短剧、看小说、读新闻等。然而&#xff0c;有时我们可能会遇到苹果手机充电慢的问题&#xff0c;这不仅影响了手机的用户体验&#xff0c;还可能给我们的生活带来一些不便。 遇到这种…

单细胞核转录组——植物:叶叶我呀裂开啦~

单细胞转录组测序技术能够在单细胞分辨率下研究样本的转录组信息&#xff0c;可以完美解决细胞异质问题&#xff0c;能全面真实揭示细胞多样性和复杂性&#xff0c;能够更加深入地研究细胞类型、细胞功能、细胞亚群及其异质性、细胞谱系等&#xff0c;还常用于识别新的细胞类型…

cesium 指定点旋转rectangle entity方式 坐标篇

cesium中rectangle是水平垂直于正北方向的&#xff0c;rectangle的属性中有rotation&#xff0c;但是rotation是以矩形的中心点进行旋转的&#xff0c;旋转过程中矩形的形状可能会变形&#xff0c;如果需要以矩形的顶点为原点进行旋转&#xff0c;可以采用entity的方式添加poly…

2024年外贸行业营销神器推荐

2024年外贸行业营销神器推荐&#xff1a;外贸人每天面对的不是国内客户&#xff0c;而是全球客户&#xff0c;相对于国内来说&#xff0c;会更加麻烦和繁琐&#xff0c;今天就码一篇2024年外贸行业营销神器的推荐文章&#xff0c;希望可以减轻各位外贸人的负担&#xff01; 1、…

OpenHarmony实战开发-页面深色模式适配。

介绍 本示例介绍在开发应用以适应深色模式时&#xff0c;对于深色和浅色模式的适配方案&#xff0c;采取了多种策略如下&#xff1a; 1. 固定属性适配&#xff1a;对于部分组件的颜色属性&#xff0c;如背景色或字体颜色&#xff0c;若保持不变&#xff0c;可直接设定固定色值…

Matroska解封装原理与实践

本期作者 背景 Matroska是一种开放标准、功能强大的多媒体封装格式&#xff0c;可容纳多种不同类型的视频、音频及字幕流&#xff0c;其常见的文件扩展名为.mkv、.mka等。与应用广泛的MP4相比&#xff0c;Matroska更加灵活开放&#xff0c;可以同时容纳多个字幕&#xff0c;甚至…

29、Lua中的元表与元方法

Lua中的元表与元方法 前言算术类的元方法__tostring元方法如何保护我们的 "奶酪"——元表__index元方法__newindex元方法 前言 Lua中每个值都可具有元表。 元表是普通的Lua表&#xff0c;定义了原始值在某些特定操作下的行为。你可通过在值的原表中设置特定的字段来…

网络协议之 STP生成树协议学习心得

title: STP生成树协议 tags: internet top: true cover: true stp协议的背景 为了解决单点故障的问题&#xff0c;提出冗余的概念&#xff0c;但是又产生了新的问题————环路 表现形式为&#xff1a; &#xff08;1&#xff09;MAC地址表抖动 &#xff08;2&#xff09;多帧…

C#引用外部组件的常用方法

我们在开发程序过程中&#xff0c;时常会使用到第三方组件&#xff0c;比如一些通信、UI组件等。常用的引用方法有下面几种。 01 NuGet引用 NuGet是.NET的一个包管理平台&#xff0c;很多开源组件会通过NuGet进行管理和发布。比如我们常用的S7NetPlus等。 从NuGet中引用组件…

零基础学Python专栏文章导航站

零基础学Python专栏文章导航站 专栏导读零基础入门篇 专栏导读 本文是零基础学Python的文章导航站。专栏分为零基础入门篇、模块篇、网络爬虫篇、Web开发篇、办公自动化篇、数据分析篇… 为了方便专栏订阅者更方便的阅读专栏文章&#xff0c;点击链接即可跳转到具体文章&#…

Vue的项目文件夹中的<router>指的是什么

在Vue框架搭建的项目中&#xff0c;前端路由主要指的是基于HTML5的history模式或hash模式来实现在不刷新页面的情况下进行页面之间的跳转。这是单页应用&#xff08;SPA, Single Page Application&#xff09;中的一个核心概念。 具体来说&#xff0c;前端路由允许我们在不重新…