JavaScript

JavaScript 是一种高层次的、解释性、动态类型的编程语言。它是 Web 开发的核心技术之一,与 HTML 和 CSS 通常一起使用。主要用于客户端网页开发,但也可以在服务器端使用(例如,通过 Node.js),增加网页的交互性、动态更新内容、控制多媒体、动画效果等。

特性

  • 动态类型:JavaScript 是动态类型语言,意味着不需要在声明变量时指定其数据类型,变量的类型可以根据赋值而改变。
  • 对象导向:JavaScript 是基于原型的语言,支持面向对象编程。
  • 事件驱动:JavaScript 常常在用户与网页的交互(如点击、滚动等)时进行响应,非常适合编写交互式应用。

JavaScript 引入方式

1. 内联 JavaScript

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>内联 JavaScript 示例</title>
</head>
<body>
    <button onclick="alert('Hello, World!')">点击我(内联)</button>
</body>
</html>

2. 内部<script> 标签

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>直接写在 HTML 中示例</title>
    <script>
        function showAlert() {
            alert('Hello, World!');
        }
    </script>
</head>
<body>
    <button onclick="showAlert()">点击我(直接写在 HTML 中)</button>
</body>
</html>

3. 外部 JavaScript 文件

  • 创建一个名为 script.js 的文件
function showAlert() {
    alert('Hello, World!');
}
  • 创建一个 HTML 文件,以引入该外部 JavaScript 文件:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>外部 JavaScript 示例</title>
    <script src="script.js"></script> <!-- 引入外部 JavaScript 文件 -->
</head>
<body>
    <button onclick="showAlert()">点击我(外部文件)</button>
</body>
</html>

JavaScript 基础

数据类型

JavaScript 有两种基本类型:原始数据类型和复杂数据类型。

原始数据类型

String:表示文本数据。

let str = "Hello, World!"; // 字符串

Number:表示数字数据。

let num = 42; // 整数
let decimal = 3.14; // 浮点数

Boolean:表示真或假的值

let isTrue = true; // 布尔值

Null:表示空值。

let emptyValue = null; // 空值

Undefined:表示未赋值的状态。

let notAssigned; // 默认值为 undefined

Symbol (ES6 引入):一种独特且不可变的值,通常用于对象属性的唯一标识。

const uniqueId = Symbol("id"); // 创建一个唯一标识符

复杂数据类型

Object:是一种包含多个值的集合,包括数组和函数。

let person = {
    name: "Alice",
    age: 30,
    isStudent: false,
    greet: function() {
        console.log("Hello, my name is " + this.name);
    }
};

Array:表示一组数据,可以包含多种数据类型。

let fruits = ["apple", "banana", "orange"];

Function:在 JavaScript 中,函数也是对象。

function add(a, b) {
    return a + b;
}

数据类型演示demo:

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JavaScript 原始和复杂数据类型示例</title>
    <style>
        body {
            font-family: Arial, sans-serif;
        }
        .output {
            margin-top: 20px;
        }
    </style>
</head>
<body>
    <h1>JavaScript 数据类型演示</h1>
    
    <button id="showDataButton">显示数据类型示例</button>
    <div class="output" id="output"></div>

    <script>
        // 原始数据类型示例
        let str = "Hello, World!"; // 字符串
        let num = 42; // 整数
        let decimal = 3.14; // 浮点数
        let isTrue = true; // 布尔值
        let emptyValue = null; // 空值
        let notAssigned; // 默认值为 undefined
        const uniqueId = Symbol("id"); // 创建一个唯一标识符

        // 复杂数据类型示例
        let person = {
            name: "Alice",
            age: 30,
            isStudent: false,
            greet: function() {
                return "Hello, my name is " + this.name;
            }
        };

        let fruits = ["apple", "banana", "orange"]; // 数组

        function add(a, b) {
            return a + b; // 函数返回两个数的和
        }

        // 当点击按钮时显示数据
        document.getElementById('showDataButton').onclick = function() {
            let output = `
                <h2>原始数据类型</h2>
                <p>字符串: ${str} (${typeof str})</p>
                <p>整数: ${num} (${typeof num})</p>
                <p>浮点数: ${decimal} (${typeof decimal})</p>
                <p>布尔值: ${isTrue} (${typeof isTrue})</p>
                <p>空值: ${emptyValue} (${typeof emptyValue})</p>
                <p>未赋值: ${notAssigned} (${typeof notAssigned})</p>
                <p>唯一标识符: ${uniqueId.toString()} (${typeof uniqueId})</p>

                <h2>复杂数据类型</h2>
                <p>对象: ${JSON.stringify(person)} (${typeof person})</p>
                <p>问候: ${person.greet()}</p>
                <p>水果: ${JSON.stringify(fruits)} (${typeof fruits})</p>

                <h2>调用函数</h2>
                <p>5 + 10 = ${add(5, 10)}</p>
            `;
            document.getElementById('output').innerHTML = output;

            // 在控制台打印相同的信息
            console.log("原始数据类型:");
            console.log(`字符串: ${str} (${typeof str})`);
            console.log(`整数: ${num} (${typeof num})`);
            console.log(`浮点数: ${decimal} (${typeof decimal})`);
            console.log(`布尔值: ${isTrue} (${typeof isTrue})`);
            console.log(`空值: ${emptyValue} (${typeof emptyValue})`);
            console.log(`未赋值: ${notAssigned} (${typeof notAssigned})`);
            console.log(`唯一标识符: ${uniqueId.toString()} (${typeof uniqueId})`);

            console.log("复杂数据类型:");
            console.log(`对象: ${JSON.stringify(person)} (${typeof person})`);
            console.log(`问候: ${person.greet()}`);
            console.log(`水果: ${JSON.stringify(fruits)} (${typeof fruits})`);

            // 调用函数
            console.log(`5 + 10 = ${add(5, 10)}`);
        };
    </script>
</body>
</html>

代码结构概述

主体部分 (<body>)

  1. 按钮 (<button>):
    • 这个按钮的文本是“显示数据类型示例”。
    • 当用户点击这个按钮时,会触发 JavaScript 中定义的事件处理程序,展示存储在 JavaScript 变量中的数据类型和数据值。
  2. 输出区域 (<div>):
    • 这个 <div> 元素是一个容器,用于动态显示 JavaScript 生成的内容。
    • 在按钮被点击时,JavaScript 将生成一段 HTML 内容,并将其插入到这个 <div> 中,该内容包括原始数据类型和复杂数据类型的值及其类型描述。

JavaScript 部分 (<script>)

  1. 变量定义:
    • 首先定义了一些变量,包括原始数据类型(如字符串、数字、布尔值等)和复杂数据类型(如对象和数组)。
    • 这些变量存储了要展示的数据。
  2. 为按钮添加点击事件:
    • 使用 document.getElementById('showDataButton').onclick 来获取按钮元素,并为其分配一个点击事件处理函数。
    • 这个事件处理函数在用户点击按钮时执行。
  3. 生成输出内容:
    • 在事件处理函数内部,使用模板字面量(template literals,即反引号包裹的字符串)创建一段 HTML 内容,该内容包括:
      • 每个原始数据类型的值及其对应的数据类型(使用 typeof 运算符)。
      • 复杂数据类型(对象和数组)的 JSON 字符串表示,以便在 HTML 中可读。
    • 例如,<p>字符串: ${str} (${typeof str})</p> 会生成类似于“字符串: Hello, World! (string)”的内容。
  4. 插入内容到输出区域:
    • 使用 document.getElementById('output').innerHTML = output; 将生成的 HTML 内容插入到之前定义的输出区域 <div> 中。这一行代码指明要将生成的字符串内容作为 HTML 填充到具有 id="output" 的 <div>中,从而在网页上展示这些数据。
  5. 控制台输出:
    • console.log() 方法用于将相同的信息输出到浏览器的开发者工具控制台。这使得开发者可以在控制台中查看这些变量的值和类型,便于调试和验证。
JavaScript

变量声明

JavaScript 支持三种变量声明方式:

var

  • 作用域:函数作用域。
  • 示例
var name = "Alice"; // 变量可以在函数内访问

let

  • 作用域:块作用域。
  • 示例
let age = 30; // 在代码块内可用
if (true) {
    let age = 25; // 不同于外部的 age
    console.log(age); // 输出 25
}
console.log(age); // 输出 30

const

  • 作用域:块作用域,常量不能重新赋值。
  • 示例
const pi = 3.14;
// pi = 3.15; // 会引发错误

demo 演示三种变量声明:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>JavaScript 变量声明演示</title>
</head>
<body>
    <h1>JavaScript 变量声明演示</h1>
    
    <h2>使用 var</h2>
    <script>
        var name = "Alice"; // 在全局声明
        function greet() {
            var name = "Bob"; // 在函数内声明
            console.log("函数内的 name:", name); // 输出: Bob
        }
        greet(); // 调用函数
        console.log("全局的 name:", name); // 输出: Alice
    </script>

    <h2>使用 let</h2>
    <script>
        let age = 30; // 在块外声明
        if (true) {
            let age = 25; // 在块内声明
            console.log("块内的 age:", age); // 输出: 25
        }
        console.log("块外的 age:", age); // 输出: 30
    </script>

    <h2>使用 const</h2>
    <script>
        const pi = 3.14; // 声明常量
        // pi = 3.15; // 取消注释将会报错,常量不能重新赋值
        console.log("常量 pi:", pi); // 输出: 3.14
    </script>
</body>
</html>
JavaScript

基本操作

运算符

算术运算符

let sum = 5 + 10; // 加法
let diff = 10 - 5; // 减法
let product = 5 * 2; // 乘法
let quotient = 10 / 2; // 除法

比较运算符

let a = 5;
let b = 10;
console.log(a == b); // 结果为 false
console.log(a === 5); // 严格比较(类型和值都相同)

逻辑运算符

let isTrue = (a < b) && (b > 5); // 结果为 true
let isEither = (a < b) || (b < 5); // 结果为 true
let notA = !isTrue; // 结果为 false

条件语句

if-else

let score = 85;
if (score >= 90) {
    console.log("优秀");
} else if (score >= 75) {
    console.log("良好");
} else {
    console.log("需努力");
}

switch

let day = 2;
switch (day) {
    case 1:
        console.log("今天是周一");
        break;
    case 2:
        console.log("今天是周二");
        break;
    default:
        console.log("今天是周末");
}

循环语句

for 循环:

for (let i = 0; i < 5; i++) {
    console.log(i); // 输出 0 到 4
}

while 循环:

let count = 0;
while (count < 5) {
    console.log(count);
    count++;
}

do while 循环(至少会执行一遍):

let num = 0;
do {
    console.log(num);
    num++;
} while (num < 5);

demo演示基本操作:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>JavaScript 基本操作示例</title>
</head>
<body>

    <h1>JavaScript 基本操作示例</h1>

    <h2>运算符</h2>
    <script>
        // 算术运算
        let sum = 5 + 10; // 加法
        let diff = 10 - 5; // 减法
        console.log("加法结果:", sum);  // 输出: 15
        console.log("减法结果:", diff); // 输出: 5

        // 比较运算
        let a = 5;
        let b = 10;
        console.log(a == b); // 输出: false
        console.log(a === 5); // 输出: true
    </script>

    <h2>条件语句</h2>
    <script>
        let score = 85;
        if (score >= 90) {
            console.log("优秀");
        } else if (score >= 75) {
            console.log("良好"); // 输出: 良好
        } else {
            console.log("需努力");
        }
    </script>

    <h2>循环语句</h2>
    <script>
        // for 循环
        for (let i = 0; i < 5; i++) {
            console.log(i); // 输出: 0, 1, 2, 3, 4
        }
        
        // while 循环
        let count = 0;
        while (count < 5) {
            console.log(count); // 输出: 0, 1, 2, 3, 4
            count++;
        }
    </script>

</body>
</html>
JavaScript

函数

函数声明:

function greet() {
    console.log("Hello!");
}
greet(); // 调用函数

特点

  • 提升(Hoisting):函数声明会被提升到作用域的顶部,无论它在代码中的位置如何,您都可以在函数声明之前调用该函数。
  • 语法清晰:语法直观,容易理解。

函数表达式:

const greet = function() {
    console.log("Hello!");
};
greet(); // 调用函数

特点

  • 不提升:函数表达式不会被提升,因此必须在函数定义之后调用,否则会导致 TypeError
  • 匿名函数:在示例中,函数没有名字(匿名函数),也可以是命名函数。
  • 可以作为变量赋值:可以将函数赋值给变量、对象属性或数组元素。

箭头函数(ES6引入)

箭头函数:

const greet = () => {
    console.log("Hello, World!");
};
greet();

特点

  • 不提升:函数表达式不会被提升,因此必须在函数定义之后调用,否则会导致 TypeError
  • 匿名函数:在示例中,函数没有名字(匿名函数),也可以是命名函数。
  • 可以作为变量赋值:可以将函数赋值给变量、对象属性或数组元素。

带参数的箭头函数:

const add = (x, y) => x + y; // 简写
console.log(add(5, 3)); // 输出 8

特点

  • 简写形式:箭头函数在只有一条返回语句时可以省略 {} 和 return 关键字。
  • 可以定义多个参数:使用括号包裹参数。

作用域

作用域

  • 全局作用域:在任何函数外部声明的变量。
  • 函数作用域:在函数内部声明的变量只能在该函数内访问。
  • 块作用域:使用 let 和 const 声明的变量在其所在的块内有效。

1. 全局作用域

定义:全局作用域是任何代码块外部的作用域。变量在全局上下文中声明后就可以在整个代码中访问。

举例

let globalVariable = "I am global";

function showGlobal() {
    console.log(globalVariable); // 可以访问到全局变量
}

showGlobal(); // 输出: I am global
console.log(globalVariable); // 输出: I am global

2. 函数作用域

定义:函数作用域是指在函数内部声明的变量,这些变量只能在函数内部访问。使用 varfunction 或 let 在函数内部声明的所有变量都是函数作用域的。

举例

function myFunction() {
    var functionScoped = "I am inside a function";
    console.log(functionScoped); // 输出: I am inside a function
}

myFunction();
// console.log(functionScoped); // 会报错: ReferenceError: functionScoped is not defined

3. 块作用域

定义:块作用域是指在 ifforwhile 等语句的 {} 中声明的变量,只能在该块内部访问。使用 let 和 const 声明的变量具有块作用域。

举例

if (true) {
    let blockScoped = "I am inside a block";
    console.log(blockScoped); // 输出: I am inside a block
}

// console.log(blockScoped); // 会报错: ReferenceError: blockScoped is not defined

4. 作用域的优先级

优先级:JavaScript 在查找变量时遵循自上而下的规则:

示例

let name = "Alice"; // 全局作用域

function greet() {
    let name = "Bob"; // 函数作用域
    console.log("Inside function:", name); // 输出: Bob

    if (true) {
        let name = "Charlie"; // 块作用域
        console.log("Inside block:", name); // 输出: Charlie
    }

    console.log("After block:", name); // 输出: Bob
}

greet();
console.log("Global scope:", name); // 输出: Alice

5. 变量提升

定义:在 JavaScript 中,变量声明(使用 var)会被提升到所在函数的顶部。可以在变量声明之前使用该变量,但其值为 undefined

示例:

function example() {
    console.log(x); // 输出: undefined,变量被提升,但尚未赋值
    var x = 5;
    console.log(x); // 输出: 5,变量的值已经被赋值
}

example();
  • 在函数 example 中,变量 x 的声明 var x; 被提升到函数顶部。
  • 当第一次调用 console.log(x); 时,x 已经"存在"于作用域中,但由于尚未赋值,所以输出 undefined
  • 当 x 被赋值之后,第二个 console.log(x); 输出 5

复杂数据类型处理

一、数组(Array)的操作

1. 创建数组

let arr1 = [1, 2, 3]; // 直接创建
let arr2 = new Array(4, 5, 6); // 使用构造函数
let arr3 = []; // 空数组

2. 增加元素

let arr = [1, 2];

// 末尾添加
arr.push(3); // [1, 2, 3]

// 开头添加
arr.unshift(0); // [0, 1, 2, 3]

3. 删除元素

let arr = [0, 1, 2, 3];

// 删除末尾元素
arr.pop(); // 返回 3,数组变为 [0, 1, 2]

// 删除开头元素
arr.shift(); // 返回 0,数组变为 [1, 2]

4. 修改元素

let arr = [10, 20, 30];
arr[1] = 99; // 修改第二个元素
console.log(arr); // [10, 99, 30]

5. 遍历数组

let arr = ['apple', 'banana', 'cherry'];

// for
for (let i = 0; i < arr.length; i++) {
  console.log(arr[i]);
}

// forEach
arr.forEach((item, index) => {
  console.log(index, item);
});

6. 查找与筛选

let arr = [5, 12, 8, 130, 44];

let found = arr.find(x => x > 10); // 找到第一个 > 10 的
console.log(found); // 12

let filtered = arr.filter(x => x > 10); // 所有 > 10 的
console.log(filtered); // [12, 130, 44]

7. 其他常用方法

let arr = [1, 2, 3];

// 合并
let arr2 = arr.concat([4, 5]); // [1,2,3,4,5]

// 截取
let sliced = arr2.slice(1, 4); // [2,3,4]

// 修改(删除/添加)
arr2.splice(1, 2, 99, 100); // 从第1位删2个,插入两个新值
console.log(arr2); // [1, 99, 100, 4, 5]

// 排序
arr2.sort((a, b) => a - b); // 升序
console.log(arr2);

// 反转
arr2.reverse();

二、对象(Object)的操作

1. 创建对象

let person = {
  name: "Alice",
  age: 25
};

let person2 = new Object(); // 空对象
person2.name = "Bob";

2、访问属性

console.log(person.name); // 点语法
console.log(person['age']); // 方括号语法

3. 添加/修改属性

person.gender = 'female'; // 添加
person.age = 26; // 修改

4. 删除属性

delete person.gender;

5. 遍历对象属性

for (let key in person) {
  console.log(key, person[key]);
}

// 或者用 Object.keys / Object.entries
Object.entries(person).forEach(([key, value]) => {
  console.log(`${key}: ${value}`);
});

6. 判断属性是否存在

console.log('name' in person); // true
console.log(person.hasOwnProperty('age')); // true

7. 对象拷贝(浅拷贝)

let copy = { ...person }; // 使用扩展运算符
let copy2 = Object.assign({}, person);

8. 嵌套对象 & 访问

let user = {
  id: 1,
  profile: {
    username: 'jack',
    email: 'jack@example.com'
  }
};

console.log(user.profile.username); // 嵌套访问

DEMO 示例

let students = [
  { id: 1, name: 'Tom', score: 80 },
  { id: 2, name: 'Jerry', score: 92 },
  { id: 3, name: 'Lucy', score: 76 }
];

// 筛选出分数大于 80 的学生
let topStudents = students.filter(stu => stu.score > 80);

// 提取名字组成数组
let names = students.map(stu => stu.name);

// 查找 id 为 2 的学生
let student2 = students.find(stu => stu.id === 2);

console.log(topStudents);
console.log(names);
console.log(student2);

数据类型转换和拼接

类型转换

隐式转换(自动转换)

字符串拼接(String + anything → String)

console.log('5' + 1);  // "51"
console.log('5' + true); // "5true"

运算符会触发数字转换

console.log('5' - 1);  // 4
console.log('5' * 2);  // 10
console.log(true + 1); // 2 (true → 1)

布尔转换:

if, while, 三元运算符、逻辑判断中会自动进行布尔转换:

if ("hello") { console.log("这是真的"); }  // 执行
if (0) { console.log("不会执行"); }        // 不执行

tips:下是会被当作 false 的值(称为 假值):false, 0, ''(空字符串), null, undefined, NaN

显式转换(手动转)

转换为字符串:

String(123);    // "123"
123..toString(); // "123"  注意:要两个点(或者加括号)
true.toString(); // "true"

转换为数字:

Number("123");   // 123
Number(true);    // 1
parseInt("42px") // 42 (遇到非数字字符停止)
parseFloat("3.14abc") // 3.14
+"123"           // 123 (一元运算符 + 也能转数字)

转换为布尔值:

Boolean(1);     // true
Boolean(0);     // false
Boolean("abc"); // true
Boolean("")     // false

拼接(Concatenation)

1. 用 + 操作符拼接

let name = "张三";
let age = 25;
console.log("我叫 " + name + ",今年 " + age + " 岁");

只要有一个是字符串,其他的都会转换成字符串。

2. 用模板字符串

反引号 ` ` 包裹,${} 插入变量,非常直观。

let name = "张三";
let age = 25;
console.log(`我叫 ${name},今年 ${age} 岁`);

DOM 操作

一、什么是 DOM

DOM 是 “文档对象模型”(Document Object Model)的缩写,是 浏览器提供的一套 API,让你可以用 JavaScript 操作 HTML 页面中的内容、结构、样式等。

你可以想象 DOM 把网页看作一个「树状结构」,每个 HTML 标签都是一个「节点(Node)」,我们可以通过 JS的内置对象 document 去访问和操作这些节点。

二、选择器(获取 HTML 元素)

1. getElementById(id)(通过 id 获取元素)

html:
<div id="box">内容</div>

js:
let box = document.getElementById('box');
console.log(box);  // 打印该 DOM 元素

2. getElementsByClassName(className)(获取所有某个 class 的元素,返回 HTMLCollection)

html:
<p class="item">A</p>
<p class="item">B</p>

js:
let items = document.getElementsByClassName('item');
console.log(items[0].textContent); // A

3. querySelector(selector)(使用 CSS 选择器,返回第一个匹配元素)

html:
<div class="box">Hello</div>

js:
let el = document.querySelector('.box');  // 获取 class 为 box 的第一个元素

4. querySelectorAll(selector)(返回所有匹配元素 NodeList)

let els = document.querySelectorAll('.item');  // 返回类名为 item 的所有元素
els.forEach(el => console.log(el.textContent));

三、修改元素内容和样式

1. innerHTML vs textContent

html:
<div id="demo">原始内容</div>

js:
let demo = document.getElementById('demo');
demo.innerHTML = "<strong>加粗</strong>";   // 插入 HTML 内容
demo.textContent = "纯文本";               // 插入纯文本,标签不会生效

2. 修改元素样式(style)

let box = document.getElementById('box');
box.style.color = 'red';          // 设置字体颜色
box.style.backgroundColor = 'yellow'; // 设置背景色

注意:CSS 中的 background-color 在 JS 中写成 backgroundColor(驼峰式写法)。

四、添加、删除、创建元素

假设我们有一张网页,HTML 是这样的:

<!DOCTYPE html>
<html>
<head>
  <title>DOM 操作示例</title>
</head>
<body>
  <div id="container">
    <div id="box">我是原来的元素</div>
  </div>
</body>
</html>

你的目标:

  1. 创建一个新的 <div> 元素
  2. 把它插入到 <body><container>
  3. 把已有的 #box 元素删除掉

1. createElement(tag):创建新元素

let newDiv = document.createElement('div');
newDiv.textContent = "我是新创建的";

解释:

  • 你就像用 JavaScript 创建了一个新的 HTML 标签。
  • 这时候它还没放进页面里,就像你手上拿了个卡片,还没贴到网页上。

2. appendChild(node):插入元素

document.body.appendChild(newDiv);  // 把刚才创建的 <div> 插入到 body 最后

或者:

let container = document.getElementById('container');
container.appendChild(newDiv);  // 把它加进 container 里

页面上就会多出一句话:"我是新创建的内容"

3. removeChild(node):删除页面上的一个已有元素

假设我们现在想删除旧的 #box 元素:

let parent = document.getElementById('container');  // 找到父元素
let child = document.getElementById('box');         // 找到你要删的子元素
parent.removeChild(child);                          // 让父元素把子元素移除

注意:removeChild() 只能通过“父元素”来删除“它的子元素”。

示例代码一:

<!DOCTYPE html>
<html>
<head>
  <title>DOM 添加与删除</title>
</head>
<body>
  <div id="container">
    <div id="box">我是原来的元素</div>
  </div>

  <button onclick="addNewDiv()">添加新元素</button>
  <button onclick="removeOldBox()">删除旧元素</button>

  <script>
    function addNewDiv() {
      let newDiv = document.createElement('div');  // 创建
      newDiv.textContent = "✅ 我是新创建的内容";  // 设置内容
      document.getElementById('container').appendChild(newDiv); // 插入
    }

    function removeOldBox() {
      let parent = document.getElementById('container');
      let child = document.getElementById('box');
      if (child) {
        parent.removeChild(child);  // 删除旧元素
      }
    }
  </script>
</body>
</html>
  • 点击“添加新元素”按钮,会在页面加一行
  • 点击“删除旧元素”按钮,会把 “我是原来的元素” 那一行删除

总结:

  • createElement → 只是造个 DOM 盒子,还没放到页面
  • appendChild → 把这个盒子贴到页面上的某个位置
  • removeChild → 把已有的某个盒子从页面中拿掉

示例代码二:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>DOM 操作演示</title>
  <style>
    body {
      font-family: Arial, sans-serif;
    }
    li {
      cursor: pointer;
      padding: 6px;
    }
    li:hover {
      background-color: #eee;
    }
  </style>
</head>
<body>

  <h2>📋 我的列表</h2>
  <ul id="myList">
    <li>初始项 1</li>
    <li>初始项 2</li>
  </ul>

  <button onclick="addItem()">➕ 添加新项</button>
  <button onclick="removeLastItem()">🗑 删除最后一项</button>

  <script>
    let count = 3; // 用于编号新项

    function addItem() {
      // 创建新 <li> 元素
      const newItem = document.createElement('li');
      newItem.textContent = `新增项 ${count++}`;
      newItem.style.color = 'blue';

      // 添加点击事件,这个等会儿讲
      newItem.addEventListener('click', () => {
        alert(`你点击了:${newItem.textContent}`);
      });

      // 加入列表
      document.getElementById('myList').appendChild(newItem);
    }

    function removeLastItem() {
      const list = document.getElementById('myList');
      const lastItem = list.lastElementChild;
      if (lastItem) {
        list.removeChild(lastItem);
      }
    }
  </script>

</body>
</html>
JavaScript
  • 点击“添加新项”,看它如何动态出现在列表中;
  • 点击“删除最后一项”,观察 removeChild() 是怎么工作的;
  • 点击任意一项,它会弹出提示内容,说明事件监听器 addEventListener 也生效了。

五、事件处理(响应用户操作)

事件让你能监听用户行为,比如点击、输入、悬停等。

1、常见事件类型

2. addEventListener() 添加事件监听器

事件功能
click点击按钮弹窗
mouseover鼠标悬停改变按钮颜色
mouseout鼠标移出恢复颜色
focus输入框获得焦点高亮边框
blur输入框失去焦点恢复边框
input实时显示输入框输入内容
submit提交表单时显示提示框并阻止刷新

2、demo

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>DOM 事件综合演示</title>
  <style>
    body {
      font-family: Arial;
      padding: 20px;
    }
    #hoverBtn {
      background-color: #f0f0f0;
      border: 1px solid #aaa;
      padding: 10px 20px;
      cursor: pointer;
    }
    #textInput:focus {
      border: 2px solid blue;
      outline: none;
    }
  </style>
</head>
<body>

  <h2>📌 DOM 事件综合示例</h2>

  <!-- 表单 -->
  <form id="myForm">
    <label for="textInput">输入框:</label>
    <input type="text" id="textInput" placeholder="输入点什么">
    <p>实时内容:<span id="liveOutput"></span></p>
    <br>
    <button type="submit">提交表单</button>
  </form>

  <br><br>

  <!-- 鼠标事件按钮 -->
  <button id="hoverBtn">鼠标事件按钮</button>

  <script>
    const input = document.getElementById('textInput');
    const output = document.getElementById('liveOutput');
    const hoverBtn = document.getElementById('hoverBtn');
    const form = document.getElementById('myForm');

    // ✅ input:实时监听输入内容
    input.addEventListener('input', function () {
      output.textContent = this.value;
    });

    // ✅ focus:获得焦点
    input.addEventListener('focus', function () {
      console.log('输入框获得焦点');
    });

    // ✅ blur:失去焦点
    input.addEventListener('blur', function () {
      console.log('输入框失去焦点');
    });

    // ✅ submit:提交表单
    form.addEventListener('submit', function (e) {
      e.preventDefault(); // 阻止默认刷新行为
      alert('表单已提交,输入值为:' + input.value);
    });

    // ✅ click:点击按钮
    hoverBtn.addEventListener('click', function () {
      alert('你点击了按钮!');
    });

    // ✅ mouseover:鼠标移入
    hoverBtn.addEventListener('mouseover', function () {
      this.style.backgroundColor = 'lightgreen';
    });

    // ✅ mouseout:鼠标移出
    hoverBtn.addEventListener('mouseout', function () {
      this.style.backgroundColor = '#f0f0f0';
    });
  </script>

</body>
</html>

测试说明:

操作效果说明
输入文字input 事件触发,实时显示文字
点击输入框focus 事件,边框变蓝
点别的地方blur 事件,边框恢复
点击提交按钮submit 事件,弹出输入内容(不刷新页面)
鼠标移到按钮上mouseover,背景变绿色
鼠标移出按钮mouseout,背景恢复
点击按钮click 事件,弹出提示
JavaScript

综合 demo

综合HTML+CSS+JS 的一个表单案例如下:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8"> <!-- 设置页面字符编码为UTF-8 -->
  <title>基础表单页面</title> <!-- 设置页面标题 -->
  <style>
    /* 设置页面整体字体、背景色和内边距 */
    body {
      font-family: Arial, sans-serif; /* 设置字体 */
      background-color: #f2f2f2; /* 设置背景颜色 */
      padding: 40px; /* 设置内边距 */
    }

    /* 表单容器,白色背景,内边距,圆角,最大宽度和居中 */
    .form-container {
      background: white; /* 背景颜色为白色 */
      padding: 30px; /* 内边距 */
      border-radius: 8px; /* 圆角效果 */
      max-width: 400px; /* 最大宽度 */
      margin: auto; /* 自动外边距以居中 */
      box-shadow: 0 4px 8px rgba(0,0,0,0.1); /* 轻微阴影效果 */
    }

    h2 {
      text-align: center; /* 将标题居中 */
    }

    /* 每个表单组之间的下间距 */
    .form-group {
      margin-bottom: 15px; /* 下间距 */
    }

    /* 标签统一设置为块级元素,加粗,底部有间距 */
    label {
      display: block; /* 块级元素 */
      font-weight: bold; /* 加粗 */
      margin-bottom: 5px; /* 底部间距 */
    }

    /* 给文本框、密码框、文件上传、文本域和下拉选择框设置统一样式 */
    input[type="text"],
    input[type="password"],
    input[type="file"],
    textarea,
    select {
      width: 100%; /* 宽度撑满容器 */
      padding: 8px; /* 内边距 */
      border: 1px solid #ccc; /* 灰色边框 */
      border-radius: 4px; /* 圆角 */
      box-sizing: border-box; /* 包含内边距和边框在宽度内 */
    }

    /* 性别和爱好那块,横向排列,间距10px */
    .form-group-inline {
      display: flex; /* 使用弹性布局 */
      gap: 10px; /* 间距 */
    }

    /* 内联标签字体不加粗 */
    .form-group-inline label {
      font-weight: normal; /* 不加粗 */
    }

    /* 提交按钮样式 */
    button {
      background-color: #4CAF50; /* 绿色背景 */
      color: white; /* 字体白色 */
      padding: 10px 15px; /* 内边距 */
      border: none; /* 去掉默认边框 */
      border-radius: 4px; /* 圆角 */
      cursor: pointer; /* 鼠标悬浮显示手指 */
    }

    /* 伪类选择器,按钮悬停时变深绿 */
    button:hover {
      background-color: #45a049; /* 悬停时变深绿色 */
    }

    /* 密码强度提示样式 */
    .password-strength {
      font-size: 0.9em; /* 字体略小 */
      color: gray; /* 字体颜色为灰色 */
    }
  </style>
  <script>
    // 页面加载完成时执行的函数
    window.onload = function() {
      const form = document.querySelector('form'); // 选择表单元素
      const hobbiesOutput = document.getElementById('hobbies-output'); // 用于显示爱好的区域
      const passwordInput = document.getElementById('password'); // 获取密码输入框
      const passwordStrength = document.createElement('div'); // 创建用于显示密码强度的div
      const fileInput = document.getElementById('avatar'); // 获取文件上传输入框

      // 插入密码强度提示
      passwordStrength.className = 'password-strength'; // 设置密码强度提示的类名
      passwordInput.parentElement.appendChild(passwordStrength); // 将其插入到密码输入框后面

      // 实时显示用户选中的爱好
      document.querySelectorAll('input[name="hobby"]').forEach(hobbyCheckbox => {
        hobbyCheckbox.addEventListener('change', updateHobbies); // 为每个爱好复选框注册事件
      });

      // 更新爱好显示的函数
      function updateHobbies() {
        const selectedHobbies = Array.from(document.querySelectorAll('input[name="hobby"]:checked')) // 获取所有选中的爱好复选框
          .map(hobby => hobby.value); // 将复选框的值映射到数组
        // 更新显示内容
        hobbiesOutput.textContent = selectedHobbies.length > 0 ? `您选择的爱好: ${selectedHobbies.join(', ')}` : '您未选择任何爱好';
      }

      // 密码复杂度提示
      passwordInput.addEventListener('input', function() {
        const passwordLength = this.value.length; // 获取当前密码长度
        let strengthMessage = '';

        if (passwordLength < 6) { // 如果密码长度小于6
          strengthMessage = '密码太短,至少需要6个字符'; // 提示密码太短
        } else {
          strengthMessage = '密码强度良好'; // 密码长度合格
        }
        passwordStrength.textContent = strengthMessage; // 更新密码强度提示内容
      });

      // 显示头像文件名
      fileInput.addEventListener('change', function() {
        const fileName = fileInput.files.length ? fileInput.files[0].name : '未选择文件'; // 获取文件名
        alert('您选择了文件: ' + fileName); // 弹出文件名
      });

      // 为表单添加提交事件监听器
      form.addEventListener('submit', function(event) {
        event.preventDefault(); // 预防表单的默认提交行为

        // 获取输入值
        const username = document.getElementById('username').value; // 获取用户名
        const password = document.getElementById('password').value; // 获取密码

        // 基本验证:检查用户名和密码是否为空
        if (username.trim() === '' || password.trim() === '') {
          alert('请填写用户名和密码!'); // 提示用户填写信息
          return;
        }

        // 如果输入有效,显示提交成功的消息
        alert('提交成功!用户名: ' + username + ', 密码: ' + password); // 弹出成功消息

        // 这里可以添加实际的表单提交逻辑,例如使用 AJAX
      });
    };
  </script>
</head>
<body>

  <div class="form-container">
    <h2>用户注册</h2> <!-- 注册表单的标题 -->
    <!-- 表单开始,提交时用POST方法发送 -->
    <form action="#" method="post">
      
      <!-- 用户名输入框组 -->
      <div class="form-group">
        <label for="username">用户名</label>
        <input type="text" id="username" name="username" required> <!-- 用户名输入框 -->
      </div>

      <!-- 密码输入框组 -->
      <div class="form-group">
        <label for="password">密码</label>
        <input type="password" id="password" name="password" required> <!-- 密码输入框 -->
      </div>

      <!-- 性别单选框组 -->
      <div class="form-group">
        <label>性别</label>
        <div class="form-group-inline">
          <label><input type="radio" name="gender" value="male"> 男</label> <!-- 男性选项 -->
          <label><input type="radio" name="gender" value="female"> 女</label> <!-- 女性选项 -->
        </div>
      </div>

      <!-- 爱好多选框组 -->
      <div class="form-group">
        <label>爱好</label>
        <div class="form-group-inline">
          <label><input type="checkbox" name="hobby" value="music"> 音乐</label> <!-- 音乐选项 -->
          <label><input type="checkbox" name="hobby" value="sports"> 运动</label> <!-- 运动选项 -->
          <label><input type="checkbox" name="hobby" value="reading"> 阅读</label> <!-- 阅读选项 -->
        </div>
        <div id="hobbies-output" style="margin-top: 5px; color: blue;">您未选择任何爱好</div> <!-- 用于显示已选择的爱好 -->
      </div>

      <!-- 个人简介多行文本输入框 -->
      <div class="form-group">
        <label for="bio">个人简介</label>
        <textarea id="bio" name="bio" rows="4"></textarea> <!-- 个人简介输入框 -->
      </div>

      <!-- 文件上传组 -->
      <div class="form-group">
        <label for="avatar">上传头像</label>
        <input type="file" id="avatar" name="avatar"> <!-- 文件上传输入框 -->
      </div>

      <!-- 提交按钮组 -->
      <div class="form-group">
        <button type="submit">提交</button> <!-- 提交按钮 -->
      </div>

    </form>
  </div>

</body>
</html>
JavaScript

这段代码实现了一个用户注册的基础表单,包含了用户名、密码、性别、爱好、多行文本输入以及文件上传等输入字段。通过 JavaScript,表单具有以下功能:

  1. 密码强度检测:在用户输入密码时实时反馈密码的强度。
  2. 爱好的实时反馈:用户选择不同的爱好后,会实时显示已选中的爱好。
  3. 头像文件上传:用户在上传头像后,会弹出提示框显示所选文件的名称。
  4. 表单验证:在提交表单时,检查用户名和密码是否为空,并阻止默认的提交行为以显示相关消息。

六、JS 定时器

在 JavaScript 中,定时器是一种用于安排在未来某个时间点执行代码的机制。JavaScript 提供了两个主要的定时器函数:

  1. setTimeout():用于在指定的延迟(以毫秒为单位)后执行一次指定的函数或代码片段。
  2. setInterval():用于按照指定的时间间隔(以毫秒为单位)重复执行指定的函数或代码片段。

1. setTimeout()

setTimeout()() 函数的基本语法如下:

let timerId = setTimeout(function, delay, arg1, arg2, ...);
  • function:要执行的函数。
  • delay:延迟时间(以毫秒为单位),在时间到达后执行。
  • arg1, arg2, ...:可选参数,传递给要执行的函数。

示例

// 执行一个简短的消息
setTimeout(() => {
    console.log("Hello after 2 seconds!");
}, 2000);

清除定时器

如果你希望取消延迟的执行,可以使用 clearTimeout() 函数。

let timerId = setTimeout(() => {
    console.log("This will not run");
}, 2000);

// 取消定时器
clearTimeout(timerId);

2. setInterval()

setInterval() 函数的基本语法如下:

let intervalId = setInterval(function, interval, arg1, arg2, ...);
  • function:要执行的函数。
  • interval:时间间隔(以毫秒为单位),重复执行的频率。
  • arg1, arg2, ...:可选参数,传递给要执行的函数。

示例:

// 每隔 1 秒打印消息
let count = 0;
let intervalId = setInterval(() => {
    console.log("This message appears every second");
    count++;
    if (count === 5) {
        clearInterval(intervalId); // 5 次后停止
    }
}, 1000);

3. 清除定时器
与 setTimeout() 一样,如果你希望停止正在进行的定时器,可以使用 clearInterval() 函数。

let intervalId = setInterval(() => {
    console.log("This will run indefinitely");
}, 1000);

// 停止定时器
clearInterval(intervalId);

4. 注意事项

  • 在 JavaScript 中,setTimeout() 和 setInterval() 的执行是异步的,这意味着它们不会阻塞主线程。
  • 由于 JavaScript 的事件循环机制,定时器的执行时间可能会有所推迟,尤其是在浏览器忙于处理其他任务时。

demo 示例:

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>计数器 Demo</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            background-color: #f0f8ff;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            flex-direction: column;
        }

        h1 {
            font-size: 48px;
            color: #333;
        }

        #counter {
            font-size: 36px;
            color: #007BFF;
            margin: 20px;
        }

        #stopButton {
            padding: 10px 20px;
            font-size: 16px;
            background-color: #FF5733;
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
        }

        #stopButton:hover {
            background-color: #C70039;
        }
    </style>
</head>
<body>

    <h1>简单计数器</h1>
    <div id="counter">0</div>
    <button id="stopButton">停止计数</button>

    <script>
        // 初始化计数器
        let count = 0;
        const counterDisplay = document.getElementById('counter');

        // 每秒更新计数器
        const intervalId = setInterval(() => {
            count++;
            counterDisplay.textContent = count;
        }, 1000);

        // 点击停止按钮时停止计数
        const stopButton = document.getElementById('stopButton');
        stopButton.addEventListener('click', () => {
            clearInterval(intervalId);
            stopButton.disabled = true; // 禁用按钮
            stopButton.textContent = '计数已停止'; // 改变按钮文本
        });
    </script>

</body>
</html>

代码解释

  1. HTML 结构
    • h1 标签用于显示标题。
    • div 标签用于显示当前的计数。
    • button 标签用于停止计数的按钮。
  2. CSS 样式
    • 基本的样式设置:背景颜色、字体、按钮样式等,使页面看起来更美观。
  3. JavaScript 部分
    • 使用 setInterval() 每秒更新计数器,增加 count 的值并将其显示在页面上。
    • 通过按钮点击事件 addEventListener,调用 clearInterval() 停止计时器,同时禁用按钮并修改其文本。
JavaScript

发布者:LJH,转发请注明出处:https://www.ljh.cool/42691.html

Like (0)
LJHLJH
Previous 2025年6月13日 上午11:24
Next 6天前

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注