首页 前端知识 JS--DOM操作

JS--DOM操作

2024-07-10 22:07:10 前端知识 前端哥 186 502 我要收藏

js组成

JavaScript的组成

  • ECMAScript:

    • 规定了js基础语法核心知识。

    • 比如:变量、分支语句、循环语句、对象等等

  • Web APIs :

    • DOM 文档对象模型, 定义了一套操作HTML文档的API

    • BOM 浏览器对象模型,定义了一套操作浏览器窗口的API

 

什么是API

        API: 应用程序接口(Application Programming Interface)

        接口:无需关心内部如何实现,程序员只需要调用就可以很方便实现某些功能

        web APIs 作用: JavaScript 去操作页面文档和浏览器

DOM简介

        DOM(Document Object Model——文档对象模型)。

        作用:DOM用来 操作网页文档,开发网页特效和实现用户交互

        DOM的核心思想就是把网页内容当做对象来处理,通过对象的属性和方法对网页内容操作

document对象

        是 DOM 里提供的一个对象,是DOM顶级对象作为网页内容的入口,所以它提供的属性和方都是用来访问和操作网页内容的。例:document.write()

获取DOM对象

利用css选择器来获取DOM元素

描述属性/方法效果
获取DOM对象document.querySelector()获取指定的第一个元素
document.querySelectorAll()获取指定的所有元素
操作元素内容元素.innerText操作元素内容,不解析标签
元素.innerHTML操作元素内容,解析标签
操作元素样式元素.style.width通过style操作样式
元素.className通过类名操作样式
元素.classList.add()增加类名
元素.classList.remove()删除类名
元素.classList.toggle()切换类名
间隔函数setInterval(function() {}, 1000)定时器,每隔指定时间重复执行
语法实例描述
getElementByIddocument.getElementById('box')根据id获取元素,单个元素
getElementsByTagNamedocument.getElementsByTagName('li')根据标签名获取元素,伪数组
getElementsByClassNamedocument.getElementsByClassName('one')根据类名获取元素,伪数组
getElementsByNamedocument.getElementsByName('sex')根据name属性值获取元素,伪数组
// 1. getElementById   根据id获取
const box = document.getElementById('box')
console.log(box)

// 2. getElementsByClassName   根据类名获取  返回伪数组
const items = document.getElementsByClassName('item')
console.log(items)

// 3. getElementsByTagName  根据标签名获取 返回伪数组
const ps = document.getElementsByTagName('p')
console.log(ps)

// 4. getElementsByName  根据name属性获取 返回伪数组
const inputs = document.getElementsByName('username')
console.log(inputs)

参考文档:https://developer.mozilla.org/zh-CN/docs/Web/API/Document/querySelector

常用语法

//document.querySelector('css选择器'),选择指定css选择器的第一个元素

const box=document.querySelector('div')

 参数:包含一个或多个有效的CSS选择器 字符串

返回值: CSS选择器匹配的第一个元素对象 ,如果没有匹配到,则返回 null。

例如:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .box {
        background-color: pink;
      }
    </style>
  </head>
  <body>
    <!-- 
        dom是用来操作也能元素(标签)
        dom是将标签解析成dom对象--对象就有属性和方法--操作标签的
        dom顶级的对象是document对象
     -->
    <div class="box">我是盒子</div>
    <ul>
      <li>5646</li>
      <li>5646</li>
      <li>5</li>
    </ul>
    <ol>
      <li>1</li>
      <li>2</li>
      <li>3</li>
    </ol>
    <script>
      // 1.3 如果获取不到则返回 null
      const p = document.querySelector('p')
      console.log(p)  // null
      //通过css选择器获取元素,document.querySelector('css选择器')
      //获取单个元素,匹配到的第一个元素
      const box = document.querySelector(".box");
      console.log(box); //只能单独输出内容
      console.dir(box); //用来输出对象格式数据

      //案例
      const ul = document.querySelector("ul li:nth-child(3)");
      console.dir(ul);// 只选择满足条件的第3个元素li

      //获取多个元素 document.querySelectorALL('css选择器')
      //All 方法获取到的是一个伪数组,具备数组的长度和索引
      //获取的都是数组形式
      //所以可以通过循环遍历的方式拿到每一个,但是不能使用数组的方法例如push()
      const lis = document.querySelectorAll("ol li");
      console.log(lis);// 只选择满足条件的第一个元素li
      for (let i = 0; i < lis.length; i++) {
        console.log(lis[i]);
      }
    </script>
  </body>
</html>

选择指定css选择器的所有元素

语法:const lis = document.querySelectorAll('.nav li')

参数:包含一个或多个有效的CSS选择器 字符串

返回值:CSS选择器匹配的NodeList 伪数组

// 2. document.querySelectorAll() 选择指定css选择器的所有元素
// 2.1 参数还是字符串的css选择器
const lis = document.querySelectorAll('.nav li')

// 2.2 返回值是一个伪数组里面包含了所有的dom对象 li
console.log(lis)

// 2.3 伪数组
// (1) 有长度和索引号
// (2) 没有数组的一些常用方法 比如 push  pop  splice等方法
// lis.push(1)
// console.log(lis)  // 因为lis是伪数组无法使用push方法所以报错

// 2.4 利用循环遍历伪数组得到里面的每一个元素对象
for (let i = 0; i < lis.length; i++) {
  console.log(lis[i]) // 里面的每一个元素对象
}

// 2.5 即使只有1个元素,我们querySelectorAll 获得的也是一个伪数组,里面只有1个元素而已

const boxs = document.querySelectorAll('.box')
console.log(boxs)

操作元素内容

         DOM对象可以操作页面标签,所以本质上就是操作DOM对象(增删改查)

如果想要操作标签元素的内容,则可以使用如下2种方式:

  • 对象.innerText 属性
  • 对象.innerHTML 属性

innerText

        innerText 将文本内容添加/更新到任意标签位置,但是文本中包含的标签不会被解析。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div>sdfi</div>
    <script>
      //操作元素内容属性
      const box = document.querySelector("div");
      //1。innerText
      //获取内容  只会获取嵌套文本
      //查
      console.log(box.innerText);
      //修改内容
      box.innerText = "新值";
     // 1.3 增
      const box1 = document.querySelector('.box1')
      console.log(box1)
      box1.innerText='hdsfas'
      // 1.4 删  给空字符串可以删除内容
      box.innerText = ''
      box1.innerText = ''
      //不解析标签(不认识),原样输出
      box.innerText = "<b>加粗</b>";
    </script>
  </body>
</html>

innerHTML

        innerHTML 将文本内容添加/更新到任意标签位置,文本中包含的标签会被解析。

<script>
  // 2. 对象.innerHTML  会解析标签,获取嵌套里面的所有内容
  box.innerHTML = '<strong>hxm</strong>'
</script>

        总结:如果文本内容中包含 html 标签时推荐使用 innerHTML,否则建议使用 innerText 属性。

常用属性修改

        可以通过DOM操作元素属性,比如通过 src 更换 图片地址,最常见的属性比如:hreftitlesrc 等等

        1,直接能过属性名修改,最简洁的语法

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div>
      <img src="" alt="" />
    </div>
    <script>
      const arr = [
        "./images/1.png",
        "./images/2.png",
        "./images/3.png",
        "./images/4.png",
      ];
      //设置常用属性 对象.属性=值
      const img = document.querySelector("img");
      //获取属性值
      //查
      console.log(img.src);
      //设置属性值
      //生成一个随机数
      //改
      const ran = Math.floor(Math.random() * arr.length);
      img.src = arr[ran];
      //增
      img.title = "你好";
      //删
      img.src = "";
    </script>
  </body>
</html>

操作样式属性

        2,DOM对象修改标签元素的样式属性

  • 比如通过 轮播图小圆点自动更换颜色 样式
  • 点击按钮可以滚动图片,这是移动的的位置 translateX 等等

三种操作方式

1,通过 style 属性操作元素样式

语法:

<script>
  // 通过style操作元素样式
  // 1. 先要获取这个box元素对象
  const box = document.querySelector('.box')

  // 2. 通过style来从操作样式
  box.style.width = '300px'
  box.style.marginTop = '50px'
  box.style.backgroundColor = 'orange'

  // 3. 注意事项
  // 3.1 给样式赋值的时候,千万不要忘了加单位比如 300px
  // 3.2 如果有-的样式,我们采取的是小驼峰命名法比如 marginTop
  // 3.3 一定不要忘了加 style 属性
</script>

2,操作类名(className) 操作CSS

        如果修改的样式比较多,直接通过style属性修改比较繁琐,我们可以通过借助于css类名的形式。就是把多个样式放到css一个类中,然后把这个类添加到这个元素身上。

<script>
  // 通过类名操作元素样式
  // 1. 获取box盒子
  const box = document.querySelector('.box')
  // 2. 利用类名操作元素样式
  // box.className = 'hxm'
  box.className = 'box hxm'
  // 3. 利用类名操作样式添加的新的类名会覆盖掉原先的类名
</script>

注意:

1.由于class是关键字, 所以使用className去代替

2.className是使用新值换旧值, 如果需要添加一个类,需要保留之前的类

 3,通过 classList 操作类控制CSS

        为了解决className 容易覆盖以前的类名,我们可以通过classList方式追加和删除类名。

案例:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      /* .box {
        width: 200px;
        height: 200px;
        color: #8df;
        border: 1px solid red;
      } */
      .nav {
        width: 300px;
        height: 300px;
        background-color: #8df;
        color: red;
      }
      .box {
        font-size: 30px;
        text-align: center;
        line-height: 300px;
        border: 10px solid pink;
      }
    </style>
  </head>
  <body>
    <!-- <div>文字</div>
    <script>
      //通过类名操作元素样式
      //通过className属性的形式设置样式
      const box = document.querySelector("div");
      box.className = "box";
      //问题:用新值换旧值
      //场景:获取类名,但是用的不多
      console.log(box.className);
    </script> -->

    <div class="nav">文字描述</div>
    <script>
      //需求:利用classList追加 删除 切换类名
      const ds = document.querySelector("div");
      //1,追加类名  在原类名的基础上,追加新类名
      ds.classList.add("box");
      //2,删除类名
      ds.classList.remove("nav");
      //3,切换类名  有则删除,没有则添加
      ds.classList.toggle("nav");
      //判断是否存在某个类名,存在返回true,否则false
      console.log(ds.classList.contains("zcb"));
      console.log(ds.classList.contains("nav"));
    </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>轮播图点击切换</title>
    <style>
      * {
        box-sizing: border-box;
      }

      .slider {
        width: 560px;
        height: 400px;
        overflow: hidden;
      }

      .slider-wrapper {
        width: 100%;
        height: 320px;
      }

      .slider-wrapper img {
        width: 100%;
        height: 100%;
        display: block;
      }

      .slider-footer {
        height: 80px;
        background-color: rgb(100, 67, 68);
        padding: 12px 12px 0 12px;
        position: relative;
      }

      .slider-footer .toggle {
        position: absolute;
        right: 0;
        top: 12px;
        display: flex;
      }

      .slider-footer .toggle button {
        margin-right: 12px;
        width: 28px;
        height: 28px;
        appearance: none;
        border: none;
        background: rgba(255, 255, 255, 0.1);
        color: #fff;
        border-radius: 4px;
        cursor: pointer;
      }

      .slider-footer .toggle button:hover {
        background: rgba(255, 255, 255, 0.2);
      }

      .slider-footer p {
        margin: 0;
        color: #fff;
        font-size: 18px;
        margin-bottom: 10px;
      }

      .slider-indicator {
        margin: 0;
        padding: 0;
        list-style: none;
        display: flex;
        align-items: center;
      }

      .slider-indicator li {
        width: 8px;
        height: 8px;
        margin: 4px;
        border-radius: 50%;
        background: #fff;
        opacity: 0.4;
        cursor: pointer;
      }

      .slider-indicator li.active {
        width: 12px;
        height: 12px;
        opacity: 1;
      }
    </style>
  </head>

  <body>
    <div class="slider">
      <div class="slider-wrapper">
        <img src="./images/slider01.jpg" alt="" />
      </div>
      <!-- 颜色,文字内容 -->
      <div class="slider-footer">
        <p>对人类来说会不会太超前了?</p>
        <ul class="slider-indicator">
          <li class="active"></li>
          <li></li>
          <li></li>
          <li></li>
          <li></li>
          <li></li>
          <li></li>
          <li></li>
        </ul>
        <div class="toggle">
          <button class="prev">&lt;</button>
          <button class="next">&gt;</button>
        </div>
      </div>
    </div>
    <script>
      // 1. 初始数据
      const sliderData = [
        {
          url: "./images/slider01.jpg",
          title: "对人类来说会不会太超前了?",
          color: "rgb(100, 67, 68)",
        },
        {
          url: "./images/slider02.jpg",
          title: "开启剑与雪的黑暗传说!",
          color: "rgb(43, 35, 26)",
        },
        {
          url: "./images/slider03.jpg",
          title: "真正的jo厨出现了!",
          color: "rgb(36, 31, 33)",
        },
        {
          url: "./images/slider04.jpg",
          title: "李玉刚:让世界通过B站看到东方大国文化",
          color: "rgb(139, 98, 66)",
        },
        {
          url: "./images/slider05.jpg",
          title: "快来分享你的寒假日常吧~",
          color: "rgb(67, 90, 92)",
        },
        {
          url: "./images/slider06.jpg",
          title: "哔哩哔哩小年YEAH",
          color: "rgb(166, 131, 143)",
        },
        {
          url: "./images/slider07.jpg",
          title: "一站式解决你的电脑配置问题!!!",
          color: "rgb(53, 29, 25)",
        },
        {
          url: "./images/slider08.jpg",
          title: "谁不想和小猫咪贴贴呢!",
          color: "rgb(99, 72, 114)",
        },
      ];
      //生成随机数,为数组的索引
      const sum = Math.floor(Math.random() * sliderData.length);
      console.log(sum);
      //根据随机数获取数组对象
      console.log(sliderData[sum]);
      //根据这个对象修改页面图片,文字,背景颜色
      const img = document.querySelector(".slider-wrapper img");
      console.log(img);
      img.src = sliderData[sum].url;

      //改变文字
      //获取p标签
      const p = document.querySelector(".slider-footer p");
      console.log(p);
      //更换内容
      p.innerHTML = sliderData[sum].title;

      //颜色
      const footer = document.querySelector(".slider-footer");
      //操作样式 背景色可以用style
      footer.style.backgroundColor = sliderData[sum].color;
        //小圆点改变
      //移除以前的高亮效果
      const a = document.querySelector(".active");
      a.classList.remove("active");
      //给当前添加高亮效果
      const li = document.querySelector(
        `.slider-indicator li:nth-child(${sum + 1})`
      );
      li.classList.add("active");
    </script>
  </body>
</html>

操作表单元素属性

        表单很多情况,也需要修改属性,比如点击眼睛,可以看到密码,本质是把表单类型转换为文本框,正常的有属性有取值的跟其他的标签属性没有任何区别

获取: DOM对象.属性

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

表单属性中添加就有效果,移除就没有效果,一律使用布尔值表示,比如实现禁用按钮,勾选按钮等,如果为 true 代表添加了该属性,如果是 false 代表移除了该属性,比如: disabledcheckedselected。

语法:

<script>
  // 操作表单属性
  // 1. 操作表单 type 和 value 属性
  // 1.1 修改type属性
  const username = document.querySelector('[name=username]')
  console.log(username)
  // username.type = 'password'

  // 1.2 操作表单的 value 属性
  // console.log(username.value)  // 查
  // username.value = '用户名试试'  // 增
  // username.value = '请输入用户名' // 改
  // username.value = ''  // 删

  // 2. 禁用按钮或者是勾选复选框  布尔型
  // 2.1 禁用按钮  
  const button = document.querySelector('button')
  // button.disabled = true  // true 是禁用
  button.disabled = false  // false 是不禁用

  // 2.2 勾选复选框
  const agree = document.querySelector('[name=agree]')
  console.log(agree)
  // agree.checked = true // true 是选中复选框
  agree.checked = false // flase 是不选中复选框
</script>

案例:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <input type="text" value="" />
    <br />
    <input type="password" value="23" />
    <br />
    <input type="radio" />男
    <br />
    <button>按钮</button>
    <br />

    <select name="" id="">
      <option value="">海南</option>
      <option value="" selected>湖南</option>
    </select>
    <script>
      //value属性 收集用户输入的值
      const uname = document.querySelector('[type="text"]');
      //获取 对象.value
      //设置 对象的value属性 对象.value=值
      // uname.value = "xiaod";
      console.log(uname);
      //type属性,规定input的类型
      const pwd = document.querySelector('[type="password"]');
      console.log(pwd.type); //查看属性类型
      pwd.type = "text"; //更改属性类型

      //修改单选或复选按钮的选中 --checked
      const radio = document.querySelector('[type="radio"]');
      //获取
      console.log(radio.checked);
      //设置false表示不选中,true表示选中
      radio.checked = true;

      //禁止使用表单--按钮类 对象.disabled
      const btn = document.querySelector("button");
      //获取
      console.log(btn.disabled);
      //设置true表示禁用。false表示启用
      btn.disabled = true;

      //使用selected设置和获取选中项判断是否被选中,选中为true否则为false
      const option = document.querySelector("select option:last-child");
      console.log(option.selected);
    </script>
  </body>
</html>

自定义属性

        标准属性: 标签天生自带的属性 比如class、id、title等, 可以直接使用点语法操作比如:对象.title

        自定义属性:

  • 在html5中推出来了专门的data-自定义属性
  • 使用场景:通过自定义属性可以存储数据,后期可以使用这个数据
  • 在标签上一律以data-开头
  • 在DOM对象上一律以dataset对象方式获取

语法:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div data-index="0" data-id="oyyy"></div>
    <!-- 语法:在标签里 data-自定义属性=值 
    作用:保存某些数据,后续使用
    获取  对象.dataset  对象集合
    对象.属性名 能获取到属性值
    -->
    <script>
      const div = document.querySelector("div");
      console.log(div.dataset); //获取的数据{index:0,id:'oyyy'}
      console.log(div.dataset.id); //获取属性值
      console.log(div.dataset.index); //获取属性值
    </script>
  </body>
</html>

定时器-间隔函数

        网页中经常会需要一种功能:每隔一段时间需要自动执行一段代码,不需要我们手动去触发,例如:网页中的倒计时 ,定时器函数有两种: 间隔函数和 延迟函数

        setInterval 是 JavaScript 中内置的函数,它的作用是间隔固定的时间自动重复执行另一个函数,也叫定时器函数。

开启定时器:

语法:

<script>
  setInterval(function () {
    console.log('我是1秒钟执行一次')
  }, 1000)
</script>

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

注意:间隔时间单位是毫秒

关闭定时器

需要定时器变量名来关闭,返回的是一个唯一的数字

<script>
  let timer = setInterval(repeat, 1000)  // 注意调用的时候直接写函数名字不需要写小括号
  console.log(timer) //  1
  let timer1 = setInterval(repeat, 1000)  // 注意调用的时候直接写函数名字不需要写小括号
  console.log(timer1) //  2
  // 2. 关闭定时器
  clearInterval(timer)

</script>

案例:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <!-- setInterval(函数,间隔时间) 
    作用:每隔一段时间调用这个函数,间隔时间单位是毫秒,可以每隔指定时间自动重复执行某些代码
    -->
    <script>
      //   function setName() {
      //     console.log("xiao");
      //   }
      //   //setInterval(函数,间隔时间)
      //   setInterval(setName, 1000);

      //   //方法2
      //   setInterval(function () {
      //     console.log("xiao");
      //   }, 1000);

      //   //开启定时器
      //   //输出的每一个数为定时器的Id
      //   const timeId = setInterval(function () {
      //     console.log("xiao");
      //   }, 1000);
      //   console.log(timeId);

      //关闭定时器
      // let 变量名=setInterval(函数,间隔时间)
      // clearInterval(变量名)
      //一般不是开启就清除,有一个条件限制
      let num = 1;
      function setName() {
        num++;
        console.log("hi");
        //限制条件
        if (num === 4) clearInterval(timeId);
      }
      let timeId = setInterval(setName, 1000);
    </script>
  </body>
</html>

事件监听

        以前写的代码都是自动执行的,我们希望一段代码在某个特定的时机才去执行,比如

  • 点击按钮可以弹出警示框

  • 比如鼠标经过显示下拉菜单等等

  • 所以通过事件监听可以解决这个问题

事件

        事件是程序在运行的时候,发生的特定动作或者特定的事情,比如,点击按钮,鼠标经过等等。

事件监听

        事件发生后,想要执行的代码写到事件处理函数里面

  • 当触发指定的事件时,则事件处理函数就会被执行

  • 事件监听是将事件处理函数注册到元素对象身上

  • 事件监听也称为: 事件注册、事件绑定

语法: 元素对象.addEventListener('事件类型', 事件处理函数)

事件监听三要素

  • 事件源(谁被触发了)

  • 事件类型 (什么情况下触发,点击还是鼠标经过等)

  • 事件处理函数(要做什么事情)

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <button>按钮</button>
    <script>
      //点击按钮弹出警示框
      const but = document.querySelector("button");
      //   事件三要素=>事件源.addEventListener('事件类型',事件处理函数)
      but.addEventListener("click", function () {
        alert("点击后执行");
      });
    </script>
  </body>
</html>

注意:

1.事件类型要加引号,小写

2.函数是点击之后再去执行,每次点击都会执行一次 

回调函数

        回调函数:当一个函数当做参数来传递给另外一个函数的时候,这个函数就是回调函数(回头调用的函数)

        作用:完成某些特定任务

<script>
  // 1. 定时器间隔函数,里面第一个参数又是函数,这个匿名函数就是回调函数
  setInterval(function () {
    console.log('我是回调函数')
  }, 1000)

  // 2. addEventListener 函数的第二个参数也是函数,这个匿名函数也是回调函数
  btn.addEventListener('click', function () {
    console.log('我是回调函数')
  })
</script>

事件监听版本

        1,DOM0 事件,事件源.on事件类型 = function() { }

btn.onclick = function () {
  alert('我是弹窗1')
}

        2, DOM 2事件,事件源.addEventListener(事件类型,事件处理函数)

btn.addEventListener('click', function () {
  console.log('我是回调函数')
})

 区别:

        on 方式同名事件会被覆盖,addEventListener则不会,同时拥有事件更多特性,推荐使用

 事件类型

        将众多的事件类型分类可分为:鼠标事件、键盘事件、表单事件、焦点事件等,我们逐一展开学习。事件类型的大小写敏感的字符串,统一用小写字母

1,鼠标事件

        鼠标事件是指跟鼠标操作相关的事件,如单击、经过等。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      div {
        width: 300px;
        height: 300px;
        background-color: #8df;
        text-align: center;
        line-height: 300px;
        color: orange;
        font-size: 30px;
        margin: 100px auto;
      }
    </style>
  </head>
  <body>
    <div>九四</div>
    <script>
      //鼠标事件,
      const div = document.querySelector("div");
      //点击,表示点击后执行语句
      div.addEventListener("click", function () {
        alert("oyyy");
      });
      //鼠标经过/鼠标进入,表示点击后执行
      div.addEventListener("mouseenter", function () {
        alert("oy");
      });
      //鼠标离开,表示点击后执行
      div.addEventListener("mouseleave", function () {
        alert("hxm");
      });
    </script>
  </body>
</html>
焦点事件

        主要是针对于表单是否获得光标的事件, 获得焦点 focus 、失去焦点 blur。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <input type="text" class="one" />
    <br />
    <input type="text" class="two" />
    <script>
      //焦点===文本框,作用域
      const one = document.querySelector(".one");
      //获取元素,获得焦点
      //当文本域获取焦点后执行函数
      one.addEventListener("focus", function () {
        console.log("666");
      });

      one.addEventListener("blur", function () {
        console.log("999");
      });
      // 2. 拓展 自动获得焦点 focus()    自动失去焦点 blur()
      //默认让two盒子自动获取焦点
      const two = document.querySelector(".two");
      two.focus();
    </script>
  </body>
</html>
键盘事件和 input事件
事件触发时机得到表单值
keydown按下键盘时触发不带最后一次按键值 ab
keyup弹起键盘时触发输入内容 abc
input表单value发生变化时触发输入内容 abc
<!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>input事件和键盘事件</title>
  <style>
    textarea {
      width: 300px;
      height: 30px;
      padding: 10px;
      border-color: transparent;
      outline: none;
      resize: none;
      background: #f5f5f5;
      border-radius: 4px;
    }
  </style>
</head>

<body>
  <textarea id="tx" placeholder="发一条友善的评论" rows="2"></textarea>
  <script>
    // 获取元素
    const tx = document.querySelector('#tx')

    // 1. 键盘事件 
    // 1.1 键盘按下事件  keydown  当我们按下键盘的时候就触发
    tx.addEventListener('keydown', function () {
      console.log('我是keydown事件' + tx.value)
    })

    // 1.2 键盘弹起事件  keyup 当我们键盘弹起的时候就触发
    tx.addEventListener('keyup', function () {
      console.log('我是keyup事件' + tx.value)
    })

    // 2. 用户输入事件 input ,是表单value的值发生变化的时候触发
    tx.addEventListener('input', function () {
      console.log('我是input事件' + tx.value)
    })
    // 3. 注意事项
    // 3.1 执行顺序  keydown →  input   →  keyup
    // 3.2 keydown 获取值的时候得不到最后一次按键的值, keyup和input可以得到用户输入内容
  </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>小米搜索框显示隐藏案例</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }

      ul {
        list-style: none;
      }

      .mi {
        position: relative;
        width: 223px;
        margin: 100px auto;
      }

      .mi .search-text {
        width: 223px;
        height: 48px;
        padding: 0 10px;
        font-size: 14px;
        line-height: 48px;
        border: 1px solid #e0e0e0;
        outline: none;
      }

      /* 搜索框边框颜色 */
      .mi .search {
        border: 1px solid #ff6700;
      }

      /* 下拉菜单 */
      .result-list {
        display: none;
        position: absolute;
        left: 0;
        top: 48px;
        width: 223px;
        border: 1px solid #ff6700;
        border-top: 0;
        background: #fff;
      }

      .result-list a {
        display: block;
        padding: 6px 15px;
        font-size: 12px;
        color: #424242;
        text-decoration: none;
      }

      .result-list a:hover {
        background-color: #eee;
      }
    </style>
  </head>

  <body>
    <div class="mi">
      <input type="search" placeholder="小米笔记本" class="search-text" />
      <ul class="result-list">
        <li><a href="#">全部商品</a></li>
        <li><a href="#">小米11</a></li>
        <li><a href="#">小米10S</a></li>
        <li><a href="#">小米笔记本</a></li>
        <li><a href="#">小米手机</a></li>
        <li><a href="#">黑鲨4</a></li>
        <li><a href="#">空调</a></li>
      </ul>
    </div>
    <script>
      //需求:表单获取焦点显示下拉菜单并且改变边框样式(类名,search),当表单失去焦点
      //,隐藏下拉菜单,取消边框样式
      //1隐藏下拉菜单
      //2给菜单绑定获取焦点事件
      const search = document.querySelector(".search-text");
      const li = document.querySelector(".result-list");
      search.addEventListener("focus", function () {
        //表单有变框颜色
        //通过添加类
        search.classList.add("search");
        //下拉菜单显示
        li.style.display = "block";
      });

      //给表单绑定失去焦点事件
      search.addEventListener("blur", function () {
        //失去边框
        search.classList.remove("search");
        //隐藏下拉菜单
        li.style.display = "none";
      });
    </script>
  </body>
</html>

案例2:评论区按回车和点击回车发布

<!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>评论回车发布</title>
    <style>
      .wrapper {
        min-width: 400px;
        max-width: 800px;
        display: flex;
        justify-content: flex-end;
      }

      .avatar {
        overflow: hidden;
        width: 48px;
        height: 48px;
        margin-right: 20px;
        border-radius: 50%;
        background: url(./images/avatar.jpg) no-repeat center / cover;
      }

      .wrapper textarea {
        flex: 1;
        height: 30px;
        padding: 10px;
        border-color: transparent;
        outline: none;
        resize: none;
        background: #f5f5f5;
        border-radius: 4px;
        transition: all 0.5s;
      }

      .wrapper textarea:focus {
        height: 50px;
        border-color: #e4e4e4;
        background: #fff;
      }

      .wrapper button {
        width: 70px;
        margin-left: 10px;
        border: none;
        color: #fff;
        background: #00aeec;
        border-radius: 4px;
        cursor: pointer;
      }

      .wrapper .total {
        margin-right: 80px;
        margin-top: 5px;
        color: #999;
        opacity: 0;
        transition: all 0.5s;
      }

      .list {
        display: flex;
        min-width: 400px;
        max-width: 800px;
      }

      .list .item {
        display: flex;
        width: 100%;
      }

      .list .item .info {
        flex: 1;
        border-bottom: 1px dashed #e4e4e4;
        padding-bottom: 10px;
      }

      .list .item p {
        margin: 0;
      }

      .list .item .name {
        color: #fb7299;
        font-size: 14px;
        font-weight: bold;
      }

      .list .item .text {
        padding: 10px 0;
        color: #333;
        font-size: 13px;
      }

      .list .item .time {
        color: #999;
        font-size: 12px;
      }
    </style>
  </head>

  <body>
    <div class="wrapper">
      <i class="avatar"></i>
      <textarea
        id="tx"
        placeholder="发一条友善的评论"
        rows="2"
        maxlength="200"
      ></textarea>
      <button>发布</button>
    </div>
    <div class="wrapper">
      <span class="total">0/200字</span>
    </div>
    <div class="list">
      <div class="item" style="display: none">
        <i class="avatar"></i>
        <div class="info">
          <p class="name">清风徐来</p>
          <p class="text">
            大家都辛苦啦,感谢各位大大的努力,能圆满完成真是太好了[笑哭][支持]
          </p>
          <p class="time">2099-10-10 20:29:21</p>
        </div>
      </div>
    </div>
    <script>
      //获取元素
      const tx = document.querySelector("#tx");
      const total = document.querySelector(".total");
      //获取文本域元素
      const li = document.querySelector(".item");
      //获取text元素替换文字
      const text = document.querySelector(".text");
      //给元素注册事件,获取焦点事件
      tx.addEventListener("focus", function () {
        total.style.opacity = 1;
      });
      //失去焦点事件
      tx.addEventListener("blur", function () {
        total.style.opacity = 0;
      });
      //统计字数
      tx.addEventListener("input", function () {
        //改变字数的数据
        // console.log(tx.value);
        //trim()方法可以去除字符串两边的空格
        total.innerHTML = `${tx.value.trim().length}/200字`;
      });

      //回车发布评论,获取键盘事件
      tx.addEventListener("keyup", function (e) {
        // // console.log("6");
        // //当按下回车键时输出文本域内容
        // if (e.key === "Enter") {
        //   li.style.display = "flex";
        //   // tx.value获取用户输入的内容
        //   text.innerHTML = tx.value.trim();
        //   //清空文本域内容和计数消除
        //   tx.value = "";
        //   total.innerHTML = "0/200字";
        //   tx.blur(); //调用隐藏文字
        // }

        //方法2 调用click函数
        if (e.key === "Enter") {
          button.click();
        }
      });
      //点击按钮也可以发布
      const button = document.querySelector("button");
      button.addEventListener("click", function () {
        // console.log("6");
        //当按下回车键时输出文本域内容

        li.style.display = "flex";
        // tx.value获取用户输入的内容
        text.innerHTML = tx.value.trim();
        //清空文本域内容和计数消除
        tx.value = "";
        total.innerHTML = "0/200字";
        tx.blur(); //调用隐藏文字
      });
    </script>
  </body>
</html>

事件对象

        概念:事件对象也是个对象,这个对象里有事件触发时的相关信息,包含属性和方法,例如:鼠标点击事件中,事件对象就存了鼠标点在哪个位置等信息

        使用场景 :可以判断用户按下哪个键,比如按下回车键可以发布新闻,可以判断鼠标点击了哪个元素,从而做相应的操作

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <input type="text" />
    <script>
      const inp = document.querySelector("input");
      //key属性  键盘事件,事件对象携带的属性
      inp.addEventListener("keydown", function (e) {
        console.log(e.key); //获取当前按下的按键名称
        //e.key  判断按下了哪一个键
        if (e.key === "Enter") {
          console.log("666");
        }

        //e.targte  表示得到触发事件的元素
        console.log(e.targte);
      });
    </script>
  </body>
</html>

        事件回调函数的第一个参数即所谓的事件对象,通常习惯性的将这个对数命名为event,ev

环境对象

        作用:弄清楚this的指向,可以让我们代码更简洁 ,能够分析判断函数运行在不同环境中 this 所指代的对象。

  • 函数的调用方式不同,this 指代的对象也不同
  • 【谁调用, this 就是谁】 是判断 this 指向的粗略规则
  • 直接调用函数,其实相当于是 window.函数,所以 this 指代 window

        环境对象:指的是函数内部特殊的 this, 它指向一个对象,并且受当前环境影响

        

<body>
  <button>点击</button>
  <script>
    // 环境对象 this   粗略规则: 谁调用函数,this就指向谁

    // 1. 全局环境
    // console.log(this)  // this 指向 window 全局对象

    // 2. 普通函数和间歇函数
      setInterval(function(){
          console.log(this)
      },1000)
      
    function fn() {
      console.log(this)  // this 指向 window 全局对象
    }
    window.fn()

    // 3. 对象方法
    const obj = {
      uname: '佩奇',
      sing: function () {
        console.log(this)  // this 指向 obj对象
      }
    }
    obj.sing()

    // 4. 事件
    const btn1 = document.querySelector('button')
    btn1.addEventListener('click', function () {
      // console.log(this)  // this 指向 btn 这个对象
      // btn1.style.backgroundColor = 'pink'
      this.style.backgroundColor = 'pink'
    })
  </script>
</body>

排他思想

        是一种思路,目的是突出显示某个元素,比如,有多个元素,当鼠标经过时,只有当前元素会添加高亮样式,其余的元素移除样式。

目标:排除其它人,保留自己

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .active {
        background-color: #8df;
      }
    </style>
  </head>
  <body>
    <button class="active">1</button>
    <button>2</button>
    <button>3</button>
    <button>4</button>
    <button>5</button>
    <script>
      //要求,鼠标经过每一个小盒子,当前盒子亮度显示
      //先获取全部小盒子,给每一个盒子添加事件
      const bttu = document.querySelectorAll("button");
      //先打印
      for (let i = 0; i < bttu.length; i++) {
        // console.log(bttu[i]);
        bttu[i].addEventListener("click", function () {
          for (let j = 0; j < bttu.length; j++) {
            //先 清除所样式
            bttu[j].classList.remove("active");
          }
          //再给当前点击添加样式
          bttu[i].classList.add("active");
        });
      }
    </script>
  </body>
</html>

事件流

        事件流指的是事件完整执行过程中的流动路径 ,当触发事件时,会经历两个阶段,分别是捕获阶段冒泡阶段

事件捕获

        概念:当一个元素的事件被触发时,会从DOM的根元素开始依次调用同名事件 (从外到里)

        语法:元素.addEventListener('click', 回调函数, 是否使用捕获) 

 

<body>
  <div class="father">
    父盒子
    <div class="son">子盒子</div>
  </div>
  <script>
    // 事件流
    const father = document.querySelector('.father')
    const son = document.querySelector('.son')
    // 1. 事件捕获
    // // 点击父盒子
     father.addEventListener('click', function () {
       alert('我是爸爸')
     }, true)  // 事件捕获
     // 点击子盒子
     son.addEventListener('click', function () {
       alert('我是儿子')
     }, true) // 事件捕获
  </script>
</body>

注意:

  • addEventListener第三个参数传入 true 代表是捕获阶段触发(很少使用)

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

 事件冒泡

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

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

  • 事件冒泡是默认存在的,或者第三个参数传入 false 都是冒泡

  • 实际工作都是使用事件冒泡为主

<body>
  <div class="father">
    父盒子
    <div class="son">子盒子</div>
  </div>
  <script>
    // 事件流
    const father = document.querySelector('.father')
    const son = document.querySelector('.son')
    // 2. 事件冒泡
    // 点击父盒子
    father.addEventListener('click', function () {
      alert('我是爸爸')
    })
    // 点击子盒子
    son.addEventListener('click', function () {
      alert('我是儿子')
    }, false) 
  </script>
</body>

阻止冒泡

        问题:因为默认就有冒泡阶段的存在,所以容易导致事件影响到父级元素(祖先元素)

        需求:若想把事件就限制在当前元素内,就需要阻止事件冒泡

        前提: 阻止事件冒泡需要拿到事件对象

<body>
  <div class="father">
    父盒子
    <div class="son">子盒子</div>
  </div>
  <script>
    // 事件流
    const father = document.querySelector('.father')
    const son = document.querySelector('.son')
    // 1. 事件冒泡
    // 点击父盒子
    father.addEventListener('click', function () {
      alert('我是爸爸')
    })
    // 点击子盒子
    son.addEventListener('click', function (e) {
      alert('我是儿子')
      // 1.1 先获取事件对象
      // 1.2 事件对象.stopPropagation()  注意是个方法 
      e.stopPropagation()
    }) 
  </script>
</body>

结论:事件对象中的 ev.stopPropagation 方法,专门用来阻止事件冒泡(事件传播)

鼠标经过事件:

mouseover 和 mouseout 会有冒泡效果

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

 事件捕获和事件冒泡案例:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .father {
        position: relative;
        width: 400px;
        height: 400px;
        background-color: pink;
        margin: 100px auto;
        text-align: center;
      }
      .son {
        position: absolute;
        top: 100px;
        left: 100px;
        width: 200px;
        height: 200px;
        background-color: blue;
        text-align: center;
        line-height: 200px;
        /* margin: 80px auto; */
      }
    </style>
  </head>
  <body>
    <div class="father">
      父盒子
      <div class="son">子盒子</div>
    </div>
    <script>
      //事件流
      const father = document.querySelector(".father");
      const son = document.querySelector(".son");
      //默认是冒泡事件流
      father.addEventListener("click", function () {
        alert("666666");
      });
      son.addEventListener("click", function (e) {
        //事件对象.stopPropagation()   阻止事件冒泡和捕获方法
        e.stopPropagation();
        alert("666");
      });
    </script>
  </body>
</html>

事件委托

        事件委托(EventDelegation):是JavaScript中注册事件的常用技巧,也称为事件委派、事件代理,简单理解:原本需要注册在子元素的事件委托给父元素,让父元素担当事件监听的职务

        可以解决的问题

  • 如果同时给多个元素注册事件,不需要利用循环多次注册事件
  • 减少了大量的事件监听的性能

事件委托是利用事件流的特征解决一些开发需求的知识技巧

  • 优点:减少注册次数,可以提高程序性能

  • 原理:事件委托其实是利用事件冒泡的特点

    • 给父元素注册事件,当我们触发子元素的时候,会冒泡到父元素身上,从而触发父元素的事件

利用事件委托方式如何得到当前点击的元素呢?

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

案例:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <ul>
      <li>第1个li</li>
      <li>第2个li</li>
      <li>第3个li</li>
      <li>第4个li</li>
      <li>第5个li</li>
    </ul>
    <script>
      //事件委托
      //事件绑定给父级,父级触发事件
      const ul = document.querySelector("ul");
      ul.addEventListener("click", function (e) {
        // console.log("4");
        // this.style.color = "#8df";
        //通过事件对象,得到事件源e.target
        // console.log(e.target);
        //通过e.target.tagName得到事件源的标签名
        // console.log(e.target.tagName);
        if (e.target.tagName === "LI") {
          e.target.style.color = "#8df";
        }
      });
    </script>
  </body>
</html>

阻止默认行为

        阻止元素发生默认的行为,例如:当点击提交按钮时阻止对表单的提交,还有阻止链接的跳转等等

语法: 事件对象.preventDefault()

 

<body>
  <form action="">
    姓名: <input type="text" name="username">
    <button>提交</button>
  </form>
  <a href="http://www.baidu.com">点击跳转</a>
  <script>
    // 阻止默认行为
    const form = document.querySelector('form')
    const input = document.querySelector('[name=username]')
    form.addEventListener('submit', function (e) {
      // 如果input表单的值为空则不允许提交
      if (input.value === '') {
        // return 无法阻止提交事件
        e.preventDefault()  // 阻止提交事件
      }
    })

    document.querySelector('a').addEventListener('click', function (e) {
      e.preventDefault()
    })
  </script>
</body>

事件解绑

        移除事件处理函数,也称为解绑事件。

<body>
  <button class="l2">移除L2事件监听</button>
  <button class="l0">移除L0事件监听</button>
  <script>
    // 需求:按钮就点击一次,然后移除点击事件

    // 1. l2事件监听
    const l2 = document.querySelector('.l2')

    l2.addEventListener('click', fn)
    function fn() {
      alert('我点击了')
      // 移除事件监听
      l2.removeEventListener('click', fn)
    }

    // 2. l0事件监听
    const l0 = document.querySelector('.l0')
    l0.onclick = function () {
      alert('我点击了')
      // 移除事件监听
      l0.onclick = null
    }
  </script>
</body>

其他事件

页面加载事件

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

        为什么要学?

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

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

语法:事件名:load

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

window.addEventListener('load', function() {
    // xxxxx
})

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

语法:事件名:DOMContentLoaded

document.addEventListener('DOMContentLoaded', function() {
    // xxxxx
})

案例:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script>
      //页面加载事件,当所有的资源加载完毕后,触发这个事件
      // window.addEventListener('load',function(){
      //     const div=document.querySelector('div')
      //     div.innerHTML='hd'
      // })

      //HTML元素加载事件--DOMContentLoaded
      //只要HTML标签加载完成了。机会触发这个事件。它不会等待Css,JS,图片视频等执行完成再执行
      document.addEventListener("DOMContentLoaded", function () {
        const div = document.querySelector("div");
        div.innerHTML = "hd";
      });
    </script>
  </head>
  <body>
    <div>文本</div>
  </body>
</html>

 元素滚动事件

        滚动条在滚动的时候持续触发的事件,

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

语法:事件名:scroll

监听整个页面滚动:

window.addEventListener('scroll', function() {
    // xxxxx
})

//document.documentElement 获取html标签
const top=document.documentElement.scrollTop//表示页面滚去多少像素,可以获取滚动的距离

scrollTop / scrollLeft, 被卷去的头部或者左侧,可以读取,也可以修改(赋值)

案例:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      body {
        min-height: 3000px;
      }
      div {
        width: 300px;
        height: 100px;
        overflow: auto;
      }
    </style>
  </head>
  <body>
    <!-- <div>
      1
      <br />
      1
      <br />
      1
      <br />
      1
      <br />
      1
      <br />
      1
      <br />
      1
      <br />
      1
      <br />
      1
      <br />
      1
      <br />
    </div> -->
    <script>
      //页面滚动事件
      window.addEventListener("scroll", function () {
        console.log("666");
        //document.documentElement--获取html标签
        const top = document.documentElement.scrollTop;
        console.log(top);
      });
      //元素添加滚动事件
      const div = document.querySelector("div");
      div.addEventListener("scroll", function () {
        console.log(2);
      });
    </script>
  </body>
</html>

页面尺寸事件

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

window.addEventListener('resize', function() {
    // xxxxx
    //获取body的宽度
    console.log(document.body.clientWidth)
     console.log(document.body.clientHeight)
})

 clientWidth和clientHeight,获取元素的可见部分宽高(不包含border,margin,滚动条等)

案例:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      window.addEventListener("resize", function () {
        // console.log(2);
        //获取body的宽度
        console.log(document.body.clientWidth);
        //获取body的高度
        console.log(document.body.clientHeight);
      });
    </script>
  </body>
</html>

元素尺寸与位置

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

 

 日期对象

        日期对象:用来表示日期和时间的对象,

        作用:可以得到当前系统日期和时间

        Date是JavaScript内置对象,日期对象使用必须先实例化:创建一个日期对象并获取时间,在代码中发现了 new 关键字时,一般将这个操作称为实例化

实例化

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      //实例化日期 new Date()
      //获取当前日期
      const dateNow = new Date();
      document.write(dateNow);
      //获取指定日期
      const da = new Date("2024-4-8");
      document.write(da);
    </script>
  </body>
</html>

 格式化日期对象

方法作用说明
getFullYear()获得年份获取四位年份
getMonth()获得月份取值为 0 ~ 11
getDate()获取月份中的每一天不同月份取值也不相同
getDay()获取星期取值为 0 ~ 6
getHours()获取小时取值为 0 ~ 23
getMinutes()获取分钟取值为 0 ~ 59
getSeconds()获取秒取值为 0 ~ 59
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      //1,实例化日期对象
      const da = new Date();
      //2对日期对象进行格式化
      // 获取年份
      console.log(da.getFullYear());
      //获取月份
      console.log(da.getMonth() + 1); //因为月份从0开始记
      //获取日期
      console.log(da.getDate());
      //获取星期
      console.log(da.getDay());
      //获取小时
      console.log(da.getHours());
      //获取分钟
      console.log(da.getMinutes());
      //获取秒钟
      console.log(da.getSeconds());
    </script>
  </body>
</html>

格式化日期对象另外方法

 

方法作用说明
toLocaleString()返回该日期对象的字符串(包含日期和时间)2099/9/20 18:30:43
toLocaleDateString()返回日期对象日期部分的字符串2099/9/20
toLocaleTimeString()返回日期对象时间部分的字符串18:30:43
<body>
  <div class="box"></div>
  <script>

    const date = new Date()
    console.log(date.toLocaleString())  // 2023/1/27 23:19:20
    console.log(date.toLocaleDateString())  // 2023/1/27 
    console.log(date.toLocaleTimeString())  // 23:19:20

    // 1. 封装一个 getDateTime函数,里面格式化时间对象
    function getDateTime() {
      const date = new Date()

      return date.toLocaleString()
    }
    // 注意: 先写上这句话,防止盒子有1秒的空白期
    document.querySelector('.box').innerText = getDateTime()
    // 3. 显示到box盒子里面,并且添加定时器
    setInterval(function () {
      document.querySelector('.box').innerText = getDateTime()
    }, 1000)
  </script>
</body>

 案例:页面显示当前日期

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div>2024年4月6号 21:30:50</div>
    <script>
      const div = document.querySelector("div");
      //实例化日期
      function getDateTime() {
        const date = new Date();
        const year = date.getFullYear();
        const month = date.getMonth() + 1;
        const day = date.getDate();
        //格式化时间
        const hours =
          date.getHours() >= 10 ? date.getHours() : "0" + date.getHours();
        const minutes =
          date.getMinutes() >= 10 ? date.getMinutes() : "0" + date.getMinutes();
        const second =
          date.getSeconds() >= 10 ? date.getSeconds() : "0" + date.getSeconds();
        return `${year}年${month}月${day}日${hours}:${minutes}:${second}`;
      }
      const result = getDateTime();
      div.innerHTML = getDateTime();
      //   document.write(result);
      //定时执行函数
      setInterval(function () {
        div.innerHTML = getDateTime();
      }, 1000);
      //   console.log(result);
    </script>
  </body>
</html>

时间戳

        概念;是指1970年01月01日00时00分00秒起至现在的总毫秒数(数字型),它是一种特殊的计量时间的方式

        使用场景: 计算倒计时效果,需要借助于时间戳完成

        算法:

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

  • 剩余时间毫秒数转换为年月日时分秒就是倒计时时间

        获取时间戳的方法,分别为 getTime 和 Date.now 和 +new Date()

    // 1. 实例化
  const date = new Date()
  // 2. 获取时间戳
  console.log(date.getTime())
// 还有一种获取时间戳的方法
  console.log(+new Date())
  // 还有一种获取时间戳的方法
  console.log(Date.now())

DOM 节点

        DOM树:DOM 将 HTML文档以树状结构直观的表现出来,我们称之为 DOM 树 或者 节点树

        节点(Node)是DOM树(节点树)中的单个点。包括文档本身、元素、文本以及注释都属于是节点。

  • 元素节点(重点)

    • 所有的标签 比如 body、 div

    • html 是根节点

  • 属性节点

    • 所有的属性 比如 href

  • 文本节点

    • 所有的文本

查找节点

利用节点关系查找节点,返回的都是对象

  • 父节点

  • 子节点

  • 兄弟节点

有了查找节点可以使我们选择元素更加方便

父节点

语法:元素.parentNode

<!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>王者荣耀关闭登录案例</title>
    <style>
      .pop {
        display: block;
        visibility: visible;
        position: fixed;
        z-index: 9999;
        left: 50%;
        top: 50%;
        width: 530px;
        height: 254px;
        margin-top: -127px;
        margin-left: -265px;
        background: url(./images1/login.webp) no-repeat;
      }

      .close {
        position: absolute;
        right: 0;
        top: 0;
        width: 40px;
        height: 40px;
      }
    </style>
  </head>

  <body>
    <div class="pop">
      <a href="javascript:;" class="close"></a>
    </div>
    <script>
      const a = document.querySelector(".close");
      //   console.log(a.parentNode);
      const p = a.parentNode;
      a.addEventListener("click", function () {
        p.style.display = "none";
      });
    </script>
  </body>
</html>
子节点

语法:父元素.children

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <ul>
      <li>第1个li</li>
      <li>第2个li</li>
      <li>第3个li</li>
      <li>第4个li</li>
      <li>第5个li</li>
    </ul>
    <script>
      //获取子节点元素
      const ul = document.querySelector("ul");
      //   console.log(ul.children);
      //   console.log(ul.children[2]);
      //   console.log(ul.children[2].innerHTML);
      //获取兄弟节点
      const li3 = ul.children[2];
      console.log(li3.previousElementSibling.innerHTML);
      console.log(li3.nextElementSibling.innerHTML);
    </script>
  </body>
</html>
兄弟节点
<body>
  <ul>
    <li>我是第1个孩子</li>
    <li>我是第2个孩子</li>
    <li>我是第3个孩子</li>
    <li>我是第4个孩子</li>
  </ul>
  <script>
    // 2. 查询兄弟节点
    const li2 = document.querySelector('ul li:nth-child(2)')
    // console.log(li2)
    console.log(li2.previousElementSibling) // 上一个兄弟
    console.log(li2.nextElementSibling)  // 下一个兄弟
    console.log(ul.children[0]) // 第一个孩子
    console.log(ul.children[2]) // 第三个孩子
  </script>
</body>

增加节点

        

很多情况下,我们需要在页面中增加元素

  • 比如,点击发布按钮,可以新增一条信息

一般情况下,我们新增节点,按照如下操作:

  • 创建一个新的节点

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

  1. 父元素最后一个子节点之后,插入节点元素,element代表元素

element.append()

     2,父元素第一个子元素的之前,插入节点元素  

element.prepend()

 例如:

<body>
  <ul>
    <li>我是小li</li>
  </ul>
  <script>
    // 1. 创建节点
    const li = document.createElement('li')
    li.innerHTML = '我是放到后面的'
    console.log(li)

    // 2. 追加给父元素
    const ul = document.querySelector('ul')
    // 2.1 append 放到ul 的最后面 类似css的 after伪元素
    ul.append(li)
    // 2.2 prepend放到 ul 的最前面 类似css的 before伪元素
    const firstli = document.createElement('li')
    firstli.innerHTML = '我是放到前面的'
    ul.prepend(firstli)
  </script>
</body>

案例:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div></div>
    <script>
      //增加节点
      //1创建节点
      const span = document.createElement("span");
      span.innerHTML = "666";
      //追加节点
      //元素后面追加
      const div = document.querySelector("div");
      //   div.append(span);
      div.prepend(span);
    </script>
  </body>
</html>

删除节点

语法: element.remove()

  1. 把对象从它所属的 DOM 树中删除

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

<!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>删除节点</title>
  </head>

  <body>
    <div class="remove">我要删除</div>
    <div class="none">我要隐藏</div>
    <script>
      // 1. 删除节点, remove 会从dom树中删除这个元素
      const remove = document.querySelector('.remove')
      remove.remove()

      // 2. display:none 隐藏元素,页面看不见,但是dom树中还存在这个标签
      const none = document.querySelector('.none')
      none.style.display = 'none'
    </script>
  </body>

</html>

M端事件

        M端(移动端)有自己独特的地方。比如触屏事件 touch(也称触摸事件),Android 和 IOS都有。

        touch 对象代表一个触摸点。触摸点可能是一根手指,也可能是一根触摸笔。触屏事件可响应用户手指(或触控笔)对屏幕或者触控板操作。

        常见的触屏事件如下:

 

<body>
  <div class="box"></div>
  <script>
    // 触摸事件
    const box = document.querySelector('.box')
    // 1. 手指触屏开始事件 touchstart
    box.addEventListener('touchstart', function () {
      console.log('我开始摸了')
    })
    // 2. 手指触屏滑动事件 touchmove
    box.addEventListener('touchmove', function () {
      console.log('我一直摸')
    })

    // 3. 手指触屏结束事件  touchend
    box.addEventListener('touchend', function () {
      console.log('我摸完了')
    })
  </script>
</body>

 案例:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      div {
        width: 300px;
        height: 300px;
        background-color: pink;
      }
    </style>
  </head>
  <body>
    <div></div>
    <script>
      const div = document.querySelector("div");
      div.addEventListener("touchstart", function () {
        console.log("666");
      });
      div.addEventListener("touchmove", function () {
        console.log("6");
      });
      div.addEventListener("touchend", function () {
        console.log("666666");
      });
    </script>
  </body>
</html>

JS插件

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

学习插件的思路:

1.看官网。了解这个插件可以完成什么需求 Swiper中文网-轮播图幻灯片js插件,H5页面前端开发

2.查看基本使用流程 。 Swiper使用方法 - Swiper中文网

3.写个小demo。看在线演示,找到符合自己需求的demo Swiper演示 - Swiper中文网

4.应用的开发中。

AlloyFinger

        AlloyFinger 是腾讯 AlloyTeam 团队开源的超轻量级 Web 手势插件,为元素注册各种手势事件

        github地址:GitHub - AlloyTeam/AlloyFinger: Super tiny size multi-touch gestures library for the web.    You can touch this →Super tiny size multi-touch gestures library for the web.    You can touch this → - AlloyTeam/AlloyFingericon-default.png?t=N7T8https://github.com/AlloyTeam/AlloyFinger

使用步骤:

  1. 下载js库:http://alloyteam.github.io/AlloyFinger/alloy_finger.js

  2. 将AlloyFinger库引入当前文件:<scriptsrc="alloy_finger.js"></script>

或者使用在线地址:<script src="<https://unpkg.com/alloyfinger@0.1.16/alloy_finger.js>"></script>

     3,配置

new AlloyFinger(element, {  // element 是给哪个元素做滑动事件
  swipe: function (e) {
    // 滑动的时候要做的事情 e.direction 可以判断上下左右滑动 Left  Right 等
  }
})

转载请注明出处或者链接地址:https://www.qianduange.cn//article/13933.html
标签
评论
发布的文章

jQuery-w3school(2020

2024-08-04 23:08:08

jQuery常用方法总结

2024-08-04 23:08:34

Vue2使用echarts树图(tree)

2024-08-04 23:08:29

图表库-Echarts

2024-08-04 23:08:57

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!