本文为个人在学习JS过程中记录的笔记,主要基于 黑马程序员前端JavaScript入门到精通 视频和 JavaScript | 菜鸟教程 进行学习。

目前暂时学习完视频P99,后续有机会再进行学习更新

基本概念

  1. 定义:javascript是一种执行在客户端的脚本语言,不需要编译,在运行过程中由js解释器(js引擎)来逐行进行解释并执行

    • 常见的js引擎,如chrome使用的v8引擎等
    • 虽然javascript最初是用于前端开发,但是现在已经可以用于多种开发,如node.js就是内置了v8引擎,使得js脚本可以在浏览器之外的环境下运行,用于编写服务端代码等。
  2. JS 的作用

    • 表单动态校验 (密码强度检测) ( JS 产生最初的目的)

      比如一个表单字段的输入并不符合规范,如果需要发给服务端,服务端收到之后判断发现并不合规,再返回就会产生比较大的延迟

    • 网页特效

    • 服务端开发(Node.js)

    • 桌面程序(Electron)

    • App(Cordova)

    • 控制硬件-物联网(Ruff)

    • 游戏开发(cocos2d-js)

  3. 浏览器如何执行JS

    浏览器分成两部分:渲染引擎和JS引擎

    • 渲染引擎(内核):用来解析HTML与CSS ,比如chrome浏览器的blink ,老版本的webkit
    • JS引擎(JS解释器):用来读取网页中的JS代码,逐行解释源码并将其转化为机器语言由计算机执行。比如chrome浏览器的V8
  4. JS的三部分组成

    • 核心(ECMAScript):即JS语法
    • Web APIs:即通过JS去操作html和浏览器
      • 文档对象模型(Document Object Model,简称DOM) :通过DOM提供的接口可以对页面上的各种元素进行操作(大小、位置、颜色等)。
      • 浏览器对象模型(Browser Object Model,简称BOM):提供了独立于内容的、可以与浏览器窗进行互动的对象结构。通过BOM可以操作浏览器窗口,比如弹出框、控制浏览器跳转、获取分辨率等。
  5. JS的书写位置

(1)内部 javascript

Javascript 脚本代码可被放置在 HTML 页面的 <body><head> 部分中。

  • 写在 <head> 部分中的js脚本在页面内容加载之前被加载和执行

    • 这对于需要在页面加载之前进行的一些初始化操作非常有用,例如预加载某些数据或设置全局变量。
    • 由于脚本在页面内容加载之前执行,如果脚本执行时间较长,可能会导致页面加载变慢,影响用户体验。
    • 如果脚本需要操作 DOM 元素,而这些元素尚未加载完成,可能会导致错误。
  • 写在 <body> 部分的js脚本在页面内容加载完成后执行

    • 可以直接写到元素的内部,不需要使用script标签

      1
      <input type="button" value="唐伯虎" onclik="alert('秋香')">

      或者写在body的尾部,使用 script 标签

    • 所有 DOM 元素都已经可以被操作,从而避免了在操作 DOM 时遇到的错误。

    • 可以在页面加载后执行一些需要立即生效的脚本,例如初始化页面内容或绑定事件处理程序。

    • <body> 部分放置大量脚本代码可能会导致 HTML 文件过于冗长,影响代码的可读性和可维护性。

如果脚本不依赖于页面内容,可以放在 <head> 部分,以便尽早加载和执行。

如果脚本需要操作页面中的 DOM 元素,通常放在 <body> 部分,或者放在 <body> 底部,以确保页面内容已经完全加载。

(2)外部 javascript

可以引入外部 JavaScript 文件,外部文件通常包含被多个网页使用的代码。可以实现 HTML 和 JavaScript 的分离,提高代码的可读性和可维护性。使用 <script> 标签中的 src 属性来标注 js 文件的位置

1
2
//注意使用外部加载js的时候,script标签中间不能写代码
<script src="my.js"></script>
  1. JS代码执行顺序
    • 按HTML文档流顺序执行JavaScript代码
    • alert()和prompt()它们会跳过页面渲染先被执行

基础语法

输入和输出

  1. 输出语法

    (1)document.write

    向body内输出内容,如果输出的内容为标签,会被解析成网页元素

    1
    2
    3
    4
    <script>
    document.write('我是div标签')
    document.write('<h1>我是标题</h1>')
    </script>

    (2)alert

    页面弹出警告窗

    1
    2
    3
    <script>
    window.alert(5 + 6)
    </script>

    (3)console.log

    控制台输出(页面中并没有效果),用于程序员的调试

    1
    2
    3
    <script>
    console.log('aaaa')
    </script>
  2. 输入语法

    (1)prompt

    显示一个对话框,对话框中包含一条文字信息,用来提示用户输入文字

    1
    2
    3
    <script>
    prompt('输入你的年龄:')
    </script>

变量和常量

  1. 变量

    初始化(声明+赋值)

    1
    let age = 18,username = 'isoda'
    • 注意一条语句中声明的多个变量不可以同时赋同一个值:

      1
      2
      //这种声明方法是错误的,定义了x,y为undefined,z为1。
      let x,y,z=1
    • 旧版本使用 var 来定义变量,目前的版本都使用 let 来进行定义

      var 相比 let 存在很多的缺点:

      • 可以先使用在声明(打印出来为undefined),不合理
      • var声明过的变量可以多次重复声明,不合理
      • 比如变量提升、全局变量、没有块级作用域等等
  2. 常量

    声明的时候必须初始化,且不允许重新赋值

    1
    2
    3
    const PI = 3.141592653589793;
    PI = 3.14; // 报错
    PI = PI + 10; // 报错

在开发的时候:

  • 基本数据类型:推荐先定义数据为常量const,后续发现这个数据需要修改再改为变量let
  • 对象数据类型:定义对象为const
    • 仍然可以追加对象中的元素,因为对象数据类型存储的是指向对象的地址,虽然对象变了但是地址没有改变
    • 不能将其指向新的对象,这样地址就产生了改变
1
2
3
const arr = ['red','blue']
arr.push('blue') //没有报错
arr = [1,2,3] //产生报错

数据类型

  1. 数据类型分类

    主要可以分成两大类

    • **值类型(基本类型)**:字符串(String)、数字(Number)、布尔(Boolean)、空(Null)、未定义(Undefined)、Symbol。
    • 引用数据类型(对象类型):对象(Object)、数组(Array)、函数(Function),还有两个特殊的对象:正则(RegExp)和日期(Date)。

    这两种类型的区别可见编程基础.计算机基础知识.堆栈

  2. 基本数据类型

    1)字符串

    1
    2
    let answer = "He is called 'Johnny'";
    let answer = 'He is called "Johnny"';
    • 字符串拼接:通过 + 运算符,或者反引号

      1
      2
      3
      4
      5
      6
      7
      //1. 通过 + 运算符
      let age = 15
      document.write("我今年"+age+"岁了")

      //2. 通过 `` 号
      let age = 15
      document.write(`我今年${age}岁了`)

    2)数字

    1
    2
    3
    let x1 = 34.00      		//使用小数点来写
    let x2 = 34 //不使用小数点来写
    let y = 123e5 // 12300000

    3)布尔

    1
    2
    let x = true
    let y = false

    4)空(null)

    null表示赋值了,但是内容为空。一般作为尚未创建的对象

    1
    2
    let x = null
    console.log(x)

    注意 undefined 和 null 的区别

    null表示空,加上1的话就表示1了

    1
    2
    console,log(undefined + 1) 		//NaN
    console.log(null+1) //1

    5)未定义(Undefined)

    声明了的对象未赋值,打印出来就是Undefined

    1
    2
    let x 
    console.log(x)

    6)数组

    javascript中列表和数组是一个概念, 没有区别

    1
    2
    3
    4
    5
    6
    7
       let cars = ["Saab","Volvo","BMW"]
    let myCars = new Array("Saab","Volvo","BMW");
    let myCars=new Array();

    // 数组的操作
    console.log(cars[0],cars[2])
    console.log(cars.length)
    • 数组添加新数据

      1
      2
      3
      4
      5
       // push()方法将一个或多个元素添加到数组末尾,返回数组的新长度
      length = arr.push(a,b,c)

      // unshift()方法将一个或多个元素添加到数组开头,返回数组的新长度
      length = arr.unshift(a,b,c)
    • 数组删除数据

      1
      2
      3
      4
      5
      6
      7
      8
      9
      // pop()方法从数组中删除最后一个元素,并返回该元素的值
      delete_data = arr.pop()

      // shift()方法从数组中删除第一个元素,并返回该元素的值
      delete_data = arr.shift()

      // splice()方法从start位置开始删除掉deletCount个元素
      arr.splice(0,1)
      arr.aplice(1,3)
  3. 检测数据类型

    1
    typeof x
  4. 数据类型转换

    • 为什么需要数据类型转换:

      表单、prompt获取到的数据默认是字符串类型的,当做数字类型等会产生错误

      1
      console.log('10000'+'2000') 	// 输出结果 100002000
    • 隐式转换

      某些运算符被执行时,系统内部自动将数据类型进行转换,这种转换称为隐式转换。

      • + 号两边只要有一个是字符串,都会把另外一个转成字符串
      • 除了 + 以外的算术运算符,比如 - * / 等都会把数据转成数字类型
      • + 号作为正号解析可以转换成数字型
      • 任何数据和字符串相加,都视作字符串拼接,结果都是字符串
      1
      2
      3
      4
      5
      6
      console.log(1 + 1)			//2
      console. log('pink' + 1) //pink1
      console.log(2 + '2') //22
      console.1og(2 - 2) //0
      console.1og(2 - '2') //0
      console.1og(+'123') //可以看作正负号,将字符串转化为数字型
    • 显示转换

      编写程序时过度依靠系统内部的隐式转换是不严禁的,因为隐式转换规律并不清晰,大多是靠经验总结的规律。为了避免因隐式转换带来的问题,通常需要对数据进行显示转换。

      即:自己写代码告诉系统该转成什么类型

    • 常见的数据类型转换方法

      1)字符串转换数字

      • Number()

        1
        2
        3
        4
        Number("3.14")    	// 返回 3.14
        Number(" ") // 空字符串返回 0
        Number("") // 空字符串返回 0
        Number("12px") // 其他非纯数字字符串返回 NaN
      • parseInt():只保留整数部分

        注意parseInt()和parseFloat()中字符串的开头必须是数字,不然都会返回NaN

        1
        2
        parseInt("12px")   			// 返回12
        parseInt("12.13") // 返回12

        注意这里和上面Number处理非纯数字字符串的区别,这里会直接过滤掉字符部分

      • parseFloat():保留小数

        1
        2
        parseFloat("12px")   			// 返回12
        parseFloat("12.13px") // 返回12.13

      2)数字转换字符串

      1
      2
      3
      4
      5
      6
      7
      8
      9
      // 使用String
      String(x) // 将变量 x 转换为字符串并返回
      String(123) // 将数字 123 转换为字符串并返回
      String(100 + 23) // 将数字表达式转换为字符串并返回

      // 使用toString()
      x.toString()
      (123).toString()
      (100 + 23).toString()

      3)转换为布尔值

      1
      Boolean(a)
  5. 数据类型存储方式

    • 基本数据类型的存储:存储的是数据的值

      1
      2
      3
      4
      let num1 = 10
      let num2 = num1
      num = 20
      console.log(num1) //输出为10
    • 对象数据类型的存储:存储的是地址

      1
      2
      3
      4
      5
      6
      let obj1 = {
      age:18
      }
      let obj2 = obj1
      obj2.age = 20
      console.log(obj1.age) //输出为20

      因为obj2中存储的是和obj1相同的地址,所以修改obj2映射到堆中的对象值后,obj1也是映射到这个地址,所以obj1的结果也产生了改变

运算符

  1. 运算符的优先级

    image-20240714171016207

    • === 判断值和类型是否完全相同,返回值为 boolean

      1
      2
      3
      // 因为 === 优先级高,先计算得到值相同类型不同,返回false
      let c = 2 === "2"
      console.log(c) // 输出为false
  2. 逻辑中断

    1)原理:当有多个表达式(值)时,左边表达式的值可以确定时,就不再继续运算右边表达式的值。

    0" " (空字符串)' '(空字符串)null(空值)undefined(未定义)NaN(非数值)都表示为false,除这些之外的为true。

    例如:这里因为123为真,所以直接返回123,右边的num++并没有执行

    1
    2
    3
    var num = 0;
    document.write(123 || num++); //逻辑中断,返回值123,之后的代码不再继续运行
    document.write(num); //num的值仍为0

    2)逻辑与

    • 如果第一个表达式的值为真,则返回表达式2
    • 如果第一个表达式的值为假,则返回表达式1
    1
    2
    3
    4
    5
    6
    console.log(false && 20)		//false
    console.log(5<3 && 20) //false
    console.log(undefined && 20) //undefined
    console.log(null && 20) //null
    console.log(0 && 20) //0,因为0是看作假的
    console.log(10 && 20) //20

    3)逻辑或

    • 如果第一个表达式的值为真,则返回表达式1
    • 如果第一个表达式的值为假,则返回表达式2
    1
    2
    3
    console.log( 123 || 456 );         //  123
    console.log( 0 || 456 ); // 456
    console.log( 123 || 456 || 789 ); // 123

语句

  1. 分支语句

    分支语句可以让我们有选择性的执行想要的代码

    1)if分支语句

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    if (time<10)
    {
    document.write("<b>早上好</b>")
    }
    else if (time>=10 && time<20)
    {
    document.write("<b>今天好</b>")
    }
    else
    {
    document.write("<b>晚上好!</b>")
    }

    2)三元运算符

    语法:条件**?代码1(满足条件执行的代码):**代码2:(不满足条件执行的代码)

    一般用于赋值

    3)switch语句

    1
    2
    3
    4
    5
    6
    7
    8
    9
    switch (d)
    {
    case 6:x="今天是星期六"
    break
    case 0:x="今天是星期日"
    break
    default:
    x="期待周末"
    }
        - 注意不要漏掉break,不然程序继续执行下一个case,直到遇到break或switch语句结束。
    
  2. 循环语句

    当明确循环次数的时候使用for,不确定的时候使用while(true)

    1)while循环和do/while循环

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    //先判断再执行
    while (i<5)
    {
    x=x + "The number is " + i + "<br>"
    i++
    }

    //先执行一次再判断
    do
    {
    x=x + "The number is " + i + "<br>"
    i++
    }
    while (i<5)

    2)for循环

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // for循环
    for (let i=0;i<cars.length;i++)
    {
    document.write(cars[i] + "<br>")
    }

    // for/in语句遍历对象的属性
    let person = {fname:"Bill",lname:"Gates",age:56};
    for (let key in person) // x 为属性名
    {
    txt = txt + person[x]
    }

    3)打破循环

    • break语句:直接跳出循环,执行循环之后的代码

      1
      2
      3
      4
      5
      6
      7
      8
      9
      for (i=0;i<10;i++)
      {
      if (i==3)
      {
      break
      }
      //if (i==3) break
      x=x + "The number is " + i + "<br>"
      }
    • continue语句:中断当前循环中的迭代,继续循环下一个迭代

      1
      2
      3
      4
      5
      for (i=0;i<=10;i++)
      {
      if (i==3) continue;
      x=x + "The number is " + i + "<br>"
      }

函数

  1. 函数的声明

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <script>
    // 注意:这样仅仅是声明,只有调用了函数才会执行
    function myFunction(let1,let2)
    {
    code
    }
    // 调用
    myFunction(let1,let2)
    </script>
  2. 具名函数和匿名函数

    1)具名函数:function fn() {}

    • 调用:fn()
    • 具名函数的调用可以写到任何位置,即可以先调用再声明

    2)匿名函数:function() {}

    • 无法调用

    • 使用方式:

      • 函数表达式

        必须先声明再调用

        1
        2
        3
        4
        5
        6
        7
        8
        <script>
        let fn = function (let1,let2)
        {
        code
        }
        // 调用
        fn(x,y)
        </script>
      • 立即执行函数

        不需要调用,直接执行。

        多个立即执行函数之间必须要用分号隔开

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        <script>
        (function ()
        {
        code
        })();
        // 注意多了两个括号
        // 第一个括号其实就是将函数声明看作函数,后面的括号直接调用函数
        (function (x,y)
        {
        console.log(x + y)
        })(1,2)
        </script>

        这样来看的话,立即执行函数好像和直接写顺序代码执行,不封装为函数没有什么区别?

        其实还是有作用的:封装了函数等于构建了一个新的作用域,在这个作用域里面使用的变量和函数外是分离的,可以重复相互不影响。达到了防止变量污染的作用。

对象

  1. 对象的定义

    对象是一种数据类型,是一种无序的数据的集合,可以用于详细地描述某个事物。

    • 对象中由属性和方法组成

    例如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    let person = {
    // 属性
    firstName:"John",
    lastName:"Doe",
    age:50,
    // 方法
    fullName : function()
    {
    return this.firstName + " " + this.lastName;
    }
    };
  2. 对象的使用

    访问对象中的属性值: 对象名.属性 对象名["属性"](属性名中包含-的时候只能用后者)

    访问方法也是一样的

    1
    2
    3
    4
    5
    6
    7
    8
    9
    // 增(直接赋值一个新的属性即可)
    person.hobby = "basketball"
    // 删
    delete person.hobby
    // 改
    person.firstName = "isoda"
    // 查
    console.log(person.firstName)
    name = person.fullName()
  3. 对象的遍历

    使用for/in语句遍历对象的属性

    1
    2
    3
    4
    5
    let person = {fname:"Bill",lname:"Gates",age:56}; 
    for (let key in person) // key 为属性名,为字符串
    {
    txt = txt + person[key]
    }

    注意:

    这里只能用 person[key] 来访问对象,因为key为字符串,为’fname’,’lname’的形式

    所以不能使用person.key,显示出来就是person.’fname’,这种形式明显是错误的,会得到undefined。而 person[‘fname’],这种访问方法才是正确的。

JS DOM

DOM简介

  1. 概念

    DOM(文档对象模型),是浏览器提供的一套专门用来操作网页内容的功能(API),通过DOM,JavaScript 可以创建动态的HTML,实现用户的交互:

    • 改变页面中的所有 HTML 元素

    • 改变页面中的所有 HTML 属性

    • 改变页面中的所有 CSS 样式

    • 对页面中的所有事件做出反应

  2. DOM树

    将HTML文档以树状结构直观的表现出来,即DOM树。可以直观体现标签和标签之间的关系

    image-20240716143932776

  3. DOM对象

    从DOM树上获取到的所有html标签都是JS对象,即DOM对象

    • 所有的标签属性都可以在这个对象上面找到
    • 修改这个对象的属性会自动映射到标签身上
    • 从dom树来看,最大的dom对象就是document对象,document对象下的属性和方法都是用来访问和操作网页内容的,如 document.write() 用来写入网页内容

获取DOM元素

  1. 通过CSS选择器来获取

    • querySelector:匹配符合的第一个元素,返回对应的HTML元素对象

    • querySelectorAll:返回符合的HTML元素对象数组

      • 注意,返回的是一个伪数组,有长度有索引号,但是没有pop和push等方法

        通过p[0]等来访问

      • 如果只有一个元素,返回的也是仅有一个元素的伪数组

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    <div class = 'box'>123</div>
    <div class = 'box'>abc</div>
    <p id="nav">导航栏</p>
    <ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    </ul>

    <script>
    // 直接获取标签
    const box = document.querySelector('div')
    // 根据class
    const box = document.querySelector('.box')
    console.log(box)
    // 根据id
    const nav = document.querySelector('#nav')
    console.log(nav)
    nav.style.color = 'red' //可以对其直接修改样式属性
    // 获取ul下的第一个li,和CSS的选择方法一样
    const li = document.querySelector('ul li:first-child')
    console.log(li)
    </script>
  2. 其他获取DOM元素的方式

    以下三种是比较老的写法,目前已经逐渐不再使用了

    • 通过 id 找到 HTML 元素
    • 通过标签名找到 HTML 元素
    • 通过类名找到 HTML 元素
    1
    2
    3
    document.getElementById('nav')
    document.getElementsByTagName('div')
    document.getElementsByClassName('w')

操作HTML内容

  1. innerText

    修改文本内容,仅显示纯文本,不解析标签

    1
    document.querySelector('.box').innerText = '我是一个盒子'
  2. innerHTML

    修改文本内容,可以解析标签

    1
    document.querySelector('.box').innerHTML = '<strong>我是一个盒子</strong>'

操作元素属性

  1. 操作元素基本属性

    如src、href、title等

    • 语法:

      1
      2
      // 对象.属性 = 值
      document.querySelector('img').src = './images/a.webp'
  2. 操作元素样式属性CSS

    1)通过style属性操作

    语法:

    1
    2
    3
    4
    // 对象.style.样式属性 = 值
    <div class = "box"> </div>
    document.querySelector('.box').style.width = '200px'
    box.style.backgroundColor = 'hotpink'
    • 属性中存在的数字单位不要忘记添加,如 px

    • 如果属性中含有 - 连接符,可以去掉 - 然后将后面的首字母大写

      background-color 可以改成 backgroundColor

    2)通过className操作

    当需要修改的样式比较多的时候,逐一修改style属性比较繁琐,可以设置一个新的class,然后将需要修改的标签的class修改为新创建的class

    语法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    // 元素.className = 新的class名称
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>Javascript学习</title>
    <style>
    .class1{
    width: 200px;
    height: 200px;
    background-color: #fff;
    }
    .class2{
    width: 300px;
    height: 300px;
    background-color:skyblue;
    margin: 100px auto;
    padding: 10px;
    }
    </style>
    </head>
    <body>
    <div class="class1">我是文字的内容</div>
    <script>
    const box = document.querySelector('div')
    box.className = 'class2'
    console.log(box) // 打印出来的class属性为 class2
    </script>
    </body>
    </html>
    • 注意这里使用的是className,因为class是关键字

    • 属性新值换旧值,这里的class1会被class2覆盖掉

      如果不想覆盖,可以这样修改:

      1
      box.className = 'class1 class2'

    3)通过classList操作

    可以直接追加、删除或者切换类名

    语法:

    1
    2
    3
    4
    5
    6
    7
    // 追加一个类
    元素.classList.add('类名')
    // 删除一个类
    元素.classList.remove('类名')
    // 切换一个类
    // 检查有没有使用这个类,如果有就删除,没有就加上(像灯反复按开关一样)
    元素.classList.toggle('类名')
  3. 操作表单元素属性

    1)有很多时候需要修改表单的属性,如点击眼睛可以看到密码文本内容,本质就是将password类型转换为text

    1
    2
    表单.value = '用户名'
    表单.value = 'password'
    • 注意,使用innerHTML是不能获取到表单内容的,只能通过value来获取

    2)表单属性中添加就有效果,移除就没有效果,一律使用布尔值表示。如果为true代表添加了该属性如果是false代表移除了该属性。如点击全选就勾选所有的内容

    如 disabled. checked 、selected,只接受布尔值

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // 方框勾选
    <input type="checkbox" name = "" id = "" checked>
    // 禁用点击
    <button disabled>点击</button>

    <script>
    const ipt = document.querySelector('input')
    ipt.checked = true
    button.disabled = true
    console.log(ipt.checked)
    </script>
    • 如果我们这里写的是 ipt.checked = 'true', 仍然会改变成true,因为非空、0的字符串默认认定为true。但是并不提倡这么写,不规范
  4. 自定义属性

    上面都是标准属性,即标签自带的属性,如class、id、title等,通常我们会自定义一些属性

    • 自定义属性要求data- 开头,在DOM对象上以 dataset. + 删除掉data-的后面部分 对象来获取
    1
    2
    3
    4
    5
    6
    // 自定义属性data-id,在后面通过dataset.id来获取
    <div data-id = '10'>盒子</div>
    <script>
    const box = document.querySelector('.box')
    console.log(box.dataset.id)
    </script>

定时器(间歇函数)

定时器面向的功能:需要每隔一段时间自动执行一段代码,不需要手动去触发

例如:网页中的倒计时。

  1. 开启定时器

    语法:setInterval(函数,间隔时间)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // 直接使用函数
    function fn(){
    console,log('一秒执行一次')
    }
    setInterval(fn,1000)

    // 可以使用匿名函数
    setInterval(function(){
    console.log('一秒钟执行一次')
    },1000)
    • 注意这里是在过了间隔时间后才第一次执行函数,并不是立即执行一次,然后过了间隔时间后再执行第二次
    • 函数名字不需要加括号
    • 定时器返回的是一个id数字,表示这是第几个定时器(页面中可能设置了多个定时器)
  2. 关闭定时器

    语法:clearInterval(定时器id)

    1
    2
    let m = setInterval(fn,1000)
    clearInterval(m)

DOM事件

  1. 基本概念

    • 什么是事件:编程时系统内发生的动作或者发生的事情,比如用户在网页上单击一个按钮、图像加载完成、鼠标移动到元素上、输入字段被改变等
    • 事件监听:检测是否有时间发生,一旦触发事件,立即调用一个函数做出响应
  2. 添加事件监听(绑定)

    语法:元素对象.addEventListener(‘事件类型’, 要执行的函数)

    • 事件类型:事件用什么方式触发,如鼠标单击click、鼠标经过mouseover等
    1
    btn.addEventListener('click', myFunction)
  3. 事件类型

    • 鼠标事件

      • 鼠标点击:click
      • 鼠标经过:mouseenter
      • 鼠标离开:mouseleave
    • 焦点事件

      • 获得焦点:focus
      • 失去焦点:blur

      注意和点击的区别,例如搜索框,鼠标点击后出现下拉框,离开就消失,这种就是得到鼠标+失去鼠标,为焦点事件

    • 键盘事件

      • 键盘按下:Keydown
      • 键盘抬起:Keyup
    • 文本事件

      • 用户输入事件:input
  4. 事件对象

其他

map函数遍历数组:JavaScript中的map()方法详解(均采用es6语法)

功能案例

1. 同意协议倒计时

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=decive-width, initial-scale=1" >
<title>案例1:同意协议倒计时</title>
</head>
<body>
<textarea name="" id="" cols="30" rows="10">
用户注册协议
欢迎注册成为微博用户,请你仔细阅读并同意一下用户协议
</textarea>
<br>
<button class="btn" disabled>我已经阅读用户协议(5)</button>
<script>
const btn = document.querySelector('.btn')
let i = 5
let n = setInterval(function(){
i --
btn.innerHTML = `我已经阅读用户协议(${i})`
if (i==0) {
clearInterval(n)
btn.disabled = false
}
},1000)
</script>
</body>
</html>

2. 轮播图

见视频P97、98

3. 发布评论

见视频P99