[前端学习] Javascript 笔记 (三)

一、变量声明

变量声明有三个:var、let、constvar是旧写法,问题多,被淘汰,现在不常用。
letconst中,const优先。

  • const的语义化更好;
  • 很多变量在声明之后不会被更改;
  • 许多框架中使用const居多。
    在使用const声明数组和对象时,在地址没有发生改变的情况下可以修改里面的属性,若修改了地址则会报错,在需要修改地址的情况,需使用let声明。
  const arrA = [1, 2, 3];
  arrA.push(4);  // 地址不变,值变为[1, 2, 3, 4]
  console.log(arrA)   // 输出:[1, 2, 3, 4]

  const arrB = [1, 2, 3];
  arrB = [1, 2, 3, 4];  // 报错,常量不能被重新赋值(重新赋值会导致地址改变)

二、Web API —— DOM 对象

Web API的作用:使用JS去操作HTML和浏览器
分类:DOM(文档对象类型)、BOM(浏览器对象类型)

  1. 什么是 DOM 和 DOM 数
    DOM(Document Object Model —— 文档对象模型)是用来呈现以及与任意HTML或XML文档交互的API。也就是说是浏览器提供的一套专门用来操作网页内容的功能,开发网页内容特效和实现用户交互。
    DOM 树:将HTML文档以树状结构直观地表现出来,我们称之为文档树或 DOM 树。是描述网页关系内容的名词。DOM 树直观地体现了标签与标签之间的关系。
  2. DOM 对象
    DOM 对象:浏览器根据HTML标签生成的js对象
    • 所有的标签属性都可以在这个对象上面找到;
    • 修改这个对象的属性会自动映射到标签上
      DOM 的核心思想:把网页当作对象来处理。

    document对象:

    • 是DOM里提供的一个对象(最大的一个对象);
    • 它提供的属性和方法都是用来访问和操作网页内容的,如:document.write()
    • 网页所有的内容都在document里。
  3. 获取 DOM 对象
    1)根据CSS选择器来获取DOM元素(常用)
    • 选择一个
      • 语法:document.querySelector('css选择器')
      • 参数:包含一个或多个有效的css选择器字符串。
      • 返回值:css选择器匹配的第一个元素,一个HTMLElement对象,如果没有匹配到,则返回null,可以使用修改对象属性的方式修改获取到的HTMLElement对象。
    • 选择多个
      • 语法:document.querySelectorAll('css选择器')
      • 返回值:css选择器匹配的NodeList对象集合,是一个伪数组(有长度有索引号,但是没有pop()、push()等数组方法),操作时需要遍历或使用索引。
        2)其他获取DOM元素方式(了解)
    • document.getElementById('id名'):根据id获取一个元素
    • document.getElementByTagName('标签名'):根据标签获取一类元素
    • document.getElementByClassName('类名'):根据标签类名获取元素
  4. 操作元素内容
    DOM 对象都是根据标签生成的,所以操作标签本质就是操作 DOM 对象。console.dir(元素对象)可以打印对象,包括所有属性和方法。
    • 对象.innerText属性:对象.innerText = '新内容',将文本内容添加/更新到标签位置,显示纯文本,不解析标签。
    • 对象.innerHTML属性
      const box1 = document.querySelector('.box1');
      console.log(box1.innerText);  // 输出:文字内容,
      box1.innerText = '新文字内容'; // 页面显示文字:新文字内容
      box1.innerText = '<strong>新文字内容</strong>'; // 无法解析标签,页面显示文字: <strong>新文字内容</strong>
      console.log(box1.innerText);  // 输出:<strong>新文字内容</strong>
    
      const box2 = document.querySelector('.box2');
      console.log(box2.innerHTML);  // 输出:文字内容
      box2.innerHTML = '<strong>新文字内容</strong>'; // 解析标签,页面显示加粗的文字:新 文字内容
      console.log(box2.innerHTML);  // 输出:<strong>新文字内容</strong>
    
  5. 操作元素属性
    1)常用属性
    对象.属性 = 值,最常见的属性有:href、title、src
    2)样式属性
    • 通过style属性:对象.style.属性 = 值
        // 通过style
        const box = document.querySelector('.box');
        box.style.width = '300px';
        box.style.border = '1px solid pink';
        // 属性中使用了短横线'-'时,需使用小驼峰命名法
        box.style.backgroundColor = 'lightblue';  // 修改的是css中的background-color
      
    • 通过类名(className):元素.className = '类名',在<style></style>标签中对类名写一个样式,然后给需要修改样式的元素添加这个类名。如果修改的样式多,可使用这种方式。
        <!-- 通过类名 className -->
        <style>
          .box {
            width: 300px;
            background-color: grey;
          }
        </style>
        <script>
          const div = document.querySelector('div');
          // 给元素添加类名,这个值会直接替换掉元素原有的class值
          div.className = 'box';
          // 若希望保留原有类名或添加多个类名,要将所有值都写上,以空格隔开
          div.className = 'oldClassName box other'
        </script>
      
    • 通过classList:使用className是覆盖原有的class值,而classList可以对class的值进行追加和删除,对于需要使用多个类名的元素更加适用。
      • 添加:元素.classList.add('类名'),多个类名之间用逗号隔开;
      • 删除:元素.classList.remove('类名'),多个类名之间用逗号隔开;
      • 切换:元素.classList.toggle('类名')
      • 检查:元素.classList.contains('类名')
      • 替换:元素.classList.replace('旧类名', '新类名')
        <!-- 通过类名 classList -->
        <style>
          .box {
            width: 300px;
            background-color: grey;
          }
        </style>
        <script>
          const div = document.querySelector('div');
          // 给元素添加类名:如果已存在就不添加,添加多个类名用逗号隔开
          div.classList.add('box');
          // 给元素删除类名:如果不存在也不会报错,删除多个类名用逗号隔开
          div.classList.remove('other');
          // 切换类名:有就删除,没有就添加
          div.classList.toggle('other');
          // 检查元素是否包含某个类名, 返回 true 或 false
          div.classList.contains("box");
          // 替换类名, 如果存在就替换, 不存在就添加
          div.classList.replace("oldClass", "newClass");
        </script>
      
    3)表单元素属性
    表单很多情况也需要修改属性,比如密码框的查看密码,本质是点击眼睛时,输入框类型(type)从密码(password)转为了文本框(text)。
    表单属性中添加就有效果,移除就没有效果,一律使用布尔值表示,为true代表添加该属性,为false代表移除该属性。比如:disabled、checked、selected
    获取:DOM对象.属性名
    设置:DOM对象.属性名 = 新值
      <input type="text" value="姓名">
      <button>点击按钮</button>
      <script>
        const uname = document.querySelector('input');
        console.log(uname.value) // 输出:姓名
        console.log(uname.innerHTML) // innerHTML无法取到表单元素的值,输出为空
        // 修改输入框的值
        uname.value = '张三';
        console.log(uname.value); // 
        // 修改输入框类型
        uname.type = 'password';  // 输入框中的内容变成密码样式的小圆点
        // 获取按钮
        const btn = document.querySelector('button');
        btn.disabled = true; // 禁用按钮
      </script>
    
    4)自定义属性
    是html5中推出的,格式为data-自定义属性名,在DOM对象上以dataset方式获取,对象.dataset.自定义属性名。使用对象.dataset可获取到该对象上所有的自定义属性。
      const box = document.querySelector('.box');
      console.log(box.dataset.id)
    
  6. 定时器函数
    定时器函数可以重复执行某段代码。
    语法:setInterval(函数, 间隔时间),间隔时间是数字,单位是毫秒.
      // 每隔一秒执行一次
      setInterval(function () {
        console.log('一秒执行一次');
      }, 1000)
      // 具名函数在setInterval中不需要加小括号
      function fn() {
        console.log('三秒执行一次');
      }
      setInterval(fn, 3000);
    
    关闭定时器:定时器返回值是一个id数字,可以使用变量存放该值,然后使用clearInterval()关闭定时器。
      let 变量名 = setInterval(函数, 间隔时间);
      clearInterval(变量名)
    
    制作倒计时效果
      <button class="btn" disabled>请先阅读协议(60)</button>
      <script>
        let i = 60; // 设置倒计时起始时间
        const btn = document.querySelector('.btn'); //  获取按钮对象
        let m = setInterval(function() {
          i--;
          btn.innerText = `请先阅读协议(${i})`; // 倒计时:一次减一秒
          if (i === 0) {  // 等于0时倒计时结束
            clearInterval(m); // 关闭倒计时
            btn.disabled = false; // 关闭按钮禁用
            btn.innerText = '同意'; // 修改按钮文字
          }
        }, 1000);
      </script>
    

三、Web API —— 事件监听

  1. addEventListener()
    语法:元素对象.addEventListener('事件类型', 要执行的函数)
    事件监听三要素:
    • 事件源:被事件触发的 DOM 元素。
    • 事件类型:什么方式触发的,如:鼠标单击click、鼠标经过mouseover等。
    • 事件调用的函数:要做什么事。
      <button>点击弹出对话框</button>
      <script>
        const btn = document.querySelector('button'); //  获取事件源
        btn.addEventListener('click', function() {  // 事件类型:点击'click'
          alert('hello world'); // 弹出对话框
        })
      </script>
    
  2. 事件监听版本
    • L0 —— 传统注册事件,在早期的事件监听中使用on事件的方式来实现:元素对象.on事件 = function() {}。如:btn.onclick = function() {console.log(11)}。这种方式会被覆盖,同一个对象,后面注册事件会覆盖前面注册的 (同一事件)。
    • L2 —— 事件监听注册,使用addEventListener。同一个对象,后面注册事件不会覆盖前面注册的 (同一事件)
  3. 事件类型
    • 鼠标事件:click(鼠标点击)、mouseover(鼠标经过)、mouseleave(鼠标离开)。
    • 焦点事件(光标):focus(获得焦点)、blur(失去焦点)。
    • 键盘事件:keydown(键盘按下触发)、keyup(键盘抬起触发)。
    • 文本事件:input(用户输入事件)。
      <div style="width: 100px; height: 100px; background-color: pink;"></div>
      <input type="text">
      <script>
        const box = document.querySelector('div');
        const input = document.querySelector('input');
        // 鼠标事件,点击
        box.addEventListener('click', function() {
          alert('hello world')
        })
        // 鼠标事件,鼠标经过
        box.addEventListener('mouseover', function() {
          box.style.backgroundColor = 'blue';
        })
        // 鼠标事件,鼠标离开
        box.addEventListener('mouseleave', function() {
          box.style.backgroundColor = 'pink';
        })
        // 焦点事件,获得焦点
        input.addEventListener('focus', function() {
          console.log('获得焦点');
        })
        // 焦点事件,失去焦点
        input.addEventListener('blur', function() {
          console.log('失去焦点');
        })
        // 键盘事件,按下键盘
        input.addEventListener('keydown', function() {
          console.log('按下键盘');
        })
        // 键盘事件,松开键盘
        input.addEventListener('keyup', function() {
          console.log('松开键盘');
        })
        // 输入事件,输入内容
        input.addEventListener('input', function() {
          console.log('输入内容');
        })
      </script>
    
  4. 事件对象
    事件对象也是一个对象,里面存放了事件触发的相关信息。例如:鼠标点击事件中,事件对象存放了鼠标点的位置信息,键盘按下时可以知道按下的是哪一个键。
    获取事件对象:在事件绑定的回调函数中的第一个参数就是事件对象,一般命名为event、ev、e
    元素.addEventListener('事件名', function(事件对象) {})
      const input = document.querySelector('input');
      input.addEventListener('keydown', function(e) {
        console.log(e); 
        // 输出:KeyboardEvent对象,包含键盘事件的信息,如按下的键值,按下的键的位置等
        // 若按下的是回车键
        // 输出的内容是KeyboardEvent {isTrusted: true, key: 'Enter', code: 'Enter', location: 0, ctrlKey: false, …}
      })
    
    常用属性描述
    type当前事件类型,如clickkeydown
    clientX/clientY光标相对于浏览器可见窗口左上角的位置
    offsetX/offsetY光标相对于当前DOM元素左上角的位置
    key用户按下的键盘的值
  5. 环境对象
    环境对象指的是函数内部特殊的变量this,它代表着当前函数运行时所处的环境。每个函数里都有this
    • 函数的调用方式不同,this指代的对象也不同。
    • 在一般情况下,谁调用,this就指向谁。(判断this指向的粗略规则)
    • 直接调用函数,就相当于window.函数,所以此时this指向window。
  6. 回调函数
    当一个函数被当作参数传递给另一个函数时,这个作为参数的函数就是回调函数。

四、Web API —— 事件流

事件流指的是事件完整执行过程中的流动路径。会经历捕获和冒泡两个阶段。捕获是从父到子,冒泡是从子到父。

  1. 事件捕获
    从DOM的根元素开始去执行对应的事件(从外到里)。
    事件捕获需要写对应代码才能看到效果。
    DOM.addEventListener(事件类型, 事件处理函数, 是否使用事件捕获机制)
    • addEventListener的三个参数传入true代表是捕获阶段触发(很少使用);
    • 若传入的是false,则代表冒泡阶段触发(默认值);
    • 若是用L0事件(传统注册事件)监听,则只要冒泡阶段,没有捕获。
  2. 事件冒泡
    当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发,这一过程被称为事件冒泡。
    简单理解:当一个元素触发事件后,会依次向上调用所有父级元素的同名事件
    事件冒泡是默认存在的。
  3. 阻止冒泡
    事件对象.stopPropagation()可阻断事件传播,对冒泡和捕获都有效果。
      input.addEventListener('click', function(e) {
        alert('1111');
        e.stopPropagation();  // 阻止冒泡
      })
    
  4. 解绑事件
    • 传统注册事件(on事件):同名事件会被覆盖,所以使用null就可以解绑事件,如btn.onclick = null
    • addEventListener方式必须使用removeEventListener(事件类型, 事件处理函数, 获取捕获或冒泡阶段)
    • 匿名函数无法解绑
  5. 阻止默认行为
    有些元素有默认的行为,但在某些情况下需要阻止默认行为,比如链接的跳转、表单提交等。
    使用e.preventDefault()阻止默认行为。
  6. 两种鼠标事件
    鼠标经过和鼠标离开事件都有两种,他们之间的区别是:mouseovermouseout会有冒泡效果,mouseentermouseleave没有冒泡效果(推荐使用)。
  7. 事件委托
    事件委托是利用事件流的特征解决一些开发需求的知识技巧。在需要给多个元素注册同一个事件时,可以使用事件委托,减少注册次数,提高程序性能。
    原理:利用事件冒泡。给父元素注册事件,当触发子元素时,会冒泡到父元素上,从而触发父元素事件。
    实现:利用事件对象,使用事件对象.target.tagName可以获得真正触发事件的元素。
      <ul>
      <p>段落</p>
      <li></li>
      <li></li>
      <li></li>
      <li></li>
      <li></li>
      </ul>
      <script>
        // 点击当前 li 文字变红色
        // 若给每个 li 都添加事件,会造成内存浪费
        // 使用事件委托,只给 ul 添加事件,点击 li 时,事件冒泡到 ul 上,触发事件
        // 通过事件对象的 target 属性,获取当前点击的元素,e.target.tagName 获取当前点击元素的标签名
        const ul = document.querySelector('ul');
        ul.addEventListener('click', function(e){
          console.log(e);
          if(e.target.tagName === 'LI'){
            e.target.style.color = 'red';
          }
        })
      </script>
    

五、Web API —— 页面加载和滚动事件

  1. 页面加载事件
    • load:当外部资源(如图片、外联CSS和JS等)加载完毕时触发的事件。多用于监听页面所有资源加载完毕。
    • DOMContentLoaded:当初始的HTML文档被完全加载和解析完成之后,DOMContentLoaded事件被触发,无需等待样式表、图像等完全加载。
      // 等待页面所有资源加载完成:给 window 添加 load 事件
      window.addEventListener('load', function(){
        alert('加载完成')
      })
      // 监听页面 DOM 加载完毕:给 document 添加 DOMContentLoaded 事件
      document.addEventListener('DOMContentLoaded', function(){
        alert('11')
      })
    
  2. 页面滚动事件
    滚动条在滚动的时候持续触发的事件scroll
    获取滚动的位置:
    • scrollTop:滚动后上方被卷去的长度(即元素向下滚动的长度);
    • scrollLeft:滚动后左边被卷去的长度(即元素向右滚动的长度);
    • 上面两个值都是可读写的。
      // 设置一开始整个页面的滚动距离为 100px
      document.documentElement.scrollTop = 100;
      // 监听整个页面的滚动:给 window / document 添加 scroll 事件
      window.addEventListener('scroll', function(){
        // 获取整个页面的滚动距离
        const n = document.documentElement.scrollTop;
        console.log(n); // 得到的值是一个数字,不带单位,表示滚动距离是多少px
      })
    
  3. 页面尺寸事件
    浏览器窗口大小发生变化的时候触发的事件resize
    • 获取元素的可见部分宽高(不包含边框,margin,滚动条等):clientWidthclientHeight
    • 获取可见元素的自身宽高,包含元素自身设置的宽高、padding、border:offsetWidthoffsetHeight
    • 获取元素距离自己定位父级元素的左、上距离:offsetLeftoffsetTop(只读属性)。
      const div = document.querySelector('.div');
      console.log(div.clientWidth);  // 打印元素的宽度
      window.addEventListener('resize', () => {
        console.log('页面变化了');
        console.log(div.clientWidth);  // 打印元素的宽度
      });
    

六、Web API —— 日期对象

  1. 日期对象Date()

    • new关键字可以实例化一个时间对象。
    • 日期对象返回的数据不能直接使用,需要转换为实际开发中常用的格式。对实例化后的日期对象使用以下方法可从中得到对应的值。
    方法作用说明
    getFullYear()获得年份获取年份的四位数
    getMonth()获得月份取值范围:0 ~ 11,0 表示 1 月
    getDate()获得月份中的某一天(年月日中的日)不同月份取值不相同
    getHours()获得小数取值范围:0 ~ 23
    getMinutes()获得分钟取值范围:0 ~ 59
    getSeconds()获得秒取值范围:0 ~ 59
    getDay()获得星期取值范围:0 ~ 6,0 表示星期天

    还可以使用toLocaleString()、toLocaleDateString()、toLocaleTimeString()对日期进行格式化。

      // 得到当前时间
      const date = new Date();  // 得到时间格式为:Wed Jan 01 2024 08:00:00 GMT+0800 (中国标准时间)
      // 得到指定时间,有几种参数形式
      // 得到指定时间,参数为字符串
      // 字符串格式可以是标准时间格式,也可以是其他格式,但是要保证能被Date.parse解析,否则会返回Invalid Date
      // 例如:'2024-01-01'、'2024/01/01'、'2024-01-01 01:01:01'、'2024/01/01 01:01:01'、'2024-01-01T01:01:01'、'2024/01/01T01:01:01'
      const date1 = new Date('2024-01-01 01:01:01');
      // 得到指定时间,参数为年月日时分秒,月份从0开始计算
      const date2 = new Date(2024, 1, 1, 1, 1, 1);
      // 得到指定时间,参数为时间戳,单位为毫秒,从1970年1月1日开始计算
      const date3 = new Date(1000);
    
      year = date.getFullYear();
      month = date.getMonth() + 1;  // 0-11,0代表1月
      day = date.getDate(); 
      hour = date.getHours();
      minute = date.getMinutes();
      second = date.getSeconds();
      week = date.getDay(); // 0-6,0代表星期天
      console.log(date);  // Wed Apr 10 2024 15:27:58 GMT+0800 (中国标准时间)
      console.log(year, month, day, hour, minute, second, week); // 2024 4 10 15 27 58 3
    
      // 格式化时间
      // 使用toLocaleString方法
      console.log(date.toLocaleString());  // 2024/4/10 15:27:58
      // 使用toLocaleDateString方法
      console.log(date.toLocaleDateString());  // 2024/4/10
      // 使用toLocaleTimeString方法
      console.log(date.toLocaleTimeString());  // 15:27:58
    
  2. 时间戳
    时间戳是指1970年01月01日00时00分00秒至现在的毫秒数,是一种特殊的计量时间的方式。

    • 将来的时间戳 - 现在的时间戳 = 剩余时间毫秒数;
    • 剩余时间毫秒数转换为剩余时间的年月日时分秒就是倒计时时间。
      获取时间戳三种方法:
    • getTime():需要先实例化,const date = new Date(); console.log(date.getTime())
    • 使用+运算符:可直接使用+new Date(),括号中写参数可得到指定时间戳,不写参数是当前时间戳;也可实例化之后再使用+,如const date = new Date(); console.log(+date)
    • Date.now():只能得到当前时间戳。

七、Web API —— DOM 节点

  1. DOM 节点
    DOM 树中每一个内容都称之为节点
    节点类型:
    • 元素节点:所有标签,如body、div,其中html是根节点;
    • 属性节点:比如href
    • 文本节点:所有的文本;
    • 其他
  2. 查找节点
    • 父节点:元素.parentNode,返回最近一级的父节点,找不到返回null
    • 子节点:元素.children,获得元素所有的子节点中的元素节点(伪数组)。
    • 兄弟节点:元素.nextElementSibling(下一个兄弟元素)、元素.previousElementSibling(上一个兄弟元素)。
  3. 新增节点
    • 创建一个节点:document.createElement('标签名')
    • 追加节点(将节点放入某个元素中):父元素.appendChild(子元素)父元素.insertBefore(要插入的元素, 在哪个元素前插入)
      // 创建新节点
      const li = document.createElement('li');
      // 追加节点
      const ul = document.querySelector('ul');
      ul.appendChild(li); // 在ul中子元素的最后追加了一个li
      ul.insertBefore(li, ul.children[0]) // 在ul的第一个子元素前插入li
    
  4. 克隆节点
    语法:被克隆元素.cloneNode(是否克隆标签里的内容):如:li.cloneNode(true)true表示将li里面的内容一起克隆,如果是false则表示只克隆一个标签。
  5. 删除节点
    在JavaScript中,删除元素必须通过父元素删除。
    语法:父元素.removeChild(要删除的元素)。若不存在父子关系则删除不成功。

八、移动端事件

移动端有一些常用事件,如触屏事件touch(触摸事件)。

  • touchstart:手指触摸到一个 DOM 元素时触发;
  • touchmove:手指在一个 DOM 元素上滑动时触发;
  • touchend:手指从一个 DOM 元素上移开时触发。

九、swiper 插件

Swiper 是一款免费以及轻量级的移动设备触控滑块的js框架。
官网链接:https://www.swiper.com.cn/

  • 27
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值