webApi第六天

118 阅读6分钟

webApi第6天

滚动事件

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

很多网页需要检测用户把页面滚动到某个区域后做一些处理, 比如固定导航栏,比如返回顶部。

事件名:scroll 监听整个页面滚动:

给 window 或 document 添加 scroll 事件。 监听某个元素的内部滚动直接给某个元素加即可。

滚动的距离

这个代码可以获取当前页面滚动的距离: document.documentElement.scrollTop

示例:

 <script>
        window.addEventListener("scroll",function(){
            //这个代码可以获取当前页面滚动的距离
            console.log(document.documentElement.scrollTop)
        })
</script>

固定导航案例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        *{
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        header{
            height: 250px;
            background-color: aqua;
        }

        nav{
            height: 250px;
            background-color: blueviolet;
            
        }

        
        .fixed{
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
        }

        div{
            background-color: pink;
        }
    </style>
</head>
<body>
    <header></header>
    <nav ></nav>
    <div>
        <ul>
            <li>1</li>
            <li>2</li>
            <li>3</li>
            <li>4</li>
            <li>5</li>
            <li>6</li>
            <li>7</li>
            <li>8</li>
            <li>9</li>
            <li>10</li>
            <li>11</li>
            <li>12</li>
            <li>13</li>
            <li>14</li>
            <li>15</li>
            <li>16</li>
            <li>17</li>
            <li>18</li>
            <li>19</li>
            <li>20</li>
            <li>21</li>
            <li>22</li>
            <li>23</li>
            <li>24</li>
            <li>25</li>
            <li>26</li>
            <li>27</li>
            <li>28</li>
            <li>29</li>
            <li>30</li>
            <li>31</li>
            <li>32</li>
            <li>33</li>
            <li>34</li>
            <li>35</li>
            <li>36</li>
            <li>37</li>
            <li>38</li>
            <li>39</li>
            <li>40</li>
            <li>41</li>
            <li>42</li>
            <li>43</li>
            <li>44</li>
            <li>45</li>
            <li>46</li>
            <li>47</li>
            <li>48</li>
            <li>49</li>
            <li>50</li>

        </ul>
    </div>

    <script>
        // 要求:鼠标滑动到导航栏的时候 导航栏固定定位在顶部


        // 获取 导航栏 和 头部
        const nav =document.querySelector("nav")
        const header =document.querySelector("header");

        //给窗口绑定鼠标滚动事件
        window.addEventListener("scroll",function(event){
            //定义一个 代表是鼠标滚动的位置
            const scrollTop=document.documentElement.scrollTop;
            //当滚动位置过了头部的时候,相当于过了头部的高度时
            if(scrollTop>=250){
                //给导航栏加个类名, 这个类名是css原先就设置好的固定定位样式等
               nav.classList.add('fixed');
               //给头部加个下外边距是自己的高度   因为导航固定定位的时候脱标了,会挡住下面的内容,给头部设置着下边距的距离 把内容挤下去显示。
               header.style.marginBottom=250+'px';
            } else{
                //未满足上面条件时,导航栏的定位标签 移除掉 以及 头部的下边距为0
                nav.classList.remove('fixed');
               header.style.marginBottom=0;
            }

        })
    </script>
</body>
</html>

小火箭返回顶部案例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body {
          height: 8000px;
          background-image: linear-gradient(red, blue);
        }
  
        a {
          color: #fff;
        }
  
        .actGotop {
          position: fixed;
          bottom: 50px;
          right: 50px;
          width: 150px;
          height: 195px;
          display: none;
          z-index: 100;
        }
  
        .actGotop a,
        .actGotop a:link {
          width: 150px;
          height: 195px;
          display: inline-block;
          background: url(./04-小火箭/images/gotop.png) no-repeat;
          outline: none;
        }
  
        .actGotop a:hover {
          width: 150px;
          height: 195px;
          background: url(./04-小火箭/images/gotop.gif) no-repeat;
          outline: none;
        }
      </style>
    </head>
  
    <body>
      <!-- 返回顶部小火箭 -->
      <div class="actGotop"><a href="javascript:;" title="Top"></a></div>
  
      <!-- 需求:
      1.滚动出屏幕的距离超过1000的时候,出现小火箭
      2.单击小火箭能够返回到顶部 -->
      
      <script>
          const div =  document.querySelector('.actGotop')
          window.addEventListener('scroll',function(){
            if (document.documentElement.scrollTop >= 100) {
                div.style.display = 'block'
            } else {  
               div.style.display = 'none'
            }
          })
          div.addEventListener('click',function () {
            //慢慢设置scrollTop 减小为0
              const timeId = setInterval(function name(params) {  
                document.documentElement.scrollTop -= 50;
                if (document.documentElement.scrollTop === 0 ) {
                  //清除定时器
                    clearInterval(timeId)
                }               
              },10)     
          })
      </script>
</body>
</html>

加载事件

load事件

标签加载完毕-标签对应外部资源加载完毕

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

为什么要学? 有很多业务和功能 都需要使用到外部资源(外部css js 图片 视频)我们希望等待资源都加载回来,才去做其他事情 写代码的时候,我们会把所有的代码 都写在 window load事件中来确保 资源全部都可以使用

事件名:load

监听页面所有资源加载完毕: 给 window 添加 load 事件。

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

DOMContentLoaded

标签加载完就触发

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

事件名:DOMContentLoaded ;

监听页面DOM加载完毕: 给 document 添加 DOMContentLoaded 事件。

  1. 因为以前写js 习惯写在head标签中,所以js会先执行, dom元素还没有开始加载。
  2. 现在js都是写在上面,所以现在该方法用的比较少。
<script>
      window.addEventListener('load', function () {
        console.log('load 标签加载完毕-标签对应外部资源加载完毕');
      });
      // DOMContentLoaded 
      // 页面的标签 都加载完毕就触发了,不需要等待标签的内容回来
      // video标签一生成, 事件就触发 
      // load事件等待 vide标签生成了,同时 video标签内的视频也加载回来 才触发 

      // video加载 分两部
      // 只是加载标签而已 很快 DOMContentLoaded    快
      // 会去加载 标签对应的视频 比较慢  load 慢
      document.addEventListener("DOMContentLoaded",function () {
        console.log("DOMContentLoaded 标签加载完毕就触发了");
      })
</script>

元素大小和位置

scroll家族

使用场景:

我们想要页面滚动一段距离,比如100px,就让某些元素显示隐藏,那我们怎么知道,页面滚动了100像素呢? 就可以使用scroll 来检测页面滚动的距离~~~

1650899237663.png

开发中,我们经常检测页面滚动的距离,比如页面滚动100像素,就可以显示一个元素,或者固定一个元素

<script>
    /* 
    scrollWidth  不包含 滚动条 大小 
    scrollWidth  等于容器可以滚动的大小 
     */
    const scrollDom = document.querySelector('.scroll-dom');
    // 输出它宽度高度
    console.log(scrollDom.scrollWidth);
    console.log(scrollDom.scrollHeight);
    // 获取当前容器滚动了的距离
    scrollDom.addEventListener('scroll', function () {
      console.log(this.scrollTop);// 获取当前容器的滚动距离
      console.log(this.scrollLeft); // 获取当前容器的滚动距离
    });

    /*
    1 页面滚动 使用  window.addEventListener("scroll") 事件
    2 页面的滚动距离 document.documentElement.scrollTop
    1 元素滚动 dom.addEventListener("scroll")
    2 获取元素滚动的距离
      dom.scrollTop
      dom.scrollLeft
    3 scrollWidth 整个可以滚动的区间的宽度
    4 scrollHeight 整个可以滚动的区域的高度 
    ---小细节  PC端的滚动条大小 17px!!!---
    ---小细节 移动端的滚动条 不占大小!!!---
     */
  </script>

offset家族

使用场景: 前面案例滚动多少距离,都是我们自己算的,最好是页面滚动到某个元素,就可以做某些事。 简单说,就是通过js的方式,得到元素在页面中的位置这样我们可以做,页面滚动到这个位置,就可以返回顶部的小盒子显示…

1650899804793.png

 <body>
    <div class="parent">
      <h1>标题</h1>
      <div>
        <div class="offset"></div>
      </div>
    </div>
    <script>
      const offsetDom = document.querySelector('.offset');

      // 获取宽度和高度 包含这滚动条的大小 
      console.log(offsetDom.offsetWidth);// 300 
      console.log(offsetDom.offsetHeight);// 300

      // console.log(offsetDom.scrollWidth); // 283
      // console.log(offsetDom.scrollHeight);// 283 

      // 获取当前元素与定位了的父元素的距离(找不到定位了的父元素,相对于页面来计算)
      console.log(offsetDom.offsetLeft);
      console.log(offsetDom.offsetTop);
      /* 
      总结 offset家族
      1 offsetWidth  获取元素的宽度 包含这滚动条
      2 offsetHeight 获取元素的高度 包含这滚动条
      3 offsetLeft 获取定位了的父元素的 水平距离 左 
      4 offsetTop 获取定位了的父元素的 垂直距离 上
       */
    </script>
  </body>

client家族

![1650900244685](webApi第6天 滚动事件.assets/1650900244685.png)

1650900244685.png

<style>
        div {
            width: 300px;
            height: 300px;
            background-color: aqua;
            margin: 100px auto;
            overflow: scroll;
            border-left: 5px solid #000;
            border-top: 10px solid #000;
        }
    </style>
</head>
<body>
    <div></div>

    <script>
        const div =document.querySelector('div')
        
        console.log(div.clientHeight);//获取可视区域的高度 (不含滚动条)
        console.log(div.clientWidth);//获取可视区域的宽度 (不含滚动条)

        console.log(div.clientLeft); //左边款宽度
        console.log(div.clientTop);//上边框高度

        // scollWidth     获取容器的宽度(包含滚动的区域)
        // offsetWidth    获取可视区域的宽度(包含滚动条)
        // clientWidth    获取可视区域的宽度(不包含滚动条)

        // scrollLeft    获取左侧滚动的距离
        // offsetLeft    获取和已经定位了的父级元素的左距离
        // clientLeft    获取左边框的大小 
    </script>
</body>

3种家族的区别总结:

获取高度和宽度
scollWidth /scollHeight获取整个滚动区域的宽度和高度(不包含滚动条的大小)
offsetWidth/offsetHeight获取可视区域的宽度和高度(包含滚动条的大小)
offsetWidth/offsetHeight获取可视区域的宽度和宽度(不包含滚动条的大小)
获取滚动距离
scrollLeft / scrollTop获取水平和垂直方向滚动的距离
offsetLeft /offsetTop获取与定位了的父元素的水平和垂直距离(寻找定位的元素按就近原则寻找,如父元素都没有定位,那就相对页面的距离)
clientLeft / clientTop获取左边框和上边框的大小

屏幕改变大小事件

window.addEventListener('resize',function (event){})
<style>
        div {
            width: 3rem;
            height: 3rem;
            font-size: 1rem;
            background-color: orange;
        }
    </style>
</head>

<body>
    <div>
        六一
    </div>
    <script>
        // 页面大小发生变化了就会触发的事件 resize window来绑定
        window.addEventListener('resize', function () {
            // console.log('change');
            //获取当前页面的宽度
            const bodyWidth = document.body.offsetWidth
            console.log(bodyWidth);
            // 移动端屏幕适配 rem   淘宝js库,flexible.js  作用  设置html的字体大小 为当前页面的宽度的十分之一
            // 获取当前页面的宽度
            // 设置页面html标签的字体大小为屏幕的十分之一
            document.documentElement.style.fontSize = bodyWidth / 10 + 'px'

            const title = document.querySelector('title')
            if (bodyWidth > 1200) {
                title.innerText = `大屏幕${bodyWidth}`
            } else if (bodyWidth > 992) {
                title.innerText = `中屏幕${bodyWidth}`
            } else if (bodyWidth > 768) {
                title.innerText = `小屏幕${bodyWidth}`
            } else {
                title.innerText = `极小屏幕${bodyWidth}`
            }
        })
    </script>
</body>

swiper-轮播图插件

插件: 就是别人写好的一些代码,我们只需要复制对应的代码,就可以直接实现对应的效果

1 下载swiper对应的文件 - css + js swiper官网: www.swiper.com.cn/

2 分布引入他们

3 拷贝别人的固定结构

4 拷贝写好的swiper 初始化js代码

例:

<!-- 
  1 下载swiper对应的文件 - css + js 
  2 分布引入他们
  3 拷贝别人的固定结构
  4 拷贝写好的swiper 初始化js代码
 -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./swiper/swiper-bundle.min.css">
    <style>
        .swiper {
            width: 600px;
            height: 300px;
        } 
    </style>
</head>
<body>
    <div class="swiper">
        <div class="swiper-wrapper">
            <div class="swiper-slide"><img src="./10-焦点轮播图/assets/b_01.jpg" alt=""></div>
            <div class="swiper-slide"><img src="./10-焦点轮播图/assets/b_02.jpg" alt=""></div>
            <div class="swiper-slide"><img src="./10-焦点轮播图/assets/b_03.jpg" alt=""></div>
            <div class="swiper-slide"><img src="./10-焦点轮播图/assets/b_04.jpg" alt=""></div>
            <div class="swiper-slide"><img src="./10-焦点轮播图/assets/b_05.jpg" alt=""></div>
        </div>
        <!-- 如果需要分页器 -->
        <div class="swiper-pagination"></div>
        
        <!-- 如果需要导航按钮 -->
        <div class="swiper-button-prev"></div>
        <div class="swiper-button-next"></div>
        
        <!-- 如果需要滚动条 -->
        <!-- <div class="swiper-scrollbar"></div> -->
    </div>

    <script src="./swiper/swiper-bundle.min.js"></script>

    
    <script>        
        var mySwiper = new Swiper ('.swiper', {
        //direction: 'vertical', // 垂直切换选项
        loop: true, // 循环模式选项
        
        // 如果需要分页器
        pagination: {
            el: '.swiper-pagination',
        },
        
        // 如果需要前进后退按钮
        navigation: {
            nextEl: '.swiper-button-next',
            prevEl: '.swiper-button-prev',
        },
        
        // 如果需要滚动条
        scrollbar: {
            el: '.swiper-scrollbar',
        },
        })        
        </script>
</body>
</html>

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

window对象

BOM

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

1650973950608.png window 是浏览器内置中的全局对象,我们所学习的所有 Web APIs 的知识内容都是基于 window 对象实现的 window 对象下包含了 navigator、location、document、history、screen 5个属性,即所谓的 BOM (浏览器对象模型) document 是实现 DOM 的基础,它其实是依附于 window 的属性。 注:依附于 window 对象的所有属性和方法,使用时可以省略 window

延时器

  • JavaScript 内置的一个用来让代码延迟执行的函数,叫 setTimeout
  • 语法:

1650974145087.png

  • setTimeout 仅仅只执行一次,所以可以理解为就是把一段代码延迟执行, 平时省略window
  • 清除延时函数:

1650974162312.png

关闭广告案例:

    <style>
        .box {
            position: fixed;
            bottom: 0;
            right: 0;
            width: 150px;
            height: 200px;
            background-color: aquamarine;
        }
    </style>
</head>

<body>
    <div class="box">大聪明</div>

    <script>
        const box = document.querySelector('.box')
        setTimeout(function () {
            box.style.display = 'none'
        }, 5000)
        /*
        // 延时器 - 只会执行一次而已
            let timeid = setTimeout(function () {
                console.log('猜猜我是谁');
            }, 5000);
            // 取消延时器
            clearTimeout(timeid); */
    </script>
</body>
  • 结合递归函数可以使用 setTimeout 实现 setInterval 一样的功能
<script>
        // 定时器 不主动清除,定时器永远执行下去
        // 延时器 只会执行一次

        // 延时器实现定时器的功能

        // 在延时器 又开启一个延时器,


        //递归  函数自己调用自己
        let num = 0;
        function digui() {
            console.log(`第${++num}次递归`);
            setTimeout(digui, 1000)
        }
        digui()
</script>

两种定时器对比

  • setInterval 的特征是重复执行,首次执行会延时
  • setTimeout 的特征是延时执行,只执行 1 次
  • setTimeout 结合递归函数,能模拟 setInterval 重复执行
  • clearTimeout 清除由 setTimeout 创建的定时任务
  • 创建的定时器应该由clearInterval来清除
  • 创建的延迟器应该由clrearTimeout来清除

递归

<script>
      /* 
      递归
      1 一个函数调用自己  

      2 使用场景
        有一个函数,可以打印出 一个dom元素的所有祖先元素 
        不可能提前知道 这个a标签有多少个父元素 

        这个函数接收一个参数,= dom 
        如果这个dom元素有父元素,就继续调用自己函数


      3 使用场景
        1 假设你现在得了肺炎 警察叔叔 
          先找你 ->  找你的邻居(得了肺炎) -> 找你的邻居的邻居(得了肺炎)->找你的邻居的邻居(得了肺炎)...
          直到找到一个邻居 没事  警察叔叔 不找结束了 
       */
      // let index = 0;

      // function func() {
      //   index++;
      //   console.log(index);
      //   func();
      // }

      // func();

      const button = document.querySelector('button');

      getParent(button);
      function getParent(dom) {
        console.log(dom);
        if (dom.parentNode) {
          // 如果有父元素
          getParent(dom.parentNode);
        } else {
          console.log('结束啦');
        }
      }
    </script>

location对象

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

  • 常用属性和方法:

    1.href 属性获取完整的 URL 地址,对其赋值时用于地址的跳转 2.search 属性获取地址中携带的参数,符号 ?后面部分 3.hash 属性获取地址中的啥希值,符号 # 后面部分 4.reload 方法用来刷新当前页面,传入参数 true 时表示强制刷新

    location 的数据类型是对象,它拆分并保存了 URL 地址的各个组成部分 常用属性和方法: href 属性获取完整的 URL 地址,对其赋值时用于地址的跳转

1650975969599.png

<body>
    <button>跳转到百度</button>
    <script>
        const button = document.querySelector('button')
        button.addEventListener('click', function () {
            // 1 使用a标签 href 属性 可以实现页面跳转
            // 2 在js中,也可以直接跳转  location.href 来跳转
            // 3 location.href 也可以实现刷新 location.href = location.href;
            // 4  location.reload(true);// true 强制刷新!
            // 5 search 后一个阶段就会用到它 了  获取 url上 ? 后面一串字符  /17-location.html?a=1&b=2
            // 6 hash 学习到了vue阶段就会用到了 获取 # 后面一串字符 /17-location.html#/index  #/index


            //跳转到百度
            // location.href = "http://www.baidu.com"

            //刷新
            // location.href=location.href

            //relode刷新
            // location.reload(true) //true  强制刷新

            //获取地址栏?后面的一串字符
            console.log(location.search);

            //获取地址栏#后面的一串字符
            // console.log(location.hash);
        })
    </script>
</body>

navigator

  • navigator的数据类型是对象,该对象下记录了浏览器自身的相关信息
  • 常用属性和方法: 通过 userAgent 检测浏览器的版本及平台

1650976392604.png

<script>
      // 作用 检测当前浏览器的版本和型号
      //  手机端来说,  安卓手机 可以直接下载apk 手机软件的 
      //               ios 手机来说 不可以直接下载手机软件 必须要回到苹果的应用商店中来下载
      // 安卓手机来说 点击 下载软件 给它下载apk
      // iphone手机来说 点击 下载软件 可能只需给苹果手机一个提示 


      // 可以识别出 当前的访问设备是 pc端还是移动端
      // 后台根据 当前用户的设备类型 来返回 对应的平台的页面
      // pc端来访问我的页面 我给你显示pc端的页面
      // 移动端来访问我的页面 我给你显示移动端的页面 
      // b站就是 


      // console.log(window.navigator.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';
      //   // }
      //   console.log(android);
      //   console.log(iphone);
      // })();
      validBrowser()
      function validBrowser() {
        var u_agent = navigator.userAgent;
        var browser_name = 'Failed to identify the browser';
        if (u_agent.indexOf('Firefox') > -1) {
          browser_name = 'Firefox';
        } else if (u_agent.indexOf('Chrome') > -1) {
          browser_name = 'Chrome';
        } else if (
          u_agent.indexOf('Trident') > -1 &&
          u_agent.indexOf('rv:11') > -1
        ) {
          browser_name = 'IE11';
        } else if (
          u_agent.indexOf('MSIE') > -1 &&
          u_agent.indexOf('Trident') > -1
        ) {
          browser_name = 'IE(8-10)';
        } else if (u_agent.indexOf('MSIE') > -1) {
          browser_name = 'IE(6-7)';
        } else if (u_agent.indexOf('Opera') > -1) {
          browser_name = 'Opera';
        } else {
          browser_name += ',info:' + u_agent;
        }
        document.write('browser_name:' + browser_name + '<br>');
        document.write('u_agent:' + u_agent + '<br>');
      }
    </script>

histroy对象

  • history 的数据类型是对象,该对象与浏览器地址栏的操作相对应,如前进、后退、历史记录等
  • 常用属性和方法:

1650976494754.png

history 对象一般在实际开发中比较少用,但是会在一些 OA 办公系统中见到。

<body>
    <a href="http://www.baidu.com">百度</a>
    
    <button class="back">后退</button>
    <button class="forward">前进</button>

    <script>
        const forward = document.querySelector('.forward')
        const back = document.querySelector('.back')

        forward.addEventListener('click',function () {
            // history.forward() //前进功能
            history.go(1)//要前进几个记录 括号内就写几
        })
        back.addEventListener('click',function () {
            // history.back() //后退功能
            history.go(-1)//要后退几个记录  括号内就写几
        })
    </script>
    
</body>