webAPIS

DOM

document object model 文档对象模型

操作网页内容,可以开发网页特效和实现用户交互

DOM树

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

DOM对象

将网页内容当成对象来处理

获取DOM对象

常用方法

document.querySelector('选择器') // 也可在其他的范围内找到对应的对象 如: window form div

根据选择器在文档中查找对应的第一个元素

document.querySelectorAll('选择器')

根据选择器在文档中查找对应的所有符合条件的元素,形成伪数组,如果没有符合的元素,则返回一个空的伪数组

括号里面写css选择器 必须是字符串,也就是必须加引号

//body 获取直接写 document.body 就可以

<body>
    <div>盒子</div>
<ul>
      <li>1</li>
      <li>2</li>
      <li>3</li>
 </ul>
<script>
    // 获取div元素
    const div = document.querySelector('div')
    // 获取所有的li标签元素
    const lis = document.querySelectorAll('li') // 伪数组
    //遍历
    for(let i = 0; i < lis.length; i++){
        console.log(lis[i]) // 打印每一个li标签元素
    }
</script>
</body>

可以根据元素的属性获取元素DOM对象

const names = document.queryselector('[name = username]') 
// 获取到文档中有 name = username属性 的元素

修改DOM元素内容

对象.innerText 属性

inner Text = textContent

能够操作标签的内容

文本中包含的标签不会被解析

对象.innerHTML 属性

能够操作标签的内容

文本中包含的标签可以被解析

<body>
    <div>盒子</div>
<ul>
      <li>1</li>
      <li>2</li>
      <li>3</li>
 </ul>

<script>
    // 获取div元素
    const div = document.querySelector('div')
    //修改div中的内容 innerText
    div.innerText = '这是一个盒子' 
    
    //使用innerHTML修改
    div.innerHTML = '<p>可以解析标签</p>'
    
    // 获取所有的li标签元素
    const lis = document.querySelectorAll('li') // 伪数组
    //遍历
    for(let i = 0; i < lis.length; i++){
        console.log(lis[i]) // 打印每一个li标签元素
    }
</script>
</body>

设置/修改DOM元素属性

设置/修改元素常用属性

最常见的属性 比如: href、title、src 等

<body>
  <img src="./images/1.jpg" width="500" alt="" />
  <script>
      // 设置/修改元素常用属性(src 、title等属性)
    let imgobj = document.querySelector('img')
      // 语法:对象.属性 = 值
    imgobj.src = './images/5.jpg';
    imgobj.title = '更换了图片'

  </script>
</body>

设置/修改元素样式属性

通过类名操作CSS
className属性
<body>
  <div class="box"></div>
  <script>
    // 使用className操作类名修改样式
      let divobj = document.querySelector('div')
      divobj.className = 'active'
    // 注意说明: 
    //  1. 在JS中使用className表示类名,因为class是个关键字
    //  2. 使用className有 覆盖 问题
  </script>
</body>
classList 语法
 classList 是追加和删除不影响以前类名
    // 使用classList操作类名修改样式
    //  classList.add()  添加类名
    //  classList.remove() 删除类名
    //  classList.toggle()  切换类名
    //  classList.contain() 是否包含这个类名
    // 说明:
    // classList 和 className之间的区别
    // clssName 是属性 属性用 =
    // classList add是方法,方法用()
    // 获取对象是方法  修改元素内容是属性(常用属性,样式属性)
    // document.querySelector('')
通过 style 属性操作CSS

语法:对象.style.样式属性名 = 值

注意:

1.修改样式通过style属性来实现

2.如果属性有-连接符,需要转换为 驼峰命名法 font-size 转换为 fontSize

3.赋值的时候,需要的时候不要忘记加css单位 (px)

4.设置背景图片,图片路径写在url()中

设置/修改 表单元素 属性

获取: DOM对象.属性名

设置: DOM对象.属性名 = 新值

 let inp1 = document.querySelector('.inp1')
    let inp2 = document.querySelector('.inp2')
    // value属性
      inp1.value = '默认值修改'
       
    // type属性
      inp1.type = 'password'

    // 布尔类型的属性 (disabled、checked、selected)
      inp1.disabled = true
      inp2.checked = false
      inp2.disabled = true

定时器函数

开启定时器

setInterval(函数, 间隔时间)

setInterval(function(){ // 回调函数
   console.log('100')
},1000) // 间隔时间

作用:每隔一段时间,调用这个函数

间隔时间单位是毫秒

function fn(){
console.log(123);
}
setInteval(fn,1000) // 每隔一秒调用函数一次,定时器调用函数时不需要加括号
 //错误的,加括号函数直接被调用了就没有定时效果了
    //  setInterval(fn(),1000)

关闭定时器

关闭定时器语法:clearInterval(定时器id)

函数名字不需要加括号

定时器返回的是一个id数字

let timerId = setInterval(function(){
         console.log('定时器')
     }, 1000)
 //关闭定时器
 clearInterval(timerId) // timerId是定时器的Id

事件

什么是事件?

事件是在编程时系统内发生的动作或者发生的事情

比如用户在网页上单击一个按钮

事件监听

就是让浏览器检测是否有事件产生,一旦有事件触发,就立即调用一个函数做出响应,也称为 注册事件

语法

//先获取想要注册事件的元素,然后注册事件
const str = document.queryselector('选择器') //也可根据元素的属性寻找元素
str.addEventListener('事件',function(){
    //触发事件将要执行的代码
})

事件监听三要素:

事件源: 哪个dom元素被事件触发了

事件: 用什么方式触发,比如鼠标单击 click、鼠标经过 mouseenter 等

事件处理程序(调用的函数): 要做什么事

注意:

  1. 事件类型要加引号

  2. 函数是点击之后再去执行,每次触发事件都会执行一次中间的代码

事件监听版本

DOM L0 事件源.on事件 = function() { }

DOM L2 事件源.addEventListener(事件, 事件处理函数)

发展史:

DOM L0 :是 DOM 的发展的第一个版本; L:level

DOM L1:DOM级别1 成为W3C推荐标准

DOM L2:使用addEventListener注册事件

DOM L3: DOM3级事件模块在DOM2级事件的基础上重新定义了这些事件,也添加了一些新事件类型

事件类型

鼠标事件

click 鼠标点击

mouseenter 鼠标经过

mouseleave 鼠标离开

焦点事件

focus 获得焦点

blur 失去焦点

键盘事件

Keydown 键盘按下触发

Keyup 键盘抬起触发

文本事件

input 用户输入事件

change 改变,用户改变输入框中的值后失去焦点触发

maxlength属性可以控制输入的字符数量

readonly 只读

length属性可以得知字符串的长度

高阶函数

JavaScript 中函数可以被当成【值】来对待

【值】就是 JavaScript 中的数据,如数值、字符串、布尔、对象等

函数表达式

就是将匿名函数赋值给变量

let fn = function(a,b){
   return a + b
}
console.log(fn(5,10)) // 15

回调函数

把一个函数a当成参数传递给另外一个函数b,就说a函数是个回调函数 例如定时器 注册事件

btn.addEventListener('click',function(){  //里面的函数就是回调函数
})

环境对象

函数内部,有一个特殊的变量 this ,称之为 环境对象

事件处理函数中 this 指向 => 事件源

let btn = document.querySelector('button')
        btn.addEventListener('click', function () {
           this.style.width = '100px'
           this.style.height = '100px'
        })

编程思想--排他思想

  1. 干掉所有人

  2. 复活他自己

节点操作

DOM节点

DOM树里每一个内容都称之为节点

元素节点

所有的标签 比如 body、 div

属性节点

所有的属性 比如 href

文本节点

所有的文本

节点关系:

父节点

子节点

兄弟节点

查找节点

查找父节点

子元素.parentNode

<body>
    <div class="father">
        <div class="son">儿子</div>
    </div>
    <script>
        // 查找son的父元素
        let son = document.querySelector('.son')
        // parentNode 属性
        console.log(son.parentNode)
    </script>
</body>
子节点查找:

父元素.children (重点)

获得所有元素节点

返回的还是一个伪数组

childNodes

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

<body>
    <button>点击</button>
    <ul>
        <li>我是孩纸</li>
        <li>我是孩纸</li>
        <li>我是孩纸</li>
        <li>我是孩纸</li>
        <li>我是孩纸</li>
        <li>我是孩纸</li>
    </ul>
    <script>
        // 需求: 点击按钮,获取ul所有的子元素
        let btn = document.querySelector('button')
        let ul = document.querySelector('ul')         
        btn.addEventListener('click', function () {
            // children 查找所有的子元素  
            console.log(ul.children)                
        })
    </script>
</body>
兄弟关系查找

下一个兄弟节点 nextElementSibling 属性

上一个兄弟节点 previousElementSibling 属性

<body>
    <button>点击</button>
    <ul>
        <li>第1个</li>
        <li class="two">第2个</li>
        <li>第3个</li>
        <li>第4个</li>
    </ul>
    <script>
        // 演示兄弟节点
        let btn = document.querySelector('button')
        let two = document.querySelector('.two')
        btn.addEventListener('click', function () {
            // 上一个兄弟节点   属性
            console.log(two.previousElementSibling)
            // 下一个兄弟节点   属性
            console.log(two.nextElementSibling)
        })
    </script>
</body>

增加节点

创建一个新的节点

把创建的新的节点放入到指定的元素内部

创建节点

语法

document.createElement('标签名')

插入到父元素的最后一个子元素:

父元素.appendChild(要添加的元素)

插入到父元素中某个子元素的前面

父元素.insertBefore(要添加的元素, 在谁前面)

<body>
    <ul>
      <li>我是大毛</li>
      <li>我是二毛</li>
    </ul>
 <script>     
      let ul = document.querySelector("ul");
      // 创建节点
      // 语法: document.createElement('标签名')
      let lili = document.createElement("li");
      //给创建的li添加内容和样式
      lili.innerHTML = "这是小明";
      lili.style.color = "pink";
      // li添加到页面ul中
      ul.appendChild(lili);
      // 语法:父元素.appendChild(要添加的元素)
      // 作用:将元素放到父元素的里面的最后面
      // 语法:父元素.insertBefore(要添加的元素, 在谁前面)
      // 作用:将节点添加到指定的节点前面
      // 需求:将创建的li添加到第一个li的前面
      ul.insertBefore(lili, ul.children[0]); //ul.children是个伪数组
      //insertBefore中的参数必须有两个,一个会报错,第二个如果为null或者undefined则时为appendChild的效果
      ul.insertBefore(lili, null);
    </script>
  </body>
克隆节点

语法:元素.cloneNode(布尔值)

true 会克隆节点自身,后代节点会克隆的

false 默认值 只会克隆节点自身,后代节点不会克隆的

<body>
    <ul>
      <li>我是内容1</li>
      <li>我是内容2</li>
      <li>我是内容3</li>
    </ul>
    <script>
      // 需求:克隆ul节点到body中
      let ul = document.querySelector("ul");
      //let body = document.querySelector("body");   === document.body   
      let ul2 = ul.cloneNode(true); // 参数为true时,ul里面的li标签也会一起克隆
      document.body.appendChild(ul)      
    </script>
  </body>

删除节点

语法:父节点.removeChild(要删除的元素)

如不存在父子关系则删除不成功

删除节点和隐藏节点(display:none) 有区别的: 隐藏节点还是存在的,但是删除,则从html中删除节点

<body>
    <ul>
        <li>我是内容1</li>
        <li>我是内容2</li>
        <li>我是内容3</li>
    </ul>
    <script>
        // 需求: 点击li,删除点击的li
        let ul = document.querySelector('ul')
        let lis = document.querySelectorAll('li')
        // 删除节点
        // 语法:父节点.removeChild(child)
        for (let i = 0; i < lis.length; i++) {
            lis[i].addEventListener('click', function () {
                //删除: 父节点.removeChild(子节点)
               ul.removeChild(this)  // this 指向每一个点击的元素li
            })
        }
    </script>
</body>

时间对象

创建时间对象

语法: new Date()

  // 得到当前时间
         let date = new Date()
         console.log(date);  // Mon May 30 2022 20:44:46 GMT+0800 (中国标准时间)
  // 得到指定时间
         let date2 = new Date ('1900')
         console.log(date2); // Mon Jan 01 1900 08:05:43 GMT+0805 (中国标准时间)

时间对象方法

<script>
        // 时间对象方法
        // 步骤:
        // 1. 先创建时间对象
        let date = new Date()
        console.log(date);
        // 2. 时间对象 去调用方法得到年月日

        // 年 四位数年份
         console.log(date.getFullYear())
        // 月 0-11,需要加1
        console.log(date.getMonth()+1)
        // 日 每个月不同
        console.log(date.getDate())
        // 时 0-23
        console.log(date.getHours())
        // 分 0-59
        console.log(date.getMinutes())
        // 秒 0-59
        console.log(date.getSeconds())
        // 星期几  0-6 星期天是0
        console.log(date.getDay())
 </script>

时间戳

是指1970年01月01日00时00分00秒起至现在的毫秒数,它是一种特殊的计量时间的方式

 <script>
      // 时间戳:距离1970年总的毫秒数,值是独一无二的
      //  使用场景:倒计时效果
      let date = new Date();
      let date2 = new Date("2020");
      // 方式1:
      // 到当前的时间
      console.log(date.getTime());
      // 到指定的时间
      console.log(date2.getTime());
      // 方式2:
      console.log(+new Date());
      console.log(+new Date("2020"));
      // 方式3:
      // 获得到当前的时间
      // 缺点:无法获得指定时间
      console.log(Date.now());
 </script>

重点记住 +new Date() 因为可以返回当前时间戳或者指定的时间戳

重绘和回流

回流(重排)

当 Render Tree (渲染树)中部分或者全部元素的尺寸、结构、布局等发生改变时,浏览器就会重新渲染部分或全部文档 的过程称为 回流。

重绘

由于节点(元素)的样式的改变并不影响它在文档流中的位置和文档布局时(比如:color、background-color、

outline等), 称为重绘

重绘不会引起回流,而回流一定会引起重绘

会导致回流(重排)的操作:

页面的首次刷新

浏览器的窗口大小发生改变

元素的大小或位置发生改变

改变字体的大小

内容的变化(如:input框的输入,图片的大小)

激活css伪类 (如::hover)

脚本操作DOM(添加或者删除可见的DOM元素)

简单理解影响到布局了,就会有回流

事件对象

当事件触发的时候,产生的对象,该对象记录有事件相关的信息

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

一般命名为event、ev、e

document.addEventListener('click',function(e){
              console.log('事件点击触发',e.tagName)
          })

常用属性

pageX/pageY

获取光标相对于页面左上角的位置

key

用户按下的键盘键的值

keydown 键盘摁下

keyup 键盘弹起

 document.addEventListener('keydown',function(e){
             console.log('键盘摁下了',e.key)
        })    
        document.addEventListener('keyup',function(e){
             console.log('键盘弹起',e.key)
        })  

事件流

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

假设页面里有个div,当触发事件时,会经历两个阶段,分别是捕获阶段、冒泡阶段

简单来说:捕获阶段是 从父到子 冒泡阶段是从子到父

事件冒泡概念:

当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发。这一过程被称为事件冒

简单理解:当一个元素触发事件后,会依次向上调用所有父级元素的同名事件

事件冒泡是默认存在的

事件捕获概念:

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

//document.addEventListener(事件类型,事件处理程序,是否使用捕获机制)

addEventListener第三个参数传入true代表是捕获阶段触发(了解即可)

若传入false代表冒泡阶段触发,默认就是false

若是用 L0 事件监听,则只有冒泡阶段,没有捕获

阻止事件流动

阻止事件流动需要通过事件对象来实现

语法: 事件对象.stopPropagation();

<body>
    <div class="father">
      <div class="son"></div>
    </div>
    <script>
      // 阻止事件流动
      // 需求:在点击son的时候,点击事件不要冒泡到father上
      let fa = document.querySelector(".father");
      let son = document.querySelector(".son");
      son.addEventListener("click", function (e) {
        console.log("is son");
        // 阻止事件流动,点击son时不会冒泡到fa上面
        e.stopPropagation();
      });      
    </script>
  </body>

此方法可以阻断事件流动传播,不光在冒泡阶段有效,捕获阶段也有效

鼠标经过事件:

mouseover 和 mouseout 会有冒泡效果

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

传统on注册(L0)

同一个对象,后面注册的事件会覆盖前面注册(同一个事件)

Ø 直接使用null覆盖就可以实现事件的解绑

都是冒泡阶段执行的

事件监听注册(L2)

语法: addEventListener(事件类型, 事件处理函数, 是否使用捕获)

后面注册的事件不会覆盖前面注册的事件(同一个事件)

可以通过第三个参数去确定是在冒泡或者捕获阶段执行

必须使用removeEventListener来解绑(事件类型, 事件处理函数, 获取捕获或者冒泡阶段)

匿名函数无法被解绑

<body>
    <button>点击</button>
    <script>
        // 演示on 和 addEventListener注册事件的区别
        let btn = document.querySelector('button')
        // 缺点:给同一个元素注册同一个事件多次,后面会覆盖前面
        btn.onclick = function () {
            console.log(1)
        }
        btn.onclick = function () {
            console.log(2)
        }
        // 使用addEventListener注册的事件不会有覆盖问题
        btn.addEventListener('click', function () {
            console.log(3)
        })
        btn.addEventListener('click', function () {
            console.log(4)
        })
        // 需求:按钮的点击事件只能触发一次
        // 解绑事件
        // 解绑语法: 元素.onclick = null
        btn.onclick = function(){
            alert('1')
            btn.onclick = null
        }
        // addEventListener 注册的事件如何解绑 ==> 需要使用removeEventListener来进行解绑
        // 没有函数名解绑不了
        btn.addEventListener('click',function(){
            alert('1')
        })
        btn.removeEventListener('click',function(){
        })
        function fn(){
            alert('1')
            btn.removeEventListener('click',fn)           
        }
        btn.addEventListener('click',fn)        
    </script>
</body>

阻止浏览器的默认行为

阻止默认行为,比如链接点击不跳转,表单域的不提交

事件对象.preventDefault()

<body>
    <a href="http://www.baidu.com">跳转到百度</a>
    <script>
      // 阻止浏览器的默认行为
      // 事件对象e有 方法可以来阻止浏览器的默认行为
      let a = document.querySelector("a");
      a.addEventListener("click", function (e) {
        alert("哈哈,被点击了");
        // 阻止浏览器默认的点击跳转
        e.preventDefault();
      });
    </script>
  </body>

事件委托

优点:给父级元素加事件(可以提高性能)

原理:事件冒泡,给父元素注册的事件,子元素是可以触发

实现:事件对象.target,可以获得真正触发事件的元素

事件对象.target

<body>
    <button class="create">新建元素</button>
    <div class="box">
      <p>这是第1个</p>
      <p>这是第2个</p>
      <p>这是第3个</p>
    </div>
    <script>
      // 需求:点击p元素 出现弹框
      let box = document.querySelector(".box");
      let ps = document.querySelectorAll(".box p");
      let create = document.querySelector(".create");
      // 常规做法:找到所有的p,给所有的p注册click
      // for (let i = 0; i < ps.length; i++) {
      //   ps[i].onclick = function () {
      //     alert("哈哈");
      //   };
      // }
      // 点击按钮,新建p添加到div中
      create.addEventListener("click", function () {
         let p = document.createElement('p')
         p.innerHTML = '这是个新建的p标签'
         box.appendChild(p)
      });

      // 事件委托做法:
      // 做法:把事件委托注册给父元素(祖先元素)
      // 优点:可以提高性能
      // 原理:事件冒泡,在父元素中点击都有效果
      box.addEventListener('click',function(e){
          if(e.target.tagName === 'P'){
            alert('哈哈')
          }
      })
    </script>
  </body>

滚动事件和加载事件

滚动事件

当页面进行滚动时触发的事件

事件名:scroll

监听整个页面滚动:

给 window 或 document 添加 scroll 事件

<script>
      // 演示 scroll 滚动事件
      window.addEventListener("scroll", function () {
        console.log("页面滚动了");
      });
      // 给页面注册滚动事件, 可以给document 或者给 window对象
      // document.addEventListener("scroll", function () {
      //   console.log("页面滚动了");
      // });
    </script>

加载事件

加载外部资源(如图片、外联CSS和JavaScript等)加载完毕时触发的事件

为什么要学?

有些时候需要等页面资源全部处理完了做一些事情

老代码喜欢把 script 写在 head 中,这时候直接找 dom 元素找不到

事件名:load

监听页面所有资源加载完毕:

给 window 添加 load 事件

注意:不仅可以监听整个页面资源加载完毕,也可以针对某个资源绑定load事件

 window.addEventListener("load", function () {
        let div = document.querySelector("div");
        div.addEventListener("click", function () {
          alert("点击登录");
        });
      });

当初始的 HTML 文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,而无需等待样式表、

图像等完全加载

事件名:DOMContentLoaded

监听页面DOM加载完毕:

给 document 添加 DOMContentLoaded 事件

注意:load 是给window注册,DOMContentLoaded 是给document注册

 document.addEventListener('DOMContentLoaded',function(){
        let pic = document.querySelector('.pic')
        pic.addEventListener('click',function(){
          alert('haha')
        })
      })

三大家族 --元素位置和大小

• scroll家族

获取宽高:

获取元素的内容总宽高(不包含滚动条)返回值不带单位

只读属性

获取位置:

scrollLeft和scrollTop

获取元素内容往左、往上滚出去看不到的距离

这两个属性是可以修改

获取页面的滚动卷曲距离: document.documentElement.scrollTop

document.documentElement = HTML HTML文档返回对象为HTML元素

<script>
      // 元素内容的宽高,只是文本内容,不包含滚动条
      // scrollWidth scrollHeight  获取元素内容 宽高 (了解) 返回纯数值,可以直接参与运算
      // scrollWidth scrollHeight 是只读属性,赋值无效
      let box = document.querySelector("div");
      console.log(box.scrollWidth, box.scrollHeight);
      // scrollLeft scrollTop 获取内容滚动卷曲距离
      // 离初始位置移动的距离
      console.log(box.scrollLeft,box.scrollTop)
      
      // 需求:给div注册 scroll 滚动事件,滚动一下就来获取内容滚动卷曲距离
      box.addEventListener("scroll", function () {
        console.log(box.scrollLeft, box.scrollTop);
      });
      // scrollLeft 和 scrollTop可以赋值修改
       box.scrollLeft = 100
      // html = document.documentElement
    </script>

• offset家族

获取宽高:

offsetWidth和offsetHeight

获取元素的真实宽高、包含元素自身设置的宽高、padding、border

获取位置:

offsetLeft和offsetTop

获取元素距离自己定位父级元素的左、上距离

如果都没有则以 文档左上角 为准

注意都是只读属性

• client家族

获取宽高:

clientWidth和clientHeight

获取元素的可见部分宽高(不包含边框,滚动条等)

获取位置:

clientLeft和clientTop

获取左边框和上边框宽度

注意都是只读属性

会在窗口尺寸改变的时候触发事件:

resize

window.addEventListener('resize'function(){
console.log('页面窗口改变了')
})

总结

offset家族

offsetWidth offsetHeight 获取元素自身大小:包括自身设置的宽高、padding,border

offsetLeft offsetTop 获取元素距离定位父级的左和上距离

都是只读属性

client家族

获取元素可见区域的大小

获取元素左、上边框距离

都是只读属性

scroll家族

获取元素内容的总大小 只读属性

获取元素向左向上滚出去看不见的距离 可读写属性

BOM

BOM(Browser Object Model ) 是浏览器对象模型

window 是浏览器内置中的全局对象,我们所学习的所有 Web APIs 的知识内容都是基于 window 对象实现的

window 对象下包含了 navigator、location、document、history、screen 5个属性,即所谓的 BOM (浏览器对象模型 )

document 是实现 DOM 的基础,它其实是依附于 window 的属性。

l 注:依附于 window 对象的所有属性和方法,使用时可以省略 window

延时器

JavaScript 内置的,用来让代码延迟执行的函数,叫 setTimeout

setTimeout 仅仅只执行一次,平时省略window

<script>
              // 需求:将fn函数延时3秒后执行
              function fn() {
                  console.log('此处是fn函数在执行')
              }
              // 开启延时器语法:setTimeout(函数, 延时时间)
              // 作用:将函数延时一段时间来执行
             let timerId = setTimeout(fn,3000)
              // 关闭延时器:clearTimeout(timerId)
              //   timerId 延时器的id ==> 开启延时器的返回值
              clearTimeout(timerId)             
    </script>

js执行机制

JavaScript 是单线程 编程语言,就是说,同一个时间只能做一件事

同步与异步任务

为了解决单线程带来的问题,JS中将任务(需要执行的代码)分成两类:

同步任务

只有前一个任务执行完毕,才能执行后一个任务

程序的执行顺序与任务的书写顺序是一致的。

同步任务会有阻塞

异步任务

异步任务由 JavaScript 委托给宿主环境(浏览器)进行执行

当异步任务执行完成后,会通知 JavaScript 主线程执行异步任务的回调函数

异步任务不会有阻塞

常见异步任务

注册事件

setTimeout setInterval

Ajax

事件循环 EventLoop

1.同步任务由 JavaScript 主线程依次来执行

2.异步任务委托给宿主环境(浏览器)执行

3.已完成的异步任务对应的回调函数,会被加入到任务队列中等待执行

4.JavaScript 主线程的执行栈被清空后,会读取任务队列中的回调函数

5.次序执行 JavaScript 主线程不断重复上面的第 4 步

location对象

常用属性

href 属性获取完整的 URL 地址,对其赋值时用于地址的跳转

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

hash 属性获取地址中的哈希值,符号 # 后面部分 后期vue路由的铺垫,实现单页应用,比如 网易云音乐

reload 方法用来刷新当前页面

navigator对象

navigator对象记录了浏览器自身的相关信息

常用属性

通过 userAgent 检测浏览器的版本及平台

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

histroy对象

常用属性和方法:

history.back() 后退功能

history.forward() 前进功能

history.go(参数) 前进后退功能,如果参数为1 ,前进一步,参数为-1,后退一步

swiper插件

学习插件的基本过程

熟悉官网,了解这个插件可以完成什么需求 https://www.swiper.com.cn/

看在线演示, 找到符合自己需求的demo https://www.swiper.com.cn/demo/index.html

查看基本使用流程 https://www.swiper.com.cn/usage/index.html

查看APi文档,去配置自己的插件 https://www.swiper.com.cn/api/index.html

注意: 多个swiper同时使用的时候, 类名需要注意区分

本地储存

localStorage

// 存储数据

语法: localStorage.setItem('键', '值')

获取数据

语法: localStorage.getItem('键')

删除数据

语法: localStorage.removeItem('键')

简单数据类型

         localStorage.setItem('name','张三')
         localStorage.setItem('age','18')
         console.log(localStorage.getItem('age'))
        //  localStorage.removeItem('name')
        // 同名的会覆盖
         localStorage.setItem('name','法外狂徒')
         sessionStorage.setItem('gender','男')
         sessionStorage.setItem('name','小明')  //临时储存,关闭浏览器就销毁
        //  同名的sessionStorage和loclStorage 之间不会覆盖 两个不是储存在一个地方        

sessionStorageloclStorage语法基本相同

复杂数据类型

存储复杂数据类型存储

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

需要将复杂数据类型转换成JSON字符串,在存储到本地

JSON.stringify(复杂数据类型)

将复杂数据转换成JSON字符串 存储 本地存储中

JSON.parse(JSON字符串)

将JSON字符串转换成对象 取出 时候使用

 let obj = {
            uname: '老王',
            age: 38,
            skill: '翻墙',
            house: '内蒙海景房'
        }
// 说明:本地存储只适合存字符串,不能直接将复杂数据类型进行本地存储
        // localStorage.setItem('obj','obj')//错误操作,不能读取到对象里的数据
        // 正确操作       
        //  本地储存,先将对象转换成字符串,然后进行本地存储
        localStorage.setItem('对象名',JSON.stringify(obj))
        //  获取本地存储的数据,此时获取出来的是字符串类型
        console.log(localStorage.getItem('obj'))
        // 在将JSON字符串解析成JS的复杂数据
        console.log(JSON.parse(localStorage.getItem('对象名')))

自定义属性

固有属性: 标签自带的属性 比如class id title等

自定义属性: 由程序员自己添加的属性

获取自定义属性: 元素.getAttribute('属性名')

设置自定义属性: 元素.setAttribute('属性名', '属性值’)

删除自定义属性 : 元素.removeAttribute('属性名')

//以上不常用

自定义属性规范做法: data-自定义属性

规范的自定义属性做法:在标签上以data-开头

在DOM对象上以dataset对象方式操作

<body>
    <div class="box" data-id="10">哈哈</div>

    <script>
        let box = document.querySelector('.box')
        console.log(box.dataset.id) 
    </script>
</body>

正则表达式

正则表达式(Regular Expression)是用于匹配字符串中字符组合的模式

在 JavaScript中,正则表达式也是对象

语法

const reg = /正则表达式/

test() 方法 用来查看正则表达式与指定的字符串是否匹配

如果正则表达式与指定的字符串匹配 ,返回true,否则false

//   包含"pit"的正则,测试字符串:"What a pity"
const string = 'What a pity'
const str = /pit/ //正则表达式
console.log(str.test(string)) // true

exec() 方法 在一个指定字符串中执行一个搜索匹配

如果匹配成功,exec() 方法返回一个数组,数组的第一个元素返回的是结果,否则返回null

/ 定义正则表达式
      let num1 = /1/;
      let num2 = /前端/;
// 正则的exec方法  搜索匹配字符串 
      console.log(num2.exec("前端阶段"));//返回数组
      console.log(num1.exec("正则表达式"));//返回nul

组成

普通字符

大多数的字符仅能够描述它们本身,这些字符称作普通字符,例如所有的字母和数字

元字符(特殊字符)

[a-z] 中括号中间代表一个值 a-z之间任意一个字母 //正则没用修饰符要区分大小写

[ ] 里面加上 ^ 取反符号 代表不是其中任意一个字符

[^a-z] 匹配除了26个小写英文字母之外的其他任何单个字符

- 字符类 (比如 \d 表示 0~9)

\d : 0-9之间所有数字,相当于[0-9]

\D: 匹配到0-9之外的所有字符,相当于[^0-9]

\w: 匹配任意数字,字母,下划线 ,相当于[a-zA-Z0-9_]

\W: 匹配除了任意数字,字母,下划线以外的字符 ,相当于[^a-zA-Z0-9_]

\s: 匹配 空格

\S: 匹配非空格的字符

. 点表示除了换行以外的任意字符

- 边界符(表示位置,开头和结尾,必须用什么开头,用什么结尾)

开头 ^

结尾 $

两个一起使用代表精确匹配

- 量词 (表示重复次数)

// 元字符 - 量词

* 0次或无数次

+一次或无数次

? 0次或一次

{n} n次

{n,} 大于等于n次

{n,m} n到m次,包含n和m次

或的使用和优先级

| 或的优先级最低 左右两边都是个单独的整体

() 优先级最高

 // | 优先级最低   左右两边都是个单独的整体
        console.log(/f|boot/.test('f'))//true
        console.log(/f|boot/.test('foot'))//true
        console.log(/f|boot/.test('boot'))//true
        console.log(/f|boot/.test('boo'))//false
        console.log(/f|boot/.test('foo'))//true
        console.log(/f|boot/.test('oot'))//false

        // () 优先级最高
        console.log(/(f|b)oot/.test('f'))//false
        console.log(/(f|b)oot/.test('foo'))//false
        console.log(/(f|b)oot/.test('boo'))//false
        console.log(/(f|b)oot/.test('oot'))//false
        console.log(/(f|b)oot/.test('foot'))//true
        console.log(/(f|b)oot/.test('boot'))//true
修饰符

i 忽略大小写

/表达式/i

g 匹配所有符合条件的字符串

/表达式/g

/表达式/修饰符 i和g可以组合使用 /hello/ig

替换 replace

字符串.replace(/正则表达式/,‘要替换的文本’)

<script>
      let str = "  abc def  abcx  yzABCsff  ";
      // 需求:将所有的空格去除掉
      // 字符串有replace方法
      //  语法: 字符串.replace(正则表达式, '替换的文本')
      str = str.replace(/\s/g, ""); //将所有空格替换为空字符串
      console.log(str);      
      console.log(str.replace(/a/gi,'13'));
      console.log(str.replace(/a/gi,'$&00')); // 替换成了a00,$&可以代替前面要替换的内容
    </script>
// 过滤关键字
<body>
    <textarea name="" id="" cols="30" rows="10"></textarea>
    <button>发布</button>
    <div></div>
    <script>
        let btn = document.querySelector('button')
        let textarea = document.querySelector('textarea')
        let div = document.querySelector('div')
        btn.addEventListener('click', function () {
            // 将文本域的内容设置到div中展示
            div.innerHTML = textarea.value
            // 需求:过滤用户输入的内容
            //      敏感词: 激情 或 基情字眼替换成 **
            console.log(textarea.value.replace(/激情|基情/g,'**'));
            div.innerHTML = textarea.value.replace(/激情|基情/g,'**')
        })
    </script>
</body>
字符串.match()

匹配满足条件的字符串

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,830评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,992评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,875评论 0 331
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,837评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,734评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,091评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,550评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,217评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,368评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,298评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,350评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,027评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,623评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,706评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,940评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,349评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,936评论 2 341

推荐阅读更多精彩内容