js学习之路(三)

1. 封装范围内随机整数

 /*
      封装范围内随机整数

      1. 0 ~ 10 之间的随机整数
        + Math.random() 可以拿到 0 ~ 1
        + 乘以 10,
        + 取整
          => Math.floor()
          => Math.ceil()
          => Math.round()
        + 0 ~ 0.999 之间
          => * 10 以后, 0 ~ 9.999 之间
          => 向下取整, 0 ~ 9
          => 向上取整, 1 ~ 10
          => 四舍五入, 0 ~ 10
            -> 0 ~ 0.499    0
            -> 0.5 ~ 1.499  1
            -> 8.5 ~ 9.499  9
            -> 9.5 ~ 9.999  10
        + 方案2:
          => Math.random()
          => 乘以 (10 + 1)
          => 向下取整
          => 0 ~ 0.999 * 10 得到 0 ~ 10.999
          => 向下取整
            -> 0 ~ 0.999     0
            -> 1 ~ 1.999     1
            -> 10 ~ 10.999   10
    */

    // 1. 0 ~ 10 方案1
    // var res = Math.round(Math.random() * 10)
    // 成成若干个试一下
    // var obj = {}
    // for (var i = 0; i < 100000; i++) {
    //   var res = Math.round(Math.random() * 10)
    //   if (obj[res]) {
    //     obj[res]++
    //   } else {
    //     obj[res] = 1
    //   }
    // }
    // console.log(obj)

    // 方案2
    // var obj = {}
    // for (var i = 0; i < 100000; i++) {
    //   var res = Math.floor(Math.random() * (10 + 1))
    //   if (obj[res]) {
    //     obj[res]++
    //   } else {
    //     obj[res] = 1
    //   }
    // }
    // console.log(obj)


    /*
      2. 0 ~ 20 的随机整数
        => Math.random() * (20 + 1)
        => 向下取整
    */

    // var obj = {}
    // for (var i = 0; i < 100000; i++) {
    //   var res = Math.floor(Math.random() * (20 + 1))
    //   if (obj[res]) {
    //     obj[res]++
    //   } else {
    //     obj[res] = 1
    //   }
    // }
    // console.log(obj)


    /*
      3.
        + 10 ~ 20 之间的随机整数
          => 取 0 ~ 10 之间的随机整数 + 10
        + 20 ~ 30 之间的随机整数
          => 0 ~ 10 之间的随机整数 + 20
        + 30 ~ 50 之间的随机整数
          => 0 ~ 20 之间的随机整数 + 30
        + 取 n ~ m 之间的随机整数
          => 取 0 ~ (m - n) 之间的随机整数 + n
        + 0 ~ 10 之间的随机整数
          => Math.random() * (10 + 1)
        + 0 ~ 20 之间的随机整数
          => Math.random() * (20 + 1)
        + 0 ~ (m - n) 之间的随机整数
          => Math.random() * (m - n + 1)
    */

    // 去一个 10 ~ 20 之间的随机整数
    // var n = 30
    // var m = 50

    // var obj = {}
    // for (var i = 0; i < 100000; i++) {
    //   var res = Math.floor(Math.random() * (m - n + 1) + n)
    //   if (obj[res]) {
    //     obj[res]++
    //   } else {
    //     obj[res] = 1
    //   }
    // }
    // console.log(obj)


    /*
      把这段代码封装起来

      1. 准备一个函数, 接收两个参数
      2. 计算一个随机整数
      3. 把随机整数返回
        => 只返回一个数字
    */

    // 1. 准备函数
    function rangeRandom(a, b) {
      // 2. 计算随机整数
      // 需要考虑谁大谁小
      var max = Math.max(a, b)
      var min = Math.min(a, b)
      var res = Math.floor(Math.random() * (max - min + 1) + min)

      // 3. 返回结果
      return res
    }

    var n = 30
    var m = 50

    var obj = {}
    for (var i =                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                0; i < 100000; i++) {
      var res = rangeRandom(10, 20)
      if (obj[res]) {
        obj[res]++
      } else {
        obj[res] = 1
      }
    }
    console.log(obj)

2. 生成一个随机颜色

 /*
      生成一个随机颜色
        + 几种表示方式
          1. rgb()
          2. 十六进制
        + 需要封装一个函数
          => 返回一个字符串, 是一个颜色的表示方法
          => 返回: 'rgb(255, 255, 255)'
          => 返回: '#FFFFFF'
          => 我们可以由一个参数决定, 你是返回一个 十六进制 还是 rgb
        + 需要一个函数, 接收一个参数
          => 表示是否是十六进制
          => true, 表示 十六进制
          => 不传递或者 false, 就表示 rgb
    */

    function randomColor(type) {
      if (!type) {
        // 返回一个 rgb 颜色
        var res = `rgb(${ rangeRandom(0, 255) }, ${ rangeRandom(0, 255) }, ${ rangeRandom(0, 255) })`
        return res
      }

      // 代码能来带这里, 表示 type 是一个 true
      // 生成一个 十六进制 的颜色, 返回
      // 将来我要返回一个 #ABCDEF
      // 前面 # 不变, 后面每两个数字是 0 ~ 255 的随机数字转成 16 进制
      var str = '#'

      // 循环一段代码执行三次
      for (var i = 0; i < 3; i++) {
        var n = rangeRandom(0, 255).toString(16)
        // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ...
        // 0 1 2 3 4 5 6 7 8 9 a  b  c  d  e  f  10
        // toString 返回值是一个 字符串, 可以直接判断 length
        if (n.length === 1) {
          n = '0' + n
        }
        console.log(n)
        str += n
      }

      // 循环结束, str 就是拼接好的颜色
      return str
    }

    console.log(randomColor(true))

3. 定时器

/*
      定时器

      单线程
        + 代码从上到下的执行
        + 一行一行的执行, 同时只能做一个事情
        + 例子: 一个厕所, 只有一个坑

      同步异步
        + JS 是单线程同步代码机制
          => 当你写一个死循环的时候, 后面的代码就全都不执行了
        + WEBAPI 给我们提供了一个队列的机制
          => 用来模拟多线程
          => 准备了一个队列
          => 我们叫做单线程异步
        + 异步:
          => 不会立即执行的代码
          => 当代码从上到下的执行, 遇到异步代码的时候
          => 会把他放在队列里面, 先不执行
          => 等到所有同步代码执行完毕, 再从队列里面拿到代码来执行

      JS 的定时器
        + JS 提供了两个异步定时器机制
        1. setTimeout()
          => 语法: setTimeout(函数, 时间ms)
          => 时间到达的时候, 执行一遍函数就结束了
          => 延时定时器 / 炸弹定时器
        2. setInterval()
          => 语法: setInterval(函数, 时间ms)
          => 每间隔固定时间, 执行一遍函数
          => 间隔定时器
    */

    // 1. setTimeout()
    // setTimeout(function () {
    //   console.log('timeout')
    // }, 1000)

    // 2. setInterval()
    // setInterval(function () {
    //   console.log('interval')
    // }, 500)


    // 异步机制
    // console.log('start')

    // setTimeout(function () {
    //   console.log('timeout')
    // }, 0)

    // console.log('end')

    // while (true) {} // 同步代码, 他没有结束

4. 定时器的返回值

 <button id="btn">关闭定时器</button>

  <script>
    /*
      定时器的返回值
        + 有返回值的
          => 不分定时器种类
          => 只表示你时页面中的第几个定时器
          => 就是一个 number 数据类型
        + 返回值的作用
          => 用来关闭定时器使用的
        + 关闭定时器
          1. clearInterval()
            => 语法: clearInterval(要关闭的定时器返回值)
          2. clearTimeout()
            => 语法: clearTimeout(要关闭的定时器返回值)
          + 关闭定时器时不分种类的, 随便关
          + 只要你的 定时器返回值时对的就可以
    */

    var timer1 = setTimeout(function () { console.log('timeout') }, 1000)
    var timer2 = setInterval(function () { console.log('interval') }, 1000)

    console.log('timer1 ', timer1) // 1
    console.log('timer2 ', timer2) // 2

    // 点击 btn 的时候关闭定时器
    btn.onclick = function () {
      clearTimeout(timer2)
      clearInterval(timer1)
    }
  </script>

5. 广告弹出层

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    div {
      width: 100px;
      height: 100px;
      background-color: pink;
      position: fixed;
      bottom: 0;
      right: 0;
      border: 1px solid #333;

      display: none;
    }
  </style>
</head>
<body>

  <div id="box">
    <button id="btn">X</button>
  </div>

  <script src="./utils.js"></script>
  <script>
    /*
      广告弹出层

      学一个知识点: 给元素设置 css 样式
        + 元素.style.样式名 = 值

      分析:
        1. 打开页面的时候不出来
          => box 盒子默认时隐藏的
        2. 过一会显示出来
          => setTimeout()
          => 可以设置一个随机时间
        3. 关闭按钮被点击的时候
          => 让 box 消失
          => 消失以后, 过一会还会出来
    */

    // 2. 过一会显示出来
    setTimeout(function () {
      // 给 box 这个元素设置 display 为 block
      box.style.display = 'block'
    }, 1000 * rangeRandom(1, 3))

    // 3. 点击关闭按钮, 让盒子消失
    btn.onclick = function () {
      // 让 box 消失
      box.style.display = 'none'

      setTimeout(function () {
        // 给 box 这个元素设置 display 为 block
        box.style.display = 'block'
      }, 1000 * rangeRandom(1, 3))
    }

  </script>
</body>
</html>

6. 浏览器窗口尺寸

/*
      浏览器窗口尺寸
        + 指的是 浏览器 可视窗口的尺寸
        + 浏览器有可能会出现滚动条
          => 再一般浏览器滚动条时算浏览器的一部分的
          => 再 MAC 上, 是不算的
        + 两个属性
          1. innerWidth
          2. innerHeight
        + 共同点: 包含滚动条的尺寸
    */

    console.log(window.innerWidth)
    console.log(window.innerHeight)

    // 可以省略 window 不写
    console.log(innerWidth)
    console.log(innerHeight)

7. 浏览器的弹出层

/*
      浏览器的弹出层
        + 再 BOM 里面, 给我们提供了三个弹出层
        + 可以再浏览器弹出一些信息
          1. alert()  警告框
            -> 弹出一段提示文本
            -> 只有一个确定按钮
          2. confirm()  选择框
            -> 弹出一段提示文本
            -> 有确定和取消两个按钮
          3. prompt()  输入框
            -> 弹出一个提示文本
            -> 有一个 input 输入框
            -> 有确定和取消按钮

      语法:
        1. alert()
          语法: window.alert('提示文本')
          返回值: undefined
        2. confirm()
          语法: window.confirm('提示文本')
          返回值: 布尔值
            -> 当用户点击确定的时候, 是 true
            -> 当用户点击取消的hi收, 是 false
        3. prompt()
          语法: window.prompt('提示文本')
          返回值:
            -> 如果用户点击确定, 那么就是文本框里面的内容
            -> 如果用户点击取消, 那么就是 null

      共同点:
        + 会阻断程序的继续执行
          => 因为 JS 单线程
          => 弹出层弹出以后, 如果用户没有点击按钮表示当前弹出层没有结束
        + 直到用户操作以后, 才会继续向下执行代码
    */


    // 1. alert()
    // var res = window.alert('我是一段提示文本')
    // console.log(res)

    //confirm()
     //var res = window.confirm('请选择')
    // console.log(res)

    // 3. prompt()
     var res = window.prompt('请输入一段文本')
    console.log(res)



    console.log('后续代码')

8. 浏览器的地址栏

 /*
      浏览器的地址栏(重点)
        + 一个地址包含哪些内容(了解)
          => http://www.guoxiang.com?a=100&b=200#abc
          => http 传输协议
          => www.guoxiang.com   域名
          => ?a=100&b=200    查询字符串(queryString)
          => #abc  哈希(hash)
        + 地址里面包含的内容的作用(了解)
          => 传输协议: 前后端交互的方式
          => 域名: 找到一台服务器电脑
          => 查询字符串:
            -> 不影响你打开页面
            -> 打开这个页面的时候携带的信息
          => 哈希: 锚点定位
        + 再 window 下有一个成员叫做 location
          => location 是一个对象, 里面存储着和网页地址所有内容相关的信息
          => hash: 当前页面的 hash 值
          => href: 是一个读写的属性(当前地址栏地址)
            -> 读: 获取当前打开的页面的地址(中文是 url 编码格式)
            -> 写: 设置当前打开的页面的地址(跳转页面)
          => search: 当前地址中的 查询字符串(queryString)
            -> 读: 查询到的是一个字符串
            -> 这个是其他页面跳转到当前页面的时候带来的信息
            -> 我们为了使用, 需要把他解析出来
        + location 里面 还有一个方法
          => reload()
          => 重新加载当前页面
          => 就相当于按下了浏览器左上角的刷新按钮
          => 注意: **不能写在打开页面就能执行的地方**
    */

    // 1. href
    // 读取
    // console.log(window.location.href)
    // 设置
    // btn.onclick = function () {
    //   window.location.href = 'https://www.baidu.com'
    // }

    // 2. search
    // 读取: 读取到当前地址的 查询字符串
    // console.log(window.location)

    // 3. reload()
    // window.location.reload()
    r.onclick = function () {
      window.location.reload()
    }

    /*
      解析查询字符串
        + 两种情况
          1. ''
          2. '?key=value&key=value'

      步骤:
        1. 准备一个函数接收一个参数
          => 参数: 要解析的查询字符串
        2. 开始解析
          2-1. 判断如果是空字符串, 直接返回 空对象
            -> 如果不是空字符串, 要把字符串解析, 放在对象里面返回
            -> 再最开始定义一个对象
            -> 判断如果 str 有, 就向对象里面添加内容
            -> 返回创建好的对象
          2-2. 截取一部分字符串
            -> ? 表示 queryString 的开始, 只要 ? 后面的不分
            -> slice(1)
            -> 使用 & 切割开
          2-3. 循环这个切割好的数组
            -> 拿到里面的每一项
            -> 把每一项再次切割, 使用 = 切割
            -> 切割好以后 [0] 就是对象的 key
            -> [1] 就是对象的 value
    */
    // var str = '?a=100&b=200'
    // // var str = ''

    // function parseQueryString(str) {
    //   var obj = {}

    //   if (str) {
    //     var tmp = str.slice(1).split('&')
    //     tmp.forEach(function (item) {
    //       var t = item.split('=')
    //       obj[t[0]] = t[1]
    //     })
    //   }

    //   return obj
    // }

    // var res = parseQueryString(str)
    // console.log(res)

9. 浏览器的历史记录

/*
      浏览器的历史记录
        + 操作浏览器前进后退
        + window 下有一个叫做 history 的成员
          => 是一个对象
          => 里面包含了一些操作历史记录的属性和方法

      1. back()
        => 语法: window.history.back()
        => 作用: 回退到上一条历史记录, 相当于 ←
        => 前提: 你需要有历史记录, 不然没得回退

      2. forward()
        => 语法: window.history.forward()
        => 作用: 前进到下一条历史记录, 相当于 →
        => 前提: 你需要会退过以后, 才可以操作

      3. go()
        => 语法: window.history.go(整数)
          -> 正整数: 表示前进
          -> 0: 表示刷新当前页面
          -> 负整数: 表示后退
    */

    console.log(window.history)

10.浏览器的版本信息

/*
      浏览器的版本信息(了解)
        + 用来区分浏览器
        + 再 window 下有一个成员叫做 navigator
          => navigator 是一个对象, 里面存储着浏览器的版本信息

      1. userAgent
        => 表示浏览器的版本及型号信息

      2. appName
        => 所有浏览器都是统一的名字 netscape
        => IE 低版本浏览器
        => IE 高版本也是 netscape

      3. platform
        => 表示浏览器所在的操作系统
    */

    // 1. userAgent
    // console.log(window.navigator.userAgent)

    // 2. appName
    // console.log(window.navigator.appName)

    // 3. platform
    // console.log(window.navigator.platform)

11.浏览器的常见事件

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <script>
    // 放在这里的时候, 是不可以操作 DOM 元素
    // btn.onclick = function () {
    //   console.log('点击')
    // }

    // 等到页面所有资源加载完毕
    // DOM 也是资源的一部分
    // window.onload = function () {
    //   btn.onclick = function () {
    //     console.log('点击')
    //   }
    // }
  </script>

  <style>
    body {
      width: 2000px;
      height: 2000px;
    }
  </style>
</head>
<body>
<!--
  <img src="https://dss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=1906469856,4113625838&fm=26&gp=0.jpg" alt="">
  <img src="https://dss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=3892521478,1695688217&fm=26&gp=0.jpg" alt="">
  <img src="https://dss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1091405991,859863778&fm=26&gp=0.jpg" alt=""> -->

  <button id="btn">按钮</button>
  <script>
    /*
      浏览器的常见事件
        + 由浏览器行为触发的事件

      1. window.onload = function () {}
        => 页面所有资源加载完毕后执行
        => 所有资源: 图片, 视频, 音频, ...
        => 作用: JS 前置
          -> 当你需要把 JS 代码写在 head 标签里面的时候
          -> 最好加上一个 window.onload

      2. window.onscroll = function () {}
        => 浏览器滚动条滚动的时候触发
        => 不管横向还是纵向, 只要滚动就触发
        => 作用:
          1. 楼层导航
          2. 顶部通栏和回到顶部按钮的显示
          3. 渐近显示页面
          4. 瀑布流

      3. window.onresize = function () {}
        => 浏览器可视窗口改变的时候触发
        => 只要改变就会触发
        => 一般结合 innerWidth 和 innerHeight 来判断屏幕尺寸
          -> 移动端: 横屏
          -> 响应式布局: 判断窗口大小
    */

    // 1. onload
    // window.onload = function () {
    //   console.log('资源加载完毕')
    // }


    // 2. onscroll
    // window.onscroll = function () {
    //   console.log('滚动条再滚动')
    // }

    // 3. onresize
    window.onresize = function () {
      console.log('浏览器可视窗口改变大小了')
    }


  </script>
</body>
</html>

12.浏览器卷去的高度和宽度

/*
      浏览器卷去的高度和宽度
        + 当页面比窗口宽或者高的时候
        + 会有一部分是随着滚动被隐藏的
        + 我们管 上面隐藏的叫做 卷去的高度
        + 我们管 左边隐藏的叫做 卷去的宽度

      获取卷去的高度:
            文档        html
        1. document.documentElement.scrollTop
          => 使用必须要由 DOCTYPE 标签
        2. document.body.scrollTop
          => 使用必须要没有 DOCTYPE 标签
        3. 兼容写法
          => var scrollTop = document.documentElement.scrollTop || documentElement.body.scrollTop
          => || 当作短路表达式使用的
            -> 当前面为 true 的时候, 那么就直接返回前面的值
            -> 当前面为 false 的时候, 那么就返回后面的值, 不管后面是不是 false

      获取卷去的宽度:
        1. document.documentElement.scrollLeft
          => 使用必须要有 DOCTYPE 标签
        2. document.body.scrollLeft
          => 使用必须没有 DOCTYPE 标签
        3. 兼容的写法
          => var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft

    */

    // 1. scrollTop
    window.onscroll = function () {
      // console.log('html', document.documentElement.scrollTop)
      // console.log('body', document.body.scrollTop)
      // var scrollTop = document.documentElement.scrollTop || document.body.scrollTop
      // console.log(scrollTop)
    }

    // 2. scrollLeft
    window.onscroll = function () {
      // console.log('有 ', document.documentElement.scrollLeft)
      // console.log('没有 ', document.body.scrollLeft)
      var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft
      console.log(scrollLeft)
    }

13.浏览器卷去的高度和宽度

/*
      短路表达式
        1. ||
        2. &&

      1. ||
        + 作用: 可以用 || 运算符分隔两个表达式
        + 如果前面的表达式结果为 true
          => 那么后面的就不执行了
          => 只有前面为 false 的时候, 才会执行后面的表达式
        + 当你使用 || 短路表达式赋值的时候
          => 前面表达式时 true, 那么就得到前面表达式的结果
          => 前面表达式是 false, 那么就得到后面表达式的结果

      2. &&
        + 作用: 可以使用 && 运算符分隔两个表达式
        + 如果前面是 true, 那么后面的才会执行
          => 如果前面的是 false, 那么后面的就不执行了
        + 当你使用 && 短路表达式赋值的时候
          => 前面表达式是 true, 那么直接运算后面表达式的结果赋值
          => 前面表达式时 false, 那么直接把前面的结果返回

    */

    // 1. ||
    // false || alert('你好')

    // 因为 1 + 1 是 true, 所以 n 得到的就是 1 + 1 的结果
    // 后面的 10 + 10 不再执行了
    // var n = 1 + 1 || 10 + 10

    // 因为 1 - 1 是 false, 所以就会执行 10 + 10
    // 不管 10 + 10 是不是 true, 得到的都是 10 + 10 的结果
    // var n = 1 - 1 || ''

    // console.log(n)

    // 1 - 1 || 10 + 10 表达式的结果是 20
    // 当 20 再 if 条件里面的时候就是 true
    // if (1 - 1 || 10 + 10) {}

    // 1 - 1 || 10 - 10 表达式的结果是 0
    // 当 0 再 if 条件里面的时候就是 false
    // if (1 - 1 || 10 - 10) {}


    // 2. &&
    // false && alert('你好')

    // 因为 1 + 1 时 true, 所以一定会执行 后面的表达式
    // 不管后面的表达式结果是什么, 都会把结果赋值给 n
    // var n = 1 + 1 && 10 - 10

    // 因为 1 - 1 是 false, 所以后面的表达式不再执行了
    // 直接把 1 - 1 的结果赋值给 n
    // var n = 1 - 1 && 10 + 10
    // console.log(n)

14.浏览器滚动到

 /*
      浏览器滚动到
        + 通过 JS 代码指定 浏览器滚动到什么位置

      1. scrollTo()
        语法:
          1. window.scrollTo(横向坐标, 纵向坐标)
            => 书写不需要单位, 给一个数字就可以了
            => 如果你传递数组, 必须两个参数, 一个参数报错
            => 特点: 瞬间定位
          2. window.scrollTo({
              top: 纵向坐标,
              left: 横向坐标,
            })
            => 对象里面写几个值无所谓
            => 特点: 可以依靠第三个配置项来决定是瞬间定位还是平滑滚动
              -> behavior: 'smooth', 'instant'
              -> 不能决定滚动时间

      如果你想自己操作滚动时间
        + 需要自己来完成
    */

    btn.onclick = function () {
      // 让浏览器滚动到 300 500 的位置
      // window.scrollTo(300)

      // 语法2:
      window.scrollTo({
        top: 0,
        left: 100,
        // 决定定位方式
        behavior: 'smooth'
      })
    }

15.自己完成浏览器回到顶部

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    body {
      height: 3000px;
    }

    button {
      position: fixed;
      bottom: 50px;
      right: 50px;
    }
  </style>
</head>
<body>

  <button id="btn">定位滚动条位置</button>

  <script>
    /*
      自己完成浏览器回到顶部
        1. document.documentElement.scrollLeft
           document.documentElement.scrollTop
           是读写的属性
          可以获取可以设置
          设置: 直接赋值就可以了
        2. 定时器
          => 作用: 每间隔一段时间执行一次代码
          => 如果: 我每间隔 30ms, 让当前浏览器卷去的高度 - 20
        3. 滚动以后, 就停不下来了
          => 因为你点击的时候, 开启了定时器
          => 这个定时器就一直存在
          => 解决问题
            -> 直接再定时器里面判断
            -> 当 卷去的高度 <= 0 的时候, 停止定时器
        4. 假设你的滚动速度比较慢
          => 再没有滚动到指定位置的时候
          => 没有办法中断
          => 回到顶部, 是数字越来越小
            -> 一旦下一次滚动比上一次滚动数字要大
            -> 说明反方向再移动
            -> 就要停下来
          => 浏览器滚动事件的时候做这个事情
            -> 记录上一次的位置
    */
    var timer = 0
    btn.onclick = function () {
      // 设置一个定时器, 来让滚动条向上滚动
      timer = setInterval(function () {
        document.documentElement.scrollTop -= 30

        // 停止滚动到目标位置以后停止定时器
        if (document.documentElement.scrollTop <= 0) {
          clearInterval(timer)
        }
      }, 50)
    }

    // 再外面记录上一次的位置
    var st = 0

    // 滚动过程中, 你改变滚动方向, 停下来
    window.onscroll = function () {
      // 再你给 st 赋值之前, st 的值是上一次的值
      // 进行比较
      if (document.documentElement.scrollTop >= st) {
        // 停止定时器
        clearInterval(timer)
      }

      // 把当前位置赋值给 st
      // 随着滚动记录每一次滚动的位置
      st = document.documentElement.scrollTop
      console.log(st)
    }
  </script>
</body>
</html>

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

EOPG

你的鼓励是我创造的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值