Javascript api学习 part-4

eve2333 发布于 2024-10-25 106 次阅读


其他事件

页面加载事件

外部资源(如图片、外联CSS和JavaScript等)加载完毕时触发的事件
原因:有些时候需要等页面资源全部处理完了做一些事情,老代码喜欢把 script 写在 head 中,这时候直接找 dom 元素找不到。
事件名: load
监听页面所有资源加载完毕:给 window 添加 load 事件

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

                        当初始的HTML文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,而无需等待样式表、图像等完全加载
事件名: DOMContentLoaded
监听页面DOM加载完毕:给 document 添加 DOMContentLoaded 事件

页面滚动事件

滚动条在滚动的时候持续触发的事件。很多网页需要检测用户把页面滚动到某个区域后做一些处理, 比如固定导航栏,比如返回顶部。
事件名:scroll
监听整个页面滚动:window.addEventListenter.('scroll',function(){console.log('man!')})

scroll不会冒泡,要想给单独标签加上滚动条可以直接写在这个标签上

scrollLeft 和 scrollTop (属性)
获取被卷去的大小,获取元素内容往左、往上滚出去看不到的距离,这两个值是可读写的, 

<script>
    const div = document.querySelector('div')
    // 页面滚动事件
    window.addEventListener('scroll', function () {
      // 获取html元素写法  
      // document.documentElement  
      const n = document.documentElement.scrollTop
      if (n >= 100) {
        div.style.display = 'block'
      } else {
        div.style.display = 'none'
      }
    })
  </script>

返回顶部

    <script>
        // 点击返回页面顶部
        const backTop = document.querySelector('#backTop')
        backTop.addEventListener('click', function () {
            // 可读写
            // document.documentElement.scrollTop = 0
            window.scrollTo(0, 0)
        })
    </script>

小兔鲜显示导航和返回顶部案例

将融合在综合案例中来写

页面尺寸事件

window.addEventListener('resize',function(){console.log(manbaout)})

检测屏幕宽度 

这里其实有一个源码

元素尺寸与位置

就是通过js的方式,得到 元素在页面中的位置
●  获取宽高: offsetWidth和offsetHeight (内容 + padding + border)
获取元素的自身宽高、包含元素自身设置的宽高、padding、border。            获取的是数值,方便计算。 
注意: 获取的是可视宽高, 如果盒子是隐藏的,获取的结果是0
●  获取位置:
1.offsetLeft和offsetTop
获取元素距离自己 定位父级元素 的左、上距离, 如果都没有则以 文档左上角 为准。
注意:offsetLeft和offsetTop 是只读属性 ​

 仿京东效果导航栏案例

<!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;
        }

        .content {
            overflow: hidden;
            width: 1000px;
            height: 3000px;
            background-color: pink;
            margin: 0 auto;
        }

        .backtop {
            display: none;
            width: 50px;
            left: 50%;
            margin: 0 0 0 505px;
            position: fixed;
            bottom: 60px;
            z-index: 100;
        }

        .backtop a {
            height: 50px;
            width: 50px;
            background: url(./images/bg2.png) 0 -600px no-repeat;
            opacity: 0.35;
            overflow: hidden;
            display: block;
            text-indent: -999em;
            cursor: pointer;
        }

        .header {
            position: fixed;
            top: -80px;
            left: 0;
            width: 100%;
            height: 80px;
            background-color: purple;
            text-align: center;
            color: #fff;
            line-height: 80px;
            font-size: 30px;
            transition: all .3s;
        }

        .sk {
            width: 300px;
            height: 300px;
            background-color: skyblue;
            margin-top: 600px;
        }
    </style>
</head>

<body>
    <div class="header">我是顶部导航栏</div>
    <div class="content">
        <div class="sk">秒杀模块</div>
    </div>
    <div class="backtop">
        <img src="./images/close2.png" alt="">
        <a href="javascript:;"></a>
    </div>


    <script>
        // 获取 header
        let header = document.querySelector('.header');
        // 获取sk
        let sk = document.querySelector('.sk');
        // 当窗口滚动距离 大于或者等于 sk距离父亲的距离 的时候 让header显示
        window.addEventListener('scroll', function () {
            // 网页距离 : document.documentElement
            // scrollTop : 是元素内容滚动的距离
            // offsetTop : 是距离自己定位离父元素的距离
            if (document.documentElement.scrollTop >= sk.offsetTop) {
                //让顶部元素显示
                header.style.top = 0;
            } else {
                // 让顶部元素隐藏
                header.style.top = '-80px';
            }
        });
    </script>
</body>

</html>

哔哩哔哩小红色滑块

缺少代码,但是有核心思想

通过视口来获得元素位置

<style>
body{
height: 2000px;
}
div {
width:200px; height: 200px; background-color:
pink; margin: 100px;
}
</style> 
</head> 
<body>
<div></div> 
<script>
const div = document.querySelector('div') 
console.log(div.getBoundingClientRect()) 
</script>
</body> 

不用锚点链接做小兔鲜电梯导航

  <script>
    // 第一大模块,页面滑动可以显示和隐藏
    (function () {
      // 获取元素
      const entry = document.querySelector('.xtx_entry')
      const elevator = document.querySelector('.xtx-elevator')
      // 1. 当页面滚动大于 300像素,就显示 电梯导航
      // 2. 给页面添加滚动事件
      window.addEventListener('scroll', function () {
        // 被卷去的头部大于 300 
        const n = document.documentElement.scrollTop
        elevator.style.opacity = n >= entry.offsetTop ? 1 : 0
      })
 
      // 点击返回页面顶部
      const backTop = document.querySelector('#backTop')
      backTop.addEventListener('click', function () {
        // 可读写
        // document.documentElement.scrollTop = 0
        window.scrollTo(0, 0)
      })
    })();
 
    // 第二第三都放到另外一个执行函数里面
    (function () {
      // 2. 点击页面可以滑动 
      const list = document.querySelector('.xtx-elevator-list')
      list.addEventListener('click', function (e) {
        // console.log(11)
        if (e.target.tagName === 'A' && e.target.dataset.name) {
          // 排他思想  
          // 先移除原来的类active 
          // 先获取这个active的对象
          const old = document.querySelector('.xtx-elevator-list .active')
          // console.log(old)
          // 判断 如果原来有active类的对象,就移除类,如果开始就没有对象,就不删除,所以不报错
          if (old) old.classList.remove('active')
          // 当前元素添加 active 
          e.target.classList.add('active')
          // 获得自定义属性  new   topic 
          // console.log(e.target.dataset.name)
          // 根据小盒子的自定义属性值 去选择 对应的大盒子
          // console.log(document.querySelector(`.xtx_goods_${e.target.dataset.name}`).offsetTop)
          // 获得对应大盒子的 offsetTop
          const top = document.querySelector(`.xtx_goods_${e.target.dataset.name}`).offsetTop
          // 让页面滚动到对应的位置
          document.documentElement.scrollTop = top
 
        }
      })
 
      // 3. 页面滚动,可以根据大盒子选 小盒子 添加 active 类
      window.addEventListener('scroll', function () {
        //  3.1  先移除类 
        // 先获取这个active的对象
        const old = document.querySelector('.xtx-elevator-list .active')
        // console.log(old)
        // 判断 如果原来有active类的对象,就移除类,如果开始就没有对象,就不删除,所以不报错
        if (old) old.classList.remove('active')
        // 3.2 判断页面当前滑动的位置,选择小盒子
 
        // 获取4个大盒子
        const news = document.querySelector('.xtx_goods_new')
        const popular = document.querySelector('.xtx_goods_popular')
        const brand = document.querySelector('.xtx_goods_brand')
        const topic = document.querySelector('.xtx_goods_topic')
        const n = document.documentElement.scrollTop
        if (n >= news.offsetTop && n < popular.offsetTop) {
          // 选择第一个小盒子
          document.querySelector('[data-name=new]').classList.add('active')
        } else if (n >= popular.offsetTop && n < brand.offsetTop) {
          document.querySelector('[data-name=popular]').classList.add('active')
        } else if (n >= brand.offsetTop && n < topic.offsetTop) {
          document.querySelector('[data-name=brand]').classList.add('active')
        } else if (n >= topic.offsetTop) {
          document.querySelector('[data-name=topic]').classList.add('active')
        }
      })
    })();
  </script>

日期对象

实例化

const date=new Date()//得到当前时间
const date1=new Date('2022-5-1 08:30:00')//指定时间

目标:能够使用日期对象中的方法写出常见日期
使用场景:因为日期对象返回的数据我们不能直接使用,所以需要转换为实际开发中常用的格式
getFullYear()获得年份获取四位年份

getMonth()获得月份取值为0~11

getDate()获取月份中的每一天,不同月份取值也不相同

getDay()获取星期,取值为0~6

getHours()获取小时,取值为0~23

getMinutes()获取分钟,取值为0~59

getSeconds()获取秒,取值为0~59 

页面显示日期

<style>
div{width:300px;
height:40px;
border:1px solid pink;
text-align:center;
line-height:50px;
}
</style>
</head>
<body>
  <div></div>
  <script>
    const div = document.querySelector('div')
    function getMyDate() {
      const date = new Date()
      let h = date.getHours()
      let m = date.getMinutes()
      let s = date.getSeconds()
      h = h < 10 ? '0' + h : h
      m = m < 10 ? '0' + m : m
      s = s < 10 ? '0' + s : s
      return `今天是: ${date.getFullYear()}年${date.getMonth() + 1}月${date.getDate()}号 ${h}:${m}:${s}`
    }
 
    div.innerHTML = getMyDate()
    setInterval(function () {
      div.innerHTML = getMyDate()
    }, 1000)
  </script>
</body>

这是自定义格式,不想写可以用系统的。

<body>
<div></div> 
<script>
const div = document.querySelector('div') 
//得到日期对象
const date = new Date()
div.innerHTML = date.toLocaleString() // 2022/4/1 09:41:21 
setInterval(function () {
const date = new Date()
div.innerHTML = date.toLocaleString() // 2022/4/1 09:41:21 
},1000)

div.innerHTML = date.toLocaLeDateString() // 2022/4/1 
div.innerHTML = date.toLocaleTimeString() // 09:41:21 

</script>
</body> 

时间戳

实际开发中,经常和后端对接口的时候就经常用到这个时间戳

使用场景: 如果计算倒计时效果,前面方法无法直接计算,需要借助于时间戳完成
时间戳:是指1970年01月01日00时00分00秒起至现在的 毫秒数 ,是一种特殊的计量时间的方式
算法:
将来的时间戳 - 现在的时间戳 = 剩余时间毫秒数
剩余时间毫秒数 转换为 剩余时间的 年月日时分秒 就是 倒计时时间
比如:将来时间戳 2000ms - 现在时间戳 1000ms = 1000ms,1000ms 转换为就是 0小时0分1秒 ​

1. 使用 getTime() 方法
const date = new Date()
console.log(date.getTime())
2.简写 +new Date()

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

console.log(+new Date())
3. 使用 Date.now()

console.log(Date.now())     但是只能得到当前的时间戳, 而前面两种可以返回指定时间的时间戳

毕业倒计时效果

<!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" <!DOCTYPE html>


    <style>
        .countdown {
            width: 240px;
            height: 305px;
            text-align: center;
            line-height: 1;
            color:
                #fff;
            background-color:
                brown;
            /* background-size: 240px; */
            /* float: Left;*/
            overflow: hidden;
        }

        .countdown .next {
            font-size: 16px;
            margin: 25px 0 14px;
        }

        .countdown .title {
            font-size: 33px;
        }

        .countdown .tips {
            margin-top: 80px;
            font-size: 23px;
        }

        .countdown small {
            font-size: 17px;
        }

        .countdown .clock {
            width: 142px;
            margin: 18px auto 0;
            overflow: hidden;

        }

        .countdown .clock span,
        .countdown .clock i {
            display: block;
            text-align: center;
            line-height: 34px;
            font-size: 23px;
            float: left;
        }

        .countdown.clock span {
            width: 34px;
            height: 34px;
            border-radius: 2px;
            background-color: □#303430;
        }

        .countdown .clock i {
            width: 20px;
            font-style: normal;
        }
    </style>

<body>
    <div class="countdown">
        <p class="next">今天是2222年2月22日</p>
        <p class="title">下班倒计时</p>
        <p class="clock">
            <span id="hour">00</span>
            <i>:</i>
            <span id="minutes">25</span>
            <i>:</i>

            <span id="scond">20</span>
        </p>
        <p class="tips">18: 30: 00下课</p>
    </div>
      <script>
    // 函数封装 getCountTime
    function getCountTime() {
      // 1. 得到当前的时间戳
      const now = +new Date()
      // 2. 得到将来的时间戳
      const last = +new Date('2022-4-1 18:30:00')
      // console.log(now, last)
      // 3. 得到剩余的时间戳 count  记得转换为 秒数
      const count = (last - now) / 1000
      // console.log(count)
      // 4. 转换为时分秒
      // h = parseInt(总秒数 / 60 / 60 % 24)      // 计算小时
      // m = parseInt(总秒数 / 60 % 60)           // 计算分数
      // s = parseInt(总秒数 % 60)                // 计算当前秒数
      // let d = parseInt(count / 60 / 60 / 24)  // 计算当前天数
      let h = parseInt(count / 60 / 60 % 24)
      h = h < 10 ? '0' + h : h
      let m = parseInt(count / 60 % 60)
      m = m < 10 ? '0' + m : m
      let s = parseInt(count % 60)
      s = s < 10 ? '0' + s : s
      console.log(h, m, s)
 
      // 把时分秒写到对应的盒子里面
      document.querySelector('#hour').innerHTML = h
      document.querySelector('#minutes').innerHTML = m
      document.querySelector('#scond').innerHTML = s
    }
    // 先调用一次
    getCountTime()
 
    // 开启定时器
    setInterval(getCountTime, 1000)
  </script>
</body>

</html>

添加随机颜色

DOM节点操作

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

元素节点: 所有的标签 比如 body、 div,html 是根节点

属性节点:所有的属性 比如 href

文本节点:所有的文本

 查找父结点

 这是举了例子,XX.parentNode即可获得这个父对象

<body>
<div class="yeye">
<div class="dad">
<div class="baby">x</div>
</div>
</div>
<script>
const baby = document.querySelector('.baby')
console.log(baby)//返回dom
console.log(baby.parentNode)//返回dom对象
console.log(baby.parentNode.parentNode)//返回dom对象
</script>
</body>
<body>
<div class="box">
我是广告
<div class="box1">X</div>
</div>
<div class="box">
我是广告
<div class="box1">X</div>
</div>
<script>
const closeBtn = document.querySelectorAll('.box1')
for (let i = 0; i < closeBtn.length; i+) {
closeBtn[i].addEventlistener('click', function(){
this. parentNode. style.display = 'none'
})

</script>
</body>

子节点

childNodes 属性,获得所有子节点、包括文本节点(空格、换行)、注释节点等               children 属性(重点) 仅获得所有元素节点,返回的还是一个 伪数组, 例如:父元素.children

兄弟节点

1. 下一个兄弟节点: nextElementSibling 属性
2. 上一个兄弟节点: previousElementSibling 属性

增加节点

document.createElement('标签名')

追加节点

要想在界面看到,还得插入到某个父元素中
(1) 插入到父元素的最后一个子元素: 父元素.appendChild(要插入的元素)
(2)插入到父元素中某个子元素的前面:父元素.insertBefore(要插入的元素,在哪个元素前面)

你们错了,其实这种方式开发中很少用,都是用框架

最开始没有元素会得到一个空数组,空数组[0]返回undefined 然后你继续用insertBefore 也不会报错的,刚刚试过了,最开始没有也不会报错

学成在线案例渲染

缺少源码...?

克隆节点和删除节点

元素.cloneNode(布尔值)

特殊情况下我们新增节点按如下操作:        1.复制一个原有的节点  2.把复制的节点放到指定的元素内部
cloneNode会克隆出一个跟原标签一样的元素,括号内传入布尔值。

若为true,则克隆时会包含后代节点一起克隆。   若为false(默认),则克隆时不包含后代节点。

 深拷贝与浅拷贝

<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<script>
const ul = document.querySelector('ul')
//1克隆节点元素.cloneNode(true)
// const li1 = ul.children[0].cloneNode(true)
// console.log(li1)
//2,追加
ul.appendChild(ul.children[0].cloneNode(true))
</script>
</body>

在 JavaScript 原生 DOM 操作中,要删除元素必须通过 父元素删除。
语法: 父元素.removeChlid(子元素), 如不存在父子关系则删除不成功
删除节点和隐藏节点(display:none) 是有区别的:
隐藏节点还是存在的,但是删除,则从html中删除节点
显然的

Mobile端事件

目标:了解M端常见的事件
移动端也有自己独特的地方。比如触屏事件touch (也称触摸事件),Android和IOS都有。
• 触屏事件touch (也称触摸事件),Android和IOS都有。
• touch对象代表一个触摸点。触摸点可能是一根手指,也可能是一根触摸笔。触屏事件可响应用户手指(或触控笔)

对屏幕或者触控板操作。
•常见的触屏事件如下:
触屏touch事件 说明
touchstart " 手指到一个DOM元素时触发
touchmove 手指在一个DOM元素上滑动时触发
touchend 手指从一个DOM元素上移开时触发

学习轮播 插件的基本过程
1. 熟悉官网,了解这个插件可以完成什么需求   https://www.swiper.com.cn/
2. 看在线演示,找到符合自己需求的demo    https://www.swiper.com.cn/demo/index.html
3. 查看基本使用流程    https://www.swiper.com.cn/usage/index.html
4. 查看APi文档,去配置自己的插件    https://www.swiper.com.cn/api/index.html
注意:多个swiper同时使用的时候, 类名需要注意区分

下载好后,打开package..............

P123 ​