javascript web api,bom&dom

发布时间 2023-05-24 14:06:21作者: yxxcl

Api

1. 获取dom元素

const x = document.querySelector('选择器') querySelectorAll返回的是伪数组

2. 操作元素内容

对象.innerText

对象.innerHTML 会解析标签

3. 操作元素样式属性

1. style

<script>
   const div = document.querySelector('.box')
   box.style.width = '300px'//x.style.x
   box.style.backgroundColor = 'yellow'//识别不出-,所以用小驼峰命名
   box.style.borderTop = '2px solid green'
</script>

2. 操作类名className

<script>
   const div = document.querySelector('div')
   div.className = 'box'//className会替换之前的类名,''可以用来删除,''内可以添加多个类名
</script>
<script>
    //element.classList.add/remove/toggle('')(追加/删除/切换)
    const box = document.querySelector('.box')
    box.classList.add('active')//classList修改的类名不加点,而且字符串
    box.classList.toggle('active')//有就删,没有就加上
</script>

3. 操作表单元素属性

<input type="text" value="computer">
<script>
const uname = document.querySelector('input')
</script>

name.value才能修改表单内容

uname.type = 'password'修改input类型

<input type="checkbox" value="" id="" checked>
<button disabled>click</button>
<script>
const ipt = document.querySelector('input')
const button = document.querySelector('button')
</script>

ipt.checked = false修改选择框状态

button.disabled = truebutton默认无法点击状态

4.data-set自定义属性

自定义属性:data-开头(html5),在data对象上一律以dataset对象方式获取。

标准属性:标签自带:class id title;可以使用点语法操作:disabled,checked,selected。

<div class="box1" data-id="10" data-zidingyi="自定义"></div>
<script>
   const box = document.querySelector('.box1')
   console.log(box.dataset);//set意为集合,所有的自定属性
</script>

见3-2法2事件委托实例

5.定时器-间歇函数

<script>
function fn(){
console.log('per 1s');
}
let n = setInterval(fn,1000)//每隔1000ms自动调用fn函数,不能写fn(),不然就是直接调用了。
console.log(n);//加上序号,即确认是页面里哪个计时器
clearInterval(n)//关闭计时器,有变量名才好关
</script>

如果不将 setInterval() 的返回值赋值给一个变量,那么就无法通过该变量来清除对应的定时器,因为 clearInterval() 需要传入 setInterval() 返回的值作为参数来清除对应的定时器。如果没有保存该返回值,则无法取消定时器。

6.事件监听

事件对象.addEventListener('事件类型',要执行的函数)

三要素:

1.事件源:哪个dom元素被触发,获取dom元素

2.事件类型:什么方式触发:click,mouseover

3:事件调用的函数:要做什么

事件类型:

鼠标事件:click,mouseover,mouseleave,mouseenter

焦点事件(表单获得光标):focus,blur(失去)

键盘事件:keydown,keyup

文本事件:input

HTMLElement.click() 方法可以用来模拟鼠标左键单击一个元素。

7.事件对象e

事件函数的回调函数绑定的第一个参数就是事件对象,console里

常见属性:

type:获取当前事件类型

clientX/Y:获得光标相对浏览器可见窗口左上角的位置

offsetX/Y:获取光标相对当前DOM元素左上角的位置

key:用户按下的键盘的键值

8.环境对象this

1. 每个函数里都有

2. 普通函数里this指向window

3. this指向函数的调用者

9.回调函数

<script>
       function fn() {
           console.log('这是一个回调函数');
      }
       setInterval(fn,1000)
       const box =  document.querySelector('.box')
       box.addEventListener('click',function (params) {
           console.log('此方程是addEventListener的回调函数');
      })
   </script>

10.事件流

事件流:事件完整执行过程中的流动路径

a. 捕获阶段(从父到子):document - element html - element body - element div

b. 冒泡阶段(从子到父):反过来,项目以事件冒泡为主

捕获和冒泡是事件传播的两种机制。在一个嵌套的 HTML 元素中,如果一个元素上触发了事件,这个事件会在该元素的祖先元素和后代元素中传递。

捕获是从最外层元素开始,逐级向下传递事件,直到到达目标元素。而冒泡则是从目标元素开始,逐级向上传递事件,直到到达最外层元素。在 DOM 标准事件模型中,先执行捕获阶段,然后执行目标阶段,最后执行冒泡阶段。

默认情况下,所有事件都是冒泡的,可以通过 addEventListener 的第三个参数来控制事件是在捕获阶段还是冒泡阶段处理。如果第三个参数是 true,则表示在捕获阶段处理事件;如果是 false 或者省略,则表示在冒泡阶段处理事件。

捕获和冒泡机制的应用场景比较广泛,比如可以用来处理事件委托,提高性能。当有大量子元素需要绑定事件时,可以将事件绑定到它们的父元素上,通过事件传播机制来处理事件。这样可以减少事件处理器的数量,提高性能

c. 阻止冒泡:阻止事件流动传播(捕获&冒泡),将事件限制在当前元素内: 函数名.stopPropagation()

11.事件解绑

const btn = document.querySelector('button')
function fn() {
           alert('click')
      }
       btn.addEventListener('click',fn)
       //L2事件解绑,匿名函数无法被解绑
       btn.removeEventListener('click',fn)

12. 鼠标经过事件

mouseover&mouseut有冒泡效果,子元素没有事件会冒泡到父级

mouseenter&mouseleave没有冒泡效果(推荐)

13. 事件委托:委托给父元素,减少注册次数,提高程序性能

多个li需要循环让每一个注册事件,利用冒泡给父元素注册事件,会从子元素冒泡到父元素

<ul>
       <li>1</li>
       <li>2</li>
       <li>3</li>
       <li>4</li>
       <li>5</li>
       <p>no color</p>
</ul>
<script>
       const ul = document.querySelector('ul')
       ul.addEventListener('click',function (e) {
           console.log(e);
           console.log(e.target);//log输出源代码,点击的那个对象
           console.dir(e.target);//点击的那个对象,dir输出对象内容,所有属性和方法
           // e.target.style.color = 'red'//点啥都变色
           if (e.target.tagName === 'LI') {
               e.target.style.color = 'red'
          }
      })
</script>

事件对象e中有一个属性target,属性值为我们点击的(上面的为li或p),但是 e.target得到的是我们点击的那个对象,但不一定ul中所有的我们都需要让其变色,需求只点击li有效果;

所以可以通过e.target.tagName获取真正的元素,这个tagName的LI一定要大写!

14. 阻止冒泡/元素默认行为

阻止链接跳转,表单域跳转:e.preventDefault()

<form action="http://www.itcast.cn">
   <input type="submit" value="login">
</form>
<script>
   const form = document.querySelector('form')
   form.addEventListener('click',function (e) {
       e.preventDefault( )//阻止提交
  })
</script>

15. 页面加载事件/元素滚动事件/页面尺寸事件

1.页面加载事件

加载外部资源(图片,外联css&js)加载完毕时触发的事件:load

不仅可以整个页面加载完毕,也可针对某个资源绑定load资源

<button>1</button
<script>
   //等待页面所有资源加载完毕,就回去执行回调函数
   window.addEventListener('load',function ( ) {
       const btn = document.querySelector('button')
       btn.addEventListener('click',function () {
           alert('11')
      })
  })
   img.addEventListener('load',function () {
       //等待图片加载完毕再执行
  })
   //DOMContentLoaded:当初始html文件被解析加载完成,DOMContentLoaded事件被触发,无需等待样式表,图像完全加载。
   //监听页面加载完毕:给domcument添加DOMContentLoaded事件。
   document.addEventListener('DOMContentLoaded',function () {
  })
</script>

2. 元素滚动事件(scroll)

检测用户滚动到某个区域后做一些处理:固定导航栏,返回顶部...

<script>
   window.addEventListener('scroll',function () {//给window加
       alert('1')
  })
</script>

获取位置scrollLeft scrollTop:可读写,获取被滚动的大小

<div class="box" style="width: 100px;
   height: 100px; overflow: scroll; border: 1px solid black; margin: 200px;">
   aaaaaaaaaaaaaaaa
   aaaaaaaaaaaaaaaa
   aaaaaaaaaaaaaaaa
   aaaaaaaaaaaaaaaa
   aaaaaaaaaaaaaaaa
   aaaaaaaaaaaaaaaa
   aaaaaaaaaaaaaaaa
</div>
<script>
   const box = document.querySelector('.box')
   box.addEventListener('scroll',function () {
       console.log(box.scrollTop);//被卷上去的头部
       console.log(box.scrollTop);
  })
   //想知道页面滚动了多少像素,获取html元素写法,document.documentElement返回对象是html元素
   window.addEventListener('scroll',function () {
       console.log(document.documentElement.scrollTop);
       if (document.documentElement.scrollTop>=100) {
       box.style.display = 'block'
  }else{
       box.style.display = 'none'
  }
  })
   //可读写:document.documentElement.scrollTop=800即打开在800的位置
</script>

3.页面尺寸事件

窗口改变时触发事件(resize)

<script>
   window.addEventListener('resize',function () {//窗口尺寸改变触发事件
       console.log(1);
  })
   //检测屏幕宽度
   window.addEventListener('resize',function () {
       const w = document.documentElement.clientWidth
       console.log(w);
  })
</script>

clientWidth,clientHeight:获取元素的可见部分宽高,不含margin,边框,滚动条。。。

<div class="box" style="height: 200px;  padding: 100px; display: inline-block; border: 20px solid red;">123456789123456789123456789123456789</div>
<script>
   const box = document.querySelector('.box')
   console.log(box.clientWidth);
</script>

16. 元素尺寸于位置

令元素滚动到某个元素(得到元素在页面中位置)就做什么事,而非计算滚动到某距离。

offsetWidth,offsetHeigh:获取元素的自身宽高,包含元素自身设置的宽高:内容+padding+border

获取的是数值,方便计算(与client区别是offset多了一个自身边框)

注意:1.获取的是可视宽高,如果隐藏了就为0;

2.二者皆为只读属性,scroll是可读写

3.是距离自己定位父级元素的左上距离,距自己最近一级带有定位的祖先元素。

<div class="box" style=" margin: 100px; width: 200px;
height: 200px;"><p style="background-color: blue; width: 100px; height: 100px; margin: 50px;"></p></div>
<!-- 发生了外边距折叠现象 -->
<script>
   const div = document.querySelector('div')
   const p = document.querySelector('p')
   console.log(div.offsetLeft);//108,body有个8px的外边距
   console.log(p.offsetLeft)
</script>

17. 日期对象

1. 实例化

实例化日期对象:代码中发现new关键字,创建一个时间对象并获取时间

<script>
   const date = new Date()//获得当前时间
   console.log(date);
   //指定时间:例如指定时间结束
   const date1 = new Date('2008-1-1')//字符串
   console.log(date1);
</script>

2. 日期对象方法

日期对象返回的数据不能直接用,转换为开发常用格式。

<script>
       const date = new Date()//实例化日期对象!
       console.log(date.getFullYear());//4位年份
       console.log(date.getMonth());//0---11
       console.log(date.getDate());//getDate获得月份的每一天
       console.log(date.getDay());//getDay是获得星期:0---6
       console.log(date.getHours());//0---23
       console.log(date.getMinutes());//0---59
       console.log(date.getSeconds());//0---59
   </script>

显示到页

<div></div>
   <script>
       const div = document.querySelector('div')
       function getMyDate() {
           const date = new Date()//实例化日期对象!
           let m = date.getMonth()+1
           let h = date.getHours()
           m = m<10 ? '0'+m:m
           h = h<10 ? '0'+h:h
           return `${date.getFullYear()}年${m}月${date.getDate()}  ${h}--${date.getMinutes()}`
      }
       div.innerHTML = getMyDate()
   </script>

简易

<div></div>
   <script>
       const div = document.querySelector('div')
       const date = new Date()
       // div.innerHTML = date.toLocaleString()//年月日,时间
       // div.innerHTML = date.toLocaleTimeString()//时间
       // div.innerHTML = date.toLocaleDateString()//年月日
       setInterval(function (params) {
           const date = new Date()
           div.innerHTML = date.toLocaleString()
      },1000)
   </script>

3. 时间戳

1970起始的第00秒至今的毫秒数,特殊的计量时间方式

某些场景计算倒计时效果,需要时间戳完成(时间不方便直接相减)

将来的时间戳-现在的时间戳 = 剩余时间毫秒数

+new Date() / Date.now() / getTime()

<script>
   //+new Date()
   console.log(+new Date());//无需实例化
   //getTime()
   const date = new Date()//实例化
   console.log(date.getTime());
   //Date.now()
   console.log(Date.now());//无需实例化,但是相对前两者可以返回指定的时间戳,Date.now()只能返回当前的

   console.log(+new Date('2023-5-1 00:00:00'));
   arr = ['sunday','1','2','3','4','5','6']
   // const date = new Date()//
   console.log(arr[new Date().getDay()]);//省略了76
</script>

18. 节点操作

1. DOM节点

DOM树里每一个内容都是一个节点

类型: 1元素节点✨:所有的标签:body,h,div; html是根节点

2属性节点:所有的属性:href,id,class,content...

3文本节点:所有的文本:文本,标题,链接名...

2. 查找节点

用的是属性(无需括号)

通过关系(父,子,兄弟)获取元素,例如点击按钮关闭图片,可以直接关闭父级元素。

返回的仍是对象

1. 父节点:.parentNode

返回最近一级的父节点,找不到返回为null

<div class="dad"><div class="son"></div></div>
<script>
   const son = document.querySelector('.son')
   console.log(son);//返回dom对象
   console.log(son.parentNode.parentNode);//返回dom对象
</script>

eg:点击关闭广告

<div class="ad" style="width: 400px;
   height: 150px; overflow: hidden ;background-color: skyblue; text-align: center; margin-bottom: 10px;">
       <div class="close" style="width: 10px;
       height: 10px; background-color: red; float: right; margin: 10px 10px;"></div>
       <span style="display: block; color: black; font-size: 30px; margin-top: 60px; line-height: 100%;">advertsment</span>
   </div>
   <div class="ad" style="width: 400px;
   height: 150px; overflow: hidden ;background-color: skyblue; text-align: center; margin-bottom: 10px;">
       <div class="close" style="width: 10px;
       height: 10px; background-color: red; float: right; margin: 10px 10px;"></div>
       <span style="display: block; color: black; font-size: 30px; margin-top: 60px; line-height: 100%;">advertsment</span>
   </div>
   <div class="ad" style="width: 400px;
   height: 150px; overflow: hidden ;background-color: skyblue; text-align: center; margin-bottom: 10px;">
       <div class="close" style="width: 10px;
       height: 10px; background-color: red; float: right; margin: 10px 10px;"></div>
       <span style="display: block; color: black; font-size: 30px; margin-top: 60px; line-height: 100%;">advertsment</span>
   </div>
   <script>
       const close = document.querySelectorAll('.close')
       for (let i = 0; i < close.length; i++) {
           close[i].addEventListener('click',function (params) {
           this.parentNode.style.display='none'
      })  
      }//✨只能为单个元素添加监听器,因此需要用循环遍历数组,给每一个添加事件监听器。
   </script>
2. 子节点 .children/childNodes

获得所有元素节点,返回伪数组!

childNodes:获得所有子节点,包括文本节点(空格,换行),注释节点等

3. 兄弟节点

previousElementSibling/nextElementSibling:上一个/下一个

<ul>
   <li><p>content</p></li>
   <li><p>222</p></li>
   <li></li>
   <li></li>
   <li></li>
</ul>
<script>
   const ul = document.querySelector('ul')
   console.log(ul.children);
   const li2 = document.querySelector('ul li:nth-child(1)')
   console.log(li2);
</script>

3. 增加节点(创建&增加)

点击发布按钮,新增一条信息————创建一个新的节点,将其放入指定的元素内部

1. 创建节点

document.createElement('tagName')

2. 追加节点

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

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

<ul><li>old</li></ul>
<script>
   const div = document.createElement('div')//创建节点
   console.log(div);
   document.body.appendChild(div)
   const ul = document.querySelector('ul')
   const li = document.createElement('li')
   li.innerHTML = 'new'
   ul.insertBefore(li,ul.children[0])//返回的是伪数组
</script>
3. 复制节点

复制一个(元素.cloneNode(布尔值)),放入指定元素的内部

深克隆:ture,全部克隆过来;浅克隆:false(空)仅克隆标签

<ul>
   <li>1</li>
   <li>2</li>
   <li>3</li>
</ul>
<script>
   const ul = document.querySelector('ul')
   const li1  = ul.children[0].cloneNode(true)//克隆了
   console.log(li1);
   ul.appendChild(li1)//放入
   ul.appendChild(ul.children[0].cloneNode(true))//复合写法
</script>

4. 删除节点

原生dom中,删除元素必要要通过父元素删除。(父元素.removeChild(要删的元素))

  1. 如果不存在父子关系则删除不成功;

  2. display:none隐藏节点但仍存在;删除就是在html里删除。

<ul>
   <li>delate</li>
</ul>
<script>
   const ul = document.querySelector('ul')
   // const li = document.querySelector('li')
   // ul.removeChild(li)
   ul.removeChild(ul.children[0])//无需获取li
</script>

19. M端事件(移动端的触屏事件)

touchstart:触摸DOM元素

touchmove:滑动在DOM元素

touchend:从DOM上移开

<div style="width: 300px;
   height: 300px; background-color: skyblue;"></div>
<script>
   const div = document.querySelector('div')
   div.addEventListener('touchstart',function () {
       console.log('1');
  })
   div.addEventListener('touchmove',function () {
       console.log('2');
  })
   div.addEventListener('touchend',function () {
       console.log('3');
  })
</script>

20.bom(window object):浏览器对象模型

1.bom

  1. bom包含dom,除dom之外还有navigetor,location,history,screen

  2. window对象是全局对象,document,alert(),console.log()都是window的属性,基本bom的属性和方法都是window的

  3. 所有定义在全局作用域中的变量,最后都会变为window对象的属性与方法

  4. window对象下的属性和方法调用的时候可以省略window:可以直接使用 setTimeout() 方法,而不必写成 window.setTimeout()。但是在某些情况下,为了避免变量名或函数名与其他作用域下的同名变量或函数冲突,最好使用 window. 前缀来显式地指定使用的是全局作用域下的属性或方法。

<script>
   console.log(document===window.document);//1.b
   console.log(alert===window.alert);
       
   function fn() {
       console.log(1);
  }
   window.fn()
   var num = 10//var是作用在全局作用域上的,等价于在window对象上创建一个属性num,其值为10
   console.log(window.num);//任何地方都可以通过 window.message 来访问这个变量。这种方式也说明了为什么全局变量会对整个应用程序产生影响,因为它们实际上是全局对象的属性,可以被任何代码访问和修改。
</script>

2.定时器-延时函数

js内置了一个用来让代码延迟执行的函数(只执行一次),setTimeout(回调函数,毫秒)

清除: clearTimeout(timer)

  1. 延时器需要等待,所以后面的先执行;

  2. 每一次调用定时器都会产生一个新的延时器

<script>
   setTimeout(function () {
       console.log(1);
  },1000)

   let timer =  setTimeout(function () {
       console.log(2);
  },1000)
   clearTimeout(timer)
</script>

3.js执行机制:单线程(同步&异步)

同步:先a再b再c:同步任务都在主线任务上进行,形成一个执行栈

异步:在a的同时b,c:js的异步是通过回调函数实现的,一般而言,异步任务有以下三种类型:

  1. 普通事件:click,reize...

  2. 资源加载:load,error...

  3. 定时器:setInterval,setTimeout...

异步任务添加到相关任务队列(消息队列)中

机制:

  1. 先执行执行栈中的同步任务

  2. 异步任务放入任务队列中。

  3. 一旦执行栈中的所有同步任务执行完毕,系统会按照顺序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行。

4.location对象

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

常用属性方法:href属性获取完整的url地址,对其赋值时用于地址的跳转。

1. 'location.href'自动跳转
<script>//a---'location.href'
       console.log(location);//可以省略window
       console.log(location.href)
       //href 经常用href 利用js的方法跳转页面
       //location.href = 'http://www.bing.com'// 直接跳转
       const a = document.createElement('a')
       document.body.appendChild(a)//别写错了成string
       
       let i=5
       a.innerHTML = `<a href="http://www.bing.com">${i}</a>`
       let timerID = setInterval(function () {
           i--
           a.innerHTML = `<a href="http://www.bing.com">${i}</a>`
           if (i===0) {
               location.href = 'http://www.bing.com'
               clearInterval(timerID)// 欲终止计时器,要先定义timerID,才能在clearInterval()里终止
          }
      },1000)
   </script>
2. 'search'

search属性获取地址中携带的参数,url中符号?后面的部分

form里name属性必须要写!

点击了button之后,网页地址栏?后面会带有输入的信息,通过search属性获取

<form action="">
       <input type="text" name="username">
       <input type="password" name="psd">
       <button>submit</button>
   </form>
   <script>
       console.log(location.search);
   </script> -->
3. 'hash'

看url变化

4. 'reload'方法
<a href="#/my">my</a>
   <a href="#/friend">friend</a>
   <a href="#/download">download</a>
   <button class="reload">reflesh</button>
   <script>
       //在控制台输入location.hash
       const reload = document.querySelector('.reload')
       reload.addEventListener('click',function () {
           location.reload()
      })
   </script>

5.navigate对象

数据类型是对象,该对象记录下了浏览器自身的相关信息。

常用属性方法:userAgent:检测浏览器的版本及平台。

<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://www.bing.com'
        }
      })();

       //这是各种匿名函数写法
       // (function () { })();
       // !(function () { })();
       // ~function () { }();
       !function () { }()
</script>

6.history对象

数据类型是对象,主要管理历史记录,该对象与浏览器地址栏的操作相对应,如前进,后退。历史记录等。

常用属性方法:back()可以后退, forward()前进, go(参数)(1前进一个页面,-1后退一个页面)

<button>backward</button>
     <button>forward</button>
     <script>
       const backward = document.querySelector('button:first-child')
       const forward = backward.nextElementSibling
       backward.addEventListener('click',function () {
           hiatory.back()
      })
       forward.addEventListener('click',function () {
           history.go(1)
      })
     <script>

21. 事件循环(event loop)

主线程不断的重复获得任务,执行任务,再获取任务,在执行,这种机制被称为事件循环。

这个过程先执行栈,然后任务队列,哪个异步任务结束了就放到执行栈里面去;结束之后又先看执行栈,没有再看任务队列,这个就叫做事件循环。而在看哪个异步完成了这个操作不是js操作,因为js单线程;而是浏览器来操作,观察哪个任务结束了就放进执行栈

<script>
       console.log(1);
       setTimeout(function () {
           console.log(2);
      },2000)
       setTimeout(function () {
           console.log(3);
      },0)
       console.log(4);

   </script>

22. 本地存储localstorage

将数据存储在本地,基于HTML5的规范 (理解为小型的仓库,数据库)

  1. 数据存储在用户浏览器中

  2. 设置,读取方便,甚至页面刷新不读取数据

  3. 容量较大,sessionStorage localStorage约5M作用

1. localStorage

将数据永远保存到本地(用户的电脑),除非手动删除,否则关闭页面也会存在。

特性: 同一浏览器可以共享;以键值对的形式存储使用;本地存储只能存储string

语法: locakStorage.setItem('key'.'value') 括号内键值对

<script>//元素---application---local storage
   //storage a name: uname;tom
   localStorage.setItem('uname','tom')
   localStorage.setItem('age',18)//数字不用''
   //获取, 只需要名字
   console.log(localStorage.getItem('uname'));
   console.log(localStorage.getItem('age'));//取出是string
   //删除,只删除名字
   localStorage.removeItem('uname')
   //改,如原来有这个键是改,没有就是增
   localStorage.setItem('uname','peter')
</script>

2. sessionstorage

特点:生命周期为关闭浏览器窗口;

同一个窗口(页面)数据可以共享;

以键值对的形式存储使用;

用法和localstorage基本相同

3. 存储复杂数据类型

本地只能存储字符串,无法存储复杂数据类型

复杂数据类型必须 转换成json字符串,再存储到本地:JSON.stringify(复杂数据类型)

使用JSON.stringify()方法将JSON对象转换为JSON字符串,也可以使用JSON.parse()方法将JSON字符串转换为JSON对象。

JSON对象和JSON字符串都是用来表示和交换数据的,它们之间可以相互转换,但是JSON字符串是一个字符串类型的数据,而JSON对象则是JavaScript原生的对象类型,

<script>
       const obj = {
           uname: 'tom',
           age: 18,
           gender: 'male '
      }
       //尝试:第一个是键!第二个值是变量
       // localStorage.setItem('obj',obj)//这样直接存无论在console还是application结果都是[object object]
       // console.log(localStorage.getItem('obj'));
       
       //a.使用JSON.stringify()方法将复杂数据类型转换为JSON字符串
       localStorage.setItem('obj',JSON.stringify(obj))
       console.log(localStorage.getItem('obj'));
       //JSON对象:{"uname":"tom","age":18,"gender":"male "} (JSON字符串)属性和值全都有 双引号!

       //b.使用JSON.parse将JSON字符串转化为 对象
       console.log(JSON.parse(localStorage.getItem('obj')));
   </script>

23. 字符串拼接方法:map();join()

1. map():

遍历数组处理数据,并且返回新的数组。

map: 映射:两个元素的集互相映射的关系,map重点有返回值,forEach没有返回值。

想要遍历数组用forEach,得到新数组用map

<script>
       const arr = ['red','blue','yellow']
       const newArr = arr.map(function (ele,index) {
           console.log(ele);
           console.log(index);
           return ele+' color'
      })
       console.log(newArr);
   </script>

2. join()

将数组中所有元素转化为一个字符串。

数组元素是通过参数里面指定的分隔符进行分割的,空字符串(''),则所有元素之间间隔没有任何字符。

<script>
   const arr = ['red','blue','yellow']
   console.log(arr.join(''));
   console.log(arr.join());//在console中进行对比,不要间隔用''
</script>

组合使用map();join()方法渲染页面

map()遍历数组数据生成tr,返回一个数组

24. 正则表达式

1. 介绍

正则表达式(Regular Expression)用于于匹配字符串中字符组合的模式;js中,正则表达式也是对象

通常用来查找,替换那些复合正则表达式的文本,许多语言都支持正则表达式。

eg:在一群人中找出戴眼镜戴帽子的男人,通过这些信息找到精确的人,这些用于查找的描述,信息编写一个模式,对应 到计算机中就是正则表达式。

使用场景:

  1. 验证表单(匹配):例如用户名只能输入字母数字下划线;

  2. 昵称只能输入中文;

  3. 敏感词替换(替换)

  4. 从字符串中提取特定部分(提取 )

2. 语法(2种)

a.定义规则;b.根据规则去查找,找到则返回

定义正则表达式语法:const 变量名 = /表达式/ ('/ /'是正则表达式字面量)

test()方法:判断是否有符合规则的字符串;用来查看正则表达式和指定的字符串是否匹配。匹配返回ture,否则返回false 。

exec()方法:在一个指定字符串中执行一个搜索匹配:regObj.exec(被检测字符串),匹配成功返回一个数组,否则返回null。

<script>
       const str = '1234566543478876543456788765433456'
       //无需引号,写什么查什么
       const reg = /6/
       console.log(reg.test(str));//匹配返回ture,否则返回false
       console.log(reg.exec(str));
   </script>

3. 元字符

普通字符:仅能描述本身,例如字母数字,普通字符只能匹配字符串中相同的字符;

元字符(特殊字符):具有特殊含义的字符,极大的提高了灵活性与匹配功能:

26个字母a,b,c,...,y,z换成元字符写法: [a-z]

元字符分类:

  1. 边界符:表示位置,开头和结尾,必须用什么开头,用什么结尾

  2. 量词:表示重复次数

  3. 字符类:比如\d表示0-9

1. 边界符

提示字符所处的位置

^:表示匹配行首的文本,以谁开始 $:表示匹配行尾的文本,以谁结束

<script>
       //元字符
       console.log(/a/.test('caba'));//ture
       //边界符
       console.log(/^a/.test('aaa'));//ture
       console.log(/^a/.test('cba'));//false
       console.log(/^a$/.test('a'));//ture同时以a开头结尾,注意写法,仅此为ture,其余全是false,原因如下
       console.log(/^a$/.test('aa'));//false同时以a开头结尾的a必须是同一个a!!!
   </script>
2. 量词

设定某个量词出现的次数,n的逗号绝对不能有空格

*: 重复0次或更多次;[0,]

+:重复1次或更多次;[1,]

?:重复0次或1次;[0,1]

{n}:重复n次;写几次就必须重复几次

{n,}:重复n次或更多次;

{n,m}:重复n-m次;

<script>
           console.log(/^a$/.test('abcbabcba'));//false
           console.log(/^a*$/.test(''));//ture
           console.log(/^a*$/.test('abcbabcba'));//false:想要ture字符串中只能有0或多个a,不能有其他的!!!!!

           console.log(/^a+$/.test('abcbabcba'))//false
           console.log(/^a+$/.test(''))//false

           console.log(/^a?$/.test('aa'))//false

           console.log(/^a{4}$/.test('aaaa'))//ture
           console.log(/^a{4}$/.test('aaaaa'))//false
        </script>
3. 字符类

[] 匹配字符集合;eg;[abc]后面的字符串只要包含abc任意一个字符(!!!只选一个!!!),都返回ture, 等同a||b||c

'-'连字符:表示一个范围,[a-z]:26个小写字母都可以;[a-zA-Z]:大小写都可以;[0-9]:0-9的数字都可以

/^1-9{4,}$/(号码从10000开始)

[^] 取反:在[]内加上^代表除去[]内的字符都可以

<script>
   console.log(/[abc]/.test('jafj'));//ture
   console.log(/[abc]/.test('jAfj'));//false

   console.log(/^[abc]$/.test('ab'));//false(只选一个!!!)
   console.log(/^[abc]{2}$/.test('ab'));//ture

   console.log(/^[a-z]$/.test('f'));//ture
   console.log(/^[a-z]$/.test('F'));//false
   console.log(/^[a-zA-Z0-9]$/.test('f'));//ture
   console.log(/^[a-z][A-Z][0-9]$/.test(3));//false:判断字符串是否由三个字符组成,并且这三个字符必须依次是小写字母、大写字母和数字。
   console.log(/^[1-9][0-9]{4,}$/.test(12345));//ture
   //^ 匹配字符串的开头
   //[1-9] 匹配1-9中的一个数字
   //[0-9]{4,} 匹配至少4位数字,即数字的长度至少为5位
   //$ 匹配字符串的结尾
</script>
<script>
       const input = document.createElement('input')
       const span = document.createElement('span')
       input.setAttribute('type','text')
       document.body.appendChild(input)
       document.body.appendChild(span)
       input.addEventListener('blur',function () {
           let tf = /^[a-zA-Z0-9-_]{6,16}$/.test(input.value)
           if (tf===true) {
               span.innerHTML= 'ture'
          }else{
               span.innerHTML = 'false'
          }
      })
   </script>
4. 预定义

某些常见方式的简写方式

[0-9]: \d

[^0-9]: \D

[a-zA-Z0-9-_]: \w

[^a-zA-Z0-9-_]: \W

[\t\r\n\v\f]: \s: 匹配空格(包括制表符,回车符,换行符,垂直制表符,换页符)

[^\t\r\n\v\f]: \S: 匹配非空格的字符

<script>
   const input = document.createElement('input')
   const button = document.createElement('button')
   document.body.appendChild(input)
   document.body.appendChild(button)
   button.innerHTML='111'
   button.addEventListener('click',function () {
       console.log(/^[12]\d{3}[01]\d[0123]\d/.test(input.value));//不能加框
       input.value = ''
  })
</script>

5. 修饰符

/表达式/修饰符

i: ignore :正则匹配时不区分大小写

g: global :匹配所有满足表达式的结果

replace:替换 : 字符串.replace(/正则/,'替换的文本')

<script>
   console.log(/^abcd$/i.test('ABCD'));

   let str = 'abaBaBaba'//不能发生改变
   str = str.replace(/b|B/g,'a')//正则里或者只要一条!虽然使用了 str.replace() 函数,但是并没有对 str 进行重新赋值,所以 str 的值仍然是原来的字符串 'abaBaBaba'。需要将 str.replace() 的结果重新赋值给 str 才能改变 str 的值。
   let str1 = str.replace(/b/ig,'a')//i是忽略大小写,一次只能替换一个,所以用'g'全部替换,'ig''gi'皆可;
   console.log(str);
   console.log(str1);
</script>