diff --git "a/\346\235\216\346\231\250\346\273\224/200t.html" "b/\346\235\216\346\231\250\346\273\224/200t.html" new file mode 100644 index 0000000000000000000000000000000000000000..66b84131b28b70b71034203fb9b8e7df7d377f71 --- /dev/null +++ "b/\346\235\216\346\231\250\346\273\224/200t.html" @@ -0,0 +1,22 @@ + + + + + + Document + + + + + + + \ No newline at end of file diff --git "a/\346\235\216\346\231\250\346\273\224/20251110-\345\210\235\350\257\206JavaScript.md" "b/\346\235\216\346\231\250\346\273\224/20251110-\345\210\235\350\257\206JavaScript.md" new file mode 100644 index 0000000000000000000000000000000000000000..3dbf7efeda8f73ac91a40de78a424b1e84b0d29b --- /dev/null +++ "b/\346\235\216\346\231\250\346\273\224/20251110-\345\210\235\350\257\206JavaScript.md" @@ -0,0 +1,25 @@ +## 认识script +1. script(三种排列方式) +- 放在body里最下面(原因:网页先构建后渲染) +- 放在标签内(相当于行内样式) +- 放在外部js文件内(需要引用) +2. 代码 +- script(js祖师爷) +- alert(弹窗) +- function(可重复使用的代码块) +- onclick(事件处理方法) + +```bash +输出老子的名言 + + 无人扶我青云志,我自踏雪至山巅。 + + + +``` +效果展示: +![](https://gitee.com/ak-47-combustible-ice/pic-go/raw/master/20251110180825336.gif) \ No newline at end of file diff --git "a/\346\235\216\346\231\250\346\273\224/20251112-JavaScript\345\237\272\347\241\200.md" "b/\346\235\216\346\231\250\346\273\224/20251112-JavaScript\345\237\272\347\241\200.md" new file mode 100644 index 0000000000000000000000000000000000000000..b1711a9a83ecd2c947266e40cd04243630e39714 --- /dev/null +++ "b/\346\235\216\346\231\250\346\273\224/20251112-JavaScript\345\237\272\347\241\200.md" @@ -0,0 +1,153 @@ +# 笔记 + ## 数据类型 + +### 基本数据类型 + - 数值型 number + - 十进制 + - 十六进制 + - 八进制 + - 浮点型数据 + - 传统记数法 + - 1.23 + - 科学计数法 + - 123e-3 + - infinity 无穷 + - NaN 非数值 + - 字符串型 string + - 单引号 + - 双引号 + - 反引号 + - 转义字符 + | 转义字符 | 描述 | 转义字符 | 描述 | + | -------- | ------------------ | -------- | ------------------------- | + | \b | 退格 | \v | 垂直制表符 | + | \n | 换行符 | \r | Enter符 | + | \t | 水平制表符,Tab空格 | `\\` | 反斜杠 | + | \f | 换页 | \OOO | 八进制整数,范围为000~777 | + | \' | 单引号 | \xHH | 十六进制整数,范围为00~FF | + | \" | 双引号 | \uhhhh | 十六进制编码的Unicode字符 | + - 要将其放在`
`格式化文本中才会起作用
+      - 字符串拼接 
+  - 布尔值 boolean
+    - true 
+    - false
+  - 空值 null
+    - 空的或者不存在的值
+  - 未定义值 undefined
+    - 变量还没有赋值
+
+## 常量和变量
+  -  常量
+    - const
+  - 变量
+    - var
+    - let
+  - 变量命名规则
+    - 以字母、下划线、$开头
+    - 不能使用关键字
+    - 区分大小写
+    - 不能使用中文
+    - 不能使用特殊字符
+    - 不能使用数字开头
+
+## 运算符
+
+- 算术运算符
+  - `+ - * / % ++ --`
+  - 优先级
+    - `() -> ** -> * / % -> + - -> ++ --`
+    - 从左到右
+    - 优先级相同,从左到右
+    - () 优先级最高
+- 字符串运算符 
+  -  `+` 连接两个字符
+  -  `+=` 连接两个字符并赋值
+- 比较运算符
+  - `== != > < >= <=`
+  - `==` 比较值是否相等
+  - `===` 比较值和类型是否相等
+  - `!=` 比较值是否不相等
+  - `!==` 比较值和类型是否不相等
+  - `> < >= <=` 比较大小
+- 赋值运算符
+  - `=` 
+  - `+=`
+  - `-=`
+  - `*=`
+  - `/=`
+  - `%=`
+
+# 练习
+1. p25练习
+-
+```bash
+    document.write('珠穆朗玛峰的高度≈8848.86m
'); +``` + +- +```bash + document.write('E:\\JavaScript\\Code\\demo'); +``` + +2. p28练习 +- +```bash + let area = 17100000 + 'km' + '\u00B2'; + document.write(`俄罗斯的国土面积 ≈ ${area}`); +``` + +- +```bash + document.write('个人信息
'+'姓名:郭靖
'+'性别:男
'+'年龄:20
'+'身高:1.77m
'+'武功:九阴真经、降龙十八掌'); +``` + +3. p37 +- +```bash + var depositAmount = 100000; + var annualInterestRate = 0.0275; + var depositTerm = 3; + var totalPrincipalAndInterest = depositAmount+depositAmount*annualInterestRate*depositTerm; + document.write('本息合计='+totalPrincipalAndInterest); +``` + +- +```bash + var Grade = 65; + resuit = (Grade >= 60)?"及格":"不及格"; + document.write(resuit); +``` + +- +```bash + var topBase = 30; + var base = 50; + var Height = 30; + var trapezoidArea = ((topBase+base)*Height)/2; + document.write('梯形稻田的面积为:'+trapezoidArea); +``` + +4. p39 +- +```bash + document.write('
');
+    document.write('他强由他强, 清风抚山岗\n' + '他横任他横, 明月照大江\n' + '他自狠来他自恶,我自一口真气足\n' +'            ——《九阳神功》');
+    document.write('
'); +``` + +- +```bash + var monthlysalary = 6500; + var specialDeduction = 500; + var individualIncomeTaxThreshold = 5000; + var taxRate = 0.03; + var actualIncome = (monthlysalary-specialDeduction)-(monthlysalary-specialDeduction-individualIncomeTaxThreshold)*taxRate; + document.write('该员工的实际收入为' + actualIncome+'元'); +``` + +- +```bash + var year = 2024; + result = (year%4 == 0 && year%100 != 0)||(year%400 == 0)?'2月有29天':'2月有28天'; + alert(year+'年'+result); +``` \ No newline at end of file diff --git "a/\346\235\216\346\231\250\346\273\224/20251113-dmo.md" "b/\346\235\216\346\231\250\346\273\224/20251113-dmo.md" new file mode 100644 index 0000000000000000000000000000000000000000..55de0e7eb95d2ac34d992dbb7172ba0dd09b0e79 --- /dev/null +++ "b/\346\235\216\346\231\250\346\273\224/20251113-dmo.md" @@ -0,0 +1,145 @@ +# 笔记 + +## 逻辑运算符 + - 逻辑与 && + - 两个都为真则为真 + - 逻辑或 || + - 其中有一个为真则为真 + - 逻辑非 ! + - !true + +## 条件运算符 + - 语法 + - `条件 ? 表达式1 : 表达式2` + - 如果条件为真,则执行表达式1,否则执行表达式2 + +## 其他运算符 +- 逗号运算符 + - `a = 1, b = 2` + - 则结果为最后一个 +- typeof 运算符 + - 判断数据类型 + | 数据类型 | 返回值 | 数据类型 | 返回值 | + | --------- | --------- | -------- | -------- | + | 数值 | number | null | objec | + | 字符串 | string | 对象 | object | + | 布尔值 | object | 函数 | function | + | undefined | undefined | ----- | ---- | +- new运算符 + - 对象实例名称=new 对象类型(参数) + - 对象实例名称=new 对象类型 + +## 表达式 +- 算术表达式 +- 逻辑表达式 +- 字符串表达式 + +# 练习 +1. p55 +- +```bash + let number1; + let all = 0; + for (number1 = 1; number1 <= 1000; number1++) { + if (number1 % 65 != 0) { + continue; + } + all = all + number1; + } + document.write(all); +``` + +- +```bash +let row, piece; + document.write('尚未使用的卡位:
'); + for (row = 1; row <= 3; row++) { + for (piece = 1; piece <= 3; piece++) { + if (row == 1 && piece == 3) { + continue; + } + if (row == 3 && piece == 2) { + continue; + } + document.write('第' + row + '排' + '第' + piece + '个\n'); + if (row == 1 && piece == 2) { + document.write('
'); + } + if (row == 2 && piece == 3) { + document.write('
'); + } + } + } +``` + +2. p55实践与练习 +- +```bash + let bmi; + let bodyWeight; + let base = 2; + let manbmi= 23; + switch (base) { + case 1: + bmi = 'body<20'; + bodyWeight = '体重过轻'; + break; + case 2: + bmi = '20<=body<=25'; + bodyWeight = '体重适中'; + break; + case 3: + bmi = '25<=body<=30'; + bodyWeight = '体重过重'; + break; + case 4: + bmi = '30<=body<=35'; + bodyWeight = '肥胖'; + break; + case 5: + bmi = 'body>35'; + bodyWeight = '非常肥胖'; + break; + } + document.write('BMI:'+manbmi+'
'+'结果:'+bodyWeight); +``` + +- +```bash + let year; + let month; + document.write('请选择您的出生年月:'); + document.write(''); + document.write(''); +``` + +- +```bash +let row; + document.write(''); + document.write(''); + for (row = 1; row <= 100; row++) { + if (row % 10 == 0) { + document.write(``); + document.writeln("") + } + else{ + document.write(``); + } + } + document.write(''); + document.write('
${row}
${row}
'); +``` + diff --git "a/\346\235\216\346\231\250\346\273\224/20251114-\346\265\201\347\250\213\346\216\247\345\210\266\350\257\255\345\217\245.md" "b/\346\235\216\346\231\250\346\273\224/20251114-\346\265\201\347\250\213\346\216\247\345\210\266\350\257\255\345\217\245.md" new file mode 100644 index 0000000000000000000000000000000000000000..634025609c3eed79e8370eae89682c7ed0371d89 --- /dev/null +++ "b/\346\235\216\346\231\250\346\273\224/20251114-\346\265\201\347\250\213\346\216\247\345\210\266\350\257\255\345\217\245.md" @@ -0,0 +1,220 @@ +# 笔记 +## 一、条件判断语句(if/switch) +条件判断是实现“根据不同情况执行不同逻辑”的核心,分为 `if` 系列和 `switch` 分支,适用于不同场景。 + +### 1. if 条件判断(单/多条件) +#### 核心知识点 +- **单条件对比**:初始化基准值,通过多个 `if` 依次对比更新,是“找最值”的经典写法; +- **多区间判断**:通过多个独立 `if` 判断数值区间(如API污染等级),需确保区间无重叠,避免逻辑冲突; +- **语法**:`if (条件) { 满足条件执行的代码 }`,条件为布尔值(或隐式转换为布尔值)。 + +#### 练习要点 +- **最小值查找案例**: + 1. 初始化 `minValue = number1`(以第一个数为基准); + 2. 依次用 `if` 对比 `minValue` 与后续数字,更小则更新 `minValue`; + 3. 核心逻辑:**初始基准值 → 逐个对比 → 更新最值**,适用于任意数量的数值对比。 +- **API污染等级案例**: + 通过 `if` 判断 `api` 所在区间(0-100、101-200等),给 `sky` 赋值对应等级,注意区间边界(如 `0<=api&&api<=100`)需准确,避免漏判/错判。 + +### 2. switch 分支语句 +#### 核心知识点 +- **适用场景**:固定值匹配(如编码1-4对应春夏秋冬),比多个 `if` 更简洁、可读性更高; +- **核心语法**: + ```javascript + switch(匹配值) { + case 固定值1: 逻辑1; break; // break必须加,否则会“穿透”执行后续case + case 固定值2: 逻辑2; break; + default: 默认逻辑; // 可选,无匹配值时执行 + } + ``` +- **预处理技巧**:先通过 `if` 将复杂条件(如月份)转为固定编码,再用 `switch` 匹配,简化逻辑。 + +#### 练习要点 +- **月份判断季节案例**: + 1. 用 `prompt` 获取月份(注意:`prompt` 返回字符串,与数字 `==` 会隐式转换); + 2. 通过 `if` 将月份转为季节编码(3-5月→1、6-8月→2等); + 3. `switch` 匹配编码赋值季节,避免直接匹配多个月份,简化代码结构; + 4. 关键:`break` 不可省略,否则会执行后续 `case`(如漏写break会同时输出“春季”“夏季”)。 + +## 二、循环语句(do-while/for/嵌套for) +循环用于重复执行一段代码,不同循环类型适用于不同场景,核心是“控制循环次数/终止条件”。 + +### 1. do-while 循环 +#### 核心知识点 +- **执行逻辑**:**先执行循环体,再判断条件**,因此至少执行1次; +- **语法**:`do { 循环体 } while (条件);`; +- **适用场景**:需要确保“至少执行一次”的循环(如工资增长、初始化数据)。 + +#### 练习要点 +- **工资增长案例**: + 1. 初始化 `year=1`、`Salary=3000`; + 2. `do` 内先涨工资(`Salary += 50`)、年份+1(`year++`),再输出; + 3. `while (year <= 5)` 控制循环次数,最终输出第2-6年的工资(循环执行5次); + 4. 对比 `while` 循环:若初始 `year=6`,`while` 直接不执行,`do-while` 仍执行1次。 + +### 2. for 循环 +#### 核心知识点 +- **语法**:`for(初始化变量; 循环条件; 变量增量) { 循环体 }`,适合**已知循环次数**的场景; +- **枚举法思路**:通过循环枚举所有可能值,计算并验证是否符合条件(如鸡兔同笼); +- **变量作用域**:ES6中 `for` 初始化的 `let` 变量仅作用于循环内,避免全局污染。 + +#### 练习要点 +- **鸡兔同笼案例**: + 1. 枚举鸡的数量(`chicken` 从0到总头数`head`); + 2. 计算兔的数量(`rabbit = head - chicken`); + 3. 验证脚数(`chicken*2 + rabbit*4 == foot`),符合则输出结果; + 4. 核心:枚举法是解决“不定方程”的常用思路,通过遍历所有可能找到解。 + +### 3. 嵌套for循环(二维循环) +#### 核心知识点 +- **适用场景**:处理二维结构(如表格、座位表),**外层循环控制行,内层循环控制列**; +- **continue关键字**:跳过本次循环剩余代码,直接进入下一次循环(如标记“已售”座位); +- **动态表格生成**:通过 `document.write` 拼接 ``/``/`` 实现行换行; + 4. 样式优化:`style="text-align: center"` 让“已售”/座位号居中显示。 + +## 三、核心关键字 +| 关键字 | 作用 | 适用场景 | +|----------|----------------------------------------------------------------------|-------------------------| +| `break` | 终止整个循环/switch分支 | switch(必加)、循环终止 | +| `continue` | 跳过本次循环剩余代码,进入下一次循环 | 跳过特殊项(如已售座位) | + +--- + +### 总结 +1. **条件判断**:`if` 适合范围/逐个对比(找最值、区间判断),`switch` 适合固定值匹配(季节编码),switch必须加`break`防穿透; +2. **循环选择**:`do-while` 至少执行1次,`for` 适合已知次数/枚举法,嵌套for处理二维结构(座位表); +3. **实战思路**:找最值用“初始基准+逐个对比”,不定方程用枚举法,二维结构用嵌套for+continue处理特殊项。 + +# 练习 +1. p48 +- +```bash + let number1 = 26; + let number2 = 17; + let number3 = 10; + let number4 = 20; + let minValue = number1; + if (minValue > number2) { + minValue = number2; + } + if (minValue > number3) { + minValue = number3; + } + if (minValue > number4) { + minValue = number4; + } + document.write('当前数字中最小值为:'+minValue); +``` + +- +```bash + let api = 56; + let sky; + if (0<=api&&api<=100) { + sky='良好'; + } + if (101<=api&&api<=200) { + sky='轻度污染'; + } + if (201<=api&&api<=300) { + sky='中度污染'; + } + if (api>300) { + sky='重度污染'; + } + document.write('该城市空气污染程度'+sky); +``` + +- +```bash + let Month = prompt('当前月份为:') + let Season; + let code; + if (Month == 3 || Month == 4 || Month == 5) { + code = 1; + } + if (Month == 6 || Month == 7 || Month == 8) { + code = 2; + } + if (Month == 9 || Month == 10 || Month == 11) { + code = 3; + } + if (Month == 12 || Month == 1 || Month == 2) { + code = 4; + } + switch (code) { + case 1: + Season = '春季'; + break; + case 2: + Season = '夏季'; + break; + case 3: + Season = '秋季'; + break; + case 4: + Season = '冬季'; + break; + } + document.write('当前月份属于' + Season); +``` + +2. p53 +- +```bash + let year = 1; + let Salary = 3000; + do { + Salary += 50; + year++; + document.write('第'+year+'年的工资是:'+Salary+'元
'); + } while (year <= 5); +``` + +- +```bash + let head = 35; + let foot = 94; + let chicken; + let rabbit; + for(chicken=0;chicken<=head;chicken++){ + rabbit=head-chicken; + if(chicken*2+rabbit*4==foot) + { + document.write('鸡有'+chicken+'只'+'兔有'+rabbit+'只'); + } + } +``` + +3. p54万达影城 +- +```bash + let i, j; + document.write('
` 标签,实现二维结构渲染。 + +#### 练习要点 +- **万达影城座位案例**: + 1. 外层 `i`(1-4行)控制行数,内层 `j`(1-10座)控制列数; + 2. 特殊处理:`i==3 && j==5/6` 时,输出“已售”并 `continue`(跳过座位号输出); + 3. 换行处理:`j==10` 时,输出座位后拼接 `
'); + for (i = 1; i <= 4; i++) { + for (j = 1; j <= 10; j++) { + if (i == 3 && j == 5) { + document.write(''); + continue; + } + if (i == 3 && j == 6) { + document.write(''); + continue;//跳过本次循环 + } + if (j == 10) { + document.write(``); + document.write(''); + } + else { + document.write(``); + } + } + } + document.write('
已售已售${i + '行' + j + '座'}
${i + '行' + j + '座'}
'); +``` diff --git "a/\346\235\216\346\231\250\346\273\224/20251117-\345\207\275\346\225\260.md" "b/\346\235\216\346\231\250\346\273\224/20251117-\345\207\275\346\225\260.md" new file mode 100644 index 0000000000000000000000000000000000000000..e2a93c1d6c5911c5ec9aa7b51eeb22490bdd772a --- /dev/null +++ "b/\346\235\216\346\231\250\346\273\224/20251117-\345\207\275\346\225\260.md" @@ -0,0 +1,125 @@ +# 笔记 +## 一、函数的基础定义与调用 +函数是封装重复逻辑的核心语法,可实现代码复用、简化逻辑结构,是JavaScript的基础核心之一。 + +### 核心知识点 +1. **函数定义语法**: + ```javascript + function 函数名(形参1, 形参2, ...) { + // 函数体(要执行的逻辑) + } + ``` + - 形参:函数定义时的参数(如`address`函数的`province`),相当于函数内部的“占位变量”; + - 实参:函数调用时传入的具体值(如`address('福建省', '龙岩市', ...)`),按顺序给形参赋值。 +2. **函数调用**:`函数名(实参1, 实参2, ...)`,调用时会执行函数体代码,传递实参给形参。 +3. **多参数处理**:参数数量可自定义,调用时需保证实参和形参**顺序一致**,数量匹配(少传则对应形参为`undefined`)。 + +### 练习要点 +- 地址拼接函数案例:定义4个形参(省份、城市、区县、详细地址),调用时传入具体值,函数体内拼接并输出,核心体现“参数传递+逻辑封装”的基础用法。 + +## 二、函数的 return 返回值 +`return` 是函数的核心关键字,用于将函数内部的结果传递给外部,同时控制函数执行流程。 + +### 核心知识点 +1. **return 的两大作用**: + - 终止函数执行:函数遇到`return`会立即停止,后续代码不再执行; + - 返回数据:`return 数据` 将结果返回给函数调用者,外部可通过变量接收(如`let end = result();`); + - 无`return`:函数默认返回`undefined`。 +2. **绝对值实现的两种方式**: + - 手动判断(三元运算符):`number < 0 ? -number : number`,简化简单的`if-else`逻辑; + - 内置方法(推荐):`Math.abs(number)`,JavaScript内置绝对值方法,无需手动判断,更高效简洁。 +3. **三元运算符语法**:`条件 ? 满足条件返回值 : 不满足条件返回值`,适用于二选一的简单判断。 + +### 练习要点 +- 绝对值函数:两种写法对比,体现“手动封装”和“使用内置API”的差异,优先使用内置方法减少代码量; +- 两数比较函数:函数内通过`if`判断>、=、<三种情况,每种情况`return`对应的拼接字符串,外部接收返回值后输出,完整体现“函数内部处理→return返回→外部接收”的流程。 + +## 三、函数实战:数值比较与找最小值 +结合`prompt`取值、类型转换、条件判断,实现实用的数值处理函数。 + +### 核心知识点 +1. **prompt 取值的关键注意点**: + - `prompt()` 返回的是**字符串类型**,若需数值比较(如大小、加减),必须用`Number()`转换为数值类型; + - 不转换的坑:字符串比较是按字符编码(如`'10' < '2'` 结果为`true`),会导致逻辑错误。 +2. **三数找最小值的逻辑**: + - 用`if-else if-else`依次判断每个数是否小于另外两个,满足条件则`return`该数; + - 拓展优化:可直接使用内置方法`Math.min(num1, num2, num3)`,一行代码获取最小值,简化逻辑。 + +### 练习要点 +- 三数找最小值案例: + 1. 第一步:用`Number(prompt())`将输入的字符串转为数值(核心!否则比较结果错误); + 2. 第二步:通过`if-else if-else`判断哪个数最小,`return`对应数值; + 3. 第三步:外部接收返回值并输出,完成“输入→处理→输出”的完整流程; + 4. 边界兼容:即使有两个数相等(如1,1,2),`else`分支仍能正确返回最小值。 + +--- + +### 总结 +1. **函数基础**:定义时指定形参,调用时传实参,`return`返回结果(无return则返回undefined); +2. **数值处理**:`prompt`取值需用`Number()`转数值,绝对值优先用`Math.abs()`,最小值可手动判断或用`Math.min()`; +3. **逻辑简化**:简单二选一判断用三元运算符替代`if-else`,减少代码量,提升可读性。 + +# 练习 +1. p61 +- +```bash + function address(province,city,district,detailedAddress){ + document.write(province+city+district+detailedAddress); + } + address('福建省','龙岩市','新罗区','闽西职业技术学院'); +``` + +- +```bash +1. function numBer(number) { + return number < 0 ? -number : number; + } + document.write(numBer(-30)); + +2. function numBer(number) { + document.write(Math.abs(number)); + } + numBer(-30); +``` + +2. p62 +- +```bash + function result() { + let number1 = prompt('请输入第1个数'); + let number2 = prompt('请输入第2个数'); + if (number1 > number2) { + return `${number1}>${number2}`; + } + if (number1 == number2) { + return `${number1}=${number2}`; + } + if (number1 < number2) { + return `${number1}<${number2}`; + } + } + let end = result(); + document.write(end); +``` + +- +```bash + function minNumber() { + let number1 = Number(prompt('请输入第1个数')); + let number2 = Number(prompt('请输入第2个数')); + let number3 = Number(prompt('请输入第3个数')); + if (number1 < number2&&number1` 换行; + - 关键:`content` 仅统计目标数据,不依赖循环变量 `i`,实现精准的格式控制。 + +### 练习要点 +- 3和5倍数筛选案例: + 1. 先过滤出15的倍数(3和5的公倍数),再按“每7个换行”格式化输出; + 2. 核心:多条件层层过滤,独立计数器控制输出格式。 + +## 四、动态创建DOM(表格函数封装) +将创建表格的逻辑封装为参数化函数,实现“一次定义、多次复用”。 + +### 核心知识点 +1. **表格创建核心方法** + | 方法 | 作用 | 优势 | + |---------------------|--------------------------|--------------------------| + | `createElement('table')` | 创建表格元素 | 通用DOM创建方法 | + | `table.insertRow()` | 创建表格行 | 比 `createElement('tr')` 更便捷 | + | `tr.insertCell()` | 创建单元格 | 比 `createElement('td')` 更便捷 | +2. **参数化设计** + - 函数形参:行(r)、列(c)、宽(w)、高(h)、边框颜色(bc),调用时传不同值即可生成不同表格; + - 样式批量设置:`style.cssText` 一次性赋值多个样式,比逐个设置 `style.xxx` 高效; + - 必设样式:`border-collapse: collapse` 合并单元格边框,避免边框重复。 + +### 练习要点 +- 动态表格案例: + 1. 函数内先创建表格,设置参数化样式(宽、高、边框合并); + 2. 嵌套循环创建行和单元格,填充“行-列”文本,设置边框颜色; + 3. 最后将表格添加到 `body`,调用时仅需传参数(如 `createTable(5,6,'80%','300px','#666')`)即可生成表格。 + +--- + +### 总结 +1. **函数设计**:遵循单一职责,通用逻辑封装为独立函数,嵌套函数实现内部逻辑隔离; +2. **条件判断**:多区间用 `if-else if` 避免重复输出,嵌套条件处理特殊场景(2月天数),规避逗号运算符、类型转换等坑; +3. **循环筛选**:多条件层层过滤目标数据,独立计数器控制输出格式; +4. **DOM封装**:动态创建表格的逻辑参数化,通过函数实现灵活复用; +5. **核心易错点**:逗号运算符≠逻辑与、`prompt` 返回字符串未转数值、多 `if` 重复执行,需重点规避。 + +# 练习 +1. p63 +- +```bash + function money(supermarket, wash, clothing) { + return supermarket + wash + clothing; + } + function ending() { + let supermarketConsume = 199; + let washConsume = 156; + let clothingConsume = 165; + let total = money(supermarketConsume, washConsume, clothingConsume) + if (total >= 500) { + let all = total * 0.9; + return `客户总消费${total}元,满足满500元优惠条件!折后金额:${all}元`; + } else { + return `客户总消费${total}元,未满足满500元优惠条件,无折扣!`; + } + } + let result = ending(); + document.write(result); +``` + +- +```bash + function totalScore(chinese, math, english, scienceCombined) { + return chinese + math + english + scienceCombined; + } + function ending() { + let chineseScore = 108; + let mathScore = 115; + let englishScore = 126; + let scienceCombinedScore = 237; + let total = totalScore(chineseScore, mathScore, englishScore,scienceCombinedScore) + if (total >= 550) { + return `该学生总分为${total}分,满足满550分本科线条件`; + } else { + return `该学生总分为${total}分,不满足满550分本科线条件`; + } + } + let result = ending(); + document.write(result); +``` + +2. p69 +- +```bash + let inputName = prompt('账号:'); + let inputPassword = prompt('密码:'); + function login(name, password) { + if (inputName === name, inputPassword === password) { + document.write('登入成功'); + } else { + document.write('账号密码错误'); + } + } + login('mr', 'mrsoft'); +``` + +- +```bash + let content = 1; + for (i = 1; i <= 1000; i++) { + if (i % 3 == 0 && i % 5 == 0) { + if (content % 7 == 0) { + document.write(i+'
'); + }else{ + document.write(i); + } + content++ + } + } +``` + +3. p70实践与练习 +- +```bash + let input = prompt('请输入你的年龄'); + function age(number) { + if (number < 18) { + document.write('未成年'); + } + if (0 <= number && number <= 6) { + document.write('童年'); + } + if (7 <= number && number <= 17) { + document.write('少年'); + } + if (18 <= number && number <= 40) { + document.write('青年'); + } + if (41 <= number && number <= 65) { + document.write('中年'); + } + if (number >= 66) { + document.write('老年'); + } + } + age(input); +``` + +- +```bash + //1.(无嵌套) + let year = prompt('请输入年份'); + let mouth = prompt('请输入月份'); + let allday; + function ending() { + if (mouth == 1 || mouth == 3 || mouth == 5 || mouth == 7 || mouth == 8 || mouth == 10 || mouth == 12) { + allday = 31; + } + else if (mouth == 2) { + if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) { + allday = 29; + } + else { + allday = 28; + } + } + else { + allday = 30; + } + return `${year}年${mouth}月有${allday}天`; + } + let result = ending(); + document.write(result); + //2.(有嵌套) + // 主函数:接收年份和月份,返回该月天数结果 + function getMonthDays() { + // 1. 嵌套函数:判断是否为闰年(内部辅助函数,仅主函数内可用) + function isLeapYear(year) { + return (year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0); + } + + // 2. 接收用户输入(也可改为通过参数传入,更灵活) + let year = prompt('请输入年份'); + let month = prompt('请输入月份'); // 原代码拼写错误 mouth 改为 month + + // 3. 转换为数字类型(避免字符串比较导致的逻辑错误) + year = Number(year); + month = Number(month); + + // 4. 嵌套逻辑:计算当月天数 + function calculateDays() { + if (month === 1 || month === 3 || month === 5 || month === 7 || month === 8 || month === 10 || month === 12) { + return 31; + } else if (month === 2) { + // 调用内部嵌套的闰年判断函数 + return isLeapYear(year) ? 29 : 28; + } else { + return 30; + } + } + + // 5. 验证输入合法性(可选增强,避免无效输入) + if (isNaN(year) || isNaN(month) || month < 1 || month > 12 || year < 1) { + return '请输入有效的年份和月份!'; + } + + // 6. 执行计算并返回结果 + const allDay = calculateDays(); + return `${year}年${month}月有${allDay}天`; + } + + // 调用主函数并输出结果 + let result = getMonthDays(); + document.write(result); +``` + +- +```bash + function createTable(r, c, w, h, bc) { + let table = document.createElement('table'); + // 基础样式+参数赋值 + table.style.cssText = `width:${w};height:${h};border-collapse:collapse;margin:20px`; + // 循环创建行和单元格 + for (let i = 0; i < r; i++) { + let tr = table.insertRow(); + for (let j = 0; j < c; j++) { + let td = tr.insertCell(); + td.style.border = `1px solid ${bc}`; + td.textContent = `${i + 1}-${j + 1}`; + } + } + document.body.appendChild(table); + } + // 调用:5行6列,80%宽,300px高,#666边框 + createTable(5, 6, '80%', '300px', '#666'); +``` diff --git "a/\346\235\216\346\231\250\346\273\224/20251120-\345\257\271\350\261\241.md" "b/\346\235\216\346\231\250\346\273\224/20251120-\345\257\271\350\261\241.md" new file mode 100644 index 0000000000000000000000000000000000000000..85a7547793d1901fcd6fbab06638a46eaff33880 --- /dev/null +++ "b/\346\235\216\346\231\250\346\273\224/20251120-\345\257\271\350\261\241.md" @@ -0,0 +1,142 @@ +# 笔记 +## 一、Date 日期对象(时间差计算+实时时间获取) +Date 对象是 JavaScript 处理日期/时间的核心工具,高频用于时间差计算、实时时间展示等场景。 + +### 核心知识点 +1. **Date 对象的三种创建方式**: + | 创建方式 | 说明 | 注意点 | + |---------------------------|----------------------------------------------------------------------|---------------------------------| + | `new Date('2023-05-01')` | 字符串格式创建,直接指定年月日 | 部分浏览器兼容 `YYYY-MM-DD` 格式 | + | `new Date(年, 月, 日)` | 数值参数创建,需传入年、月、日(可选时/分/秒) | ⚠️ 月份是**0基**(0=1月,6=7月,11=12月) | + | `new Date()` | 无参创建,获取当前系统的实时时间 | 包含年/月/日/时/分/秒/毫秒 | +2. **时间戳与时间差计算**: + - 时间戳:`date.getTime()` → 获取从 1970-01-01 00:00:00 UTC 到该日期的**毫秒数**,是时间差计算的核心; + - 时间差:两个 Date 对象直接相减(或 `getTime()` 相减),结果为毫秒差; + - 单位转换公式(高频): + - 小时差 = 毫秒差 / 3600000(1小时 = 3600×1000 毫秒); + - 天数差 = 毫秒差 / (24×60×60×1000),用 `Math.ceil()` 向上取整(避免小数天数,如 100.2 天→101天); +3. **实时时间分量获取**: + - `date.getHours()`:获取当前小时(0-23); + - `date.getMinutes()`:获取当前分钟(0-59); + - `date.getSeconds()`:获取当前秒数(0-59)。 + +### 练习要点 +- 日期间隔小时数:用 `Math.abs(结束日期 - 开始日期)` 计算毫秒差(abs 避免负数),再转小时; +- 生日/高考天数计算:注意 `new Date(2023,6,7)` 实际是 2023年7月7日(月份+1),通过时间戳差转天数; +- 实时时分秒展示:无参 `new Date()` 获取当前时间,搭配 `getHours/minutes/seconds` 拆分时间分量。 + +## 二、鼠标事件对象(event)与按键判断 +通过事件对象可精准识别鼠标操作,实现交互反馈,是前端鼠标交互的基础。 + +### 核心知识点 +1. **鼠标事件绑定**:`document.onmousedown = 函数名` → 监听全局鼠标按下事件,点击页面任意位置触发; +2. **event 对象的 button 属性(按键判断)**: + - `e.button == 0`:鼠标左键; + - `e.button == 1`:鼠标中键(滚轮键); + - `e.button == 2`:鼠标右键; +3. **阻止默认行为**:`return false` → 阻止浏览器默认操作(如右键按下时弹出默认菜单)。 + +### 练习要点 +- 鼠标按键判断案例: + 1. 函数形参声明 `e` 接收事件对象; + 2. 判断 `e.button` 值,弹窗提示对应按键; + 3. 每个分支 `return false`,避免触发浏览器默认行为。 + +## 三、对象封装函数(模块化+随机数生成) +将功能逻辑封装到对象中,实现代码模块化、复用性提升,是前端工程化的基础思路。 + +### 核心知识点 +1. **对象字面量封装功能**: + - 格式:`let 对象名 = { 方法名: function(参数) { 逻辑 } }`; + - 示例:`RandomNumberGenerator` 对象封装“指定位数随机数生成”方法,代码更整洁、便于维护; +2. **随机数生成核心逻辑**: + - `Math.random()`:生成 0~1(不包含1)的随机小数; + - `Math.floor(Math.random()*6)+1`:生成 1~6 的随机整数(先乘6得0~6,floor 取整为0~5,+1得1~6); + - `Array.from({ length: n }, 回调)`:创建长度为 `n` 的数组,每个元素由回调函数生成(批量生成随机数); + - `join('')`:将数组转为字符串(如 `[1,2,3]` → `"123"`); +3. **参数校验**:`Number.isInteger(n)` 判断参数是否为整数,`n < 1` 时返回提示语,避免无效输入导致逻辑错误。 + +### 练习要点 +- 指定位数随机数生成: + 1. 先校验参数(必须是正整数),不满足则返回提示; + 2. 用 `Array.from` 生成指定位数的数组,每个元素是 1~6 的随机数; + 3. `join('')` 拼接数组为字符串,返回最终随机数; +- 优势:将随机数生成逻辑封装到对象中,可多次调用,且参数化设计支持灵活指定位数。 + +--- + +### 总结 +1. **日期处理**:Date 对象月份是0基,时间差计算先转毫秒差再做单位转换,`Math.ceil()` 处理天数向上取整; +2. **鼠标事件**:通过 `event.button` 判断按键,`return false` 阻止默认行为; +3. **模块化封装**:功能逻辑封装到对象中,随机数生成用 `Math.random()+Array.from` 实现批量生成,参数校验提升代码健壮性。 + +# 练习 +1. p89 +- +```bash + let time = { + startDate: new Date('2023-05-01'), + endDate: new Date('2023-06-01'), + getHours() { + let msDiff = Math.abs(time.endDate - time.startDate); + return msDiff / 3600000; + } + }; + let hours = time.getHours(); + document.write('开始日期与结束日期的间隔小时数:', hours); +``` + +- +```bash + let date1 = new Date(2023,6,7); + let date2 = new Date(2025,11,20); + let date3 = date2.getTime()- date1.getTime(); + let day = Math.ceil(date3/(24*60*60*1000)); + document.write("距离2023年高考已经过了"+day+"天"); +``` + +- +```bash + function gosite(e){ + if(e.button == 0){ + alert('您单击了鼠标左键'); + return false; + } + if(e.button == 1){ + alert('您单击了鼠标中键'); + return false; + } + if(e.button == 2){ + alert('您单击了鼠标右键'); + return false; + } + } + document.onmousedown=gosite; +``` + +2. p89实践与练习 +- +```bash + let number = Number(prompt('请输入要生成几位数')); + let RandomNumberGenerator = { + generate: function (n) { + if (!Number.isInteger(n) || n < 1) return '请输入正整数位数'; + return Array.from({ length: n }, () => Math.floor(Math.random() * 6) + 1).join(''); + } + }; + document.write(RandomNumberGenerator.generate(number)); +``` + +- +```bash + let date1 = new Date(1996, 6, 9); + let date2 = new Date(2025, 11, 20); + let date3 = new Date; + let date4 = date2.getTime() - date1.getTime(); + let day = Math.ceil(date4 / (24 * 60 * 60 * 1000)); + let hour = date3.getHours() + let minute = date3.getMinutes() + let second = date3.getSeconds() + document.write(`周星星从出生到现在已度过了
${day} 天>>>${hour}小时>>>${minute}分>>>{second}秒`); +``` + diff --git "a/\346\235\216\346\231\250\346\273\224/20251121-\346\225\260\347\273\204.md" "b/\346\235\216\346\231\250\346\273\224/20251121-\346\225\260\347\273\204.md" new file mode 100644 index 0000000000000000000000000000000000000000..118021eec027e65481b7971f1203a9152b9c9da8 --- /dev/null +++ "b/\346\235\216\346\231\250\346\273\224/20251121-\346\225\260\347\273\204.md" @@ -0,0 +1,27 @@ +# 笔记 + 1. 定义数组 + - 空数组: + ```bash + let arr = new Array();//定义一个空数组 + arr[0] = "html"; + arr[1] = "css"; + arr[2] = "js"; + ``` + + - 指定数组长度: + ```bash + let arr = new Array(3);//定义一个元素个数为3的数组 + arr[0] = 10; + arr[1] = 20; + arr[2] = 30; + ``` + + - 指定数组元素: + ```bash + let arr = new Array("张三","李四","王五");//定义一个包含3个元素的数组 + ``` + + - 直接定义数组: + ```bash + let arr = ["张三","李四","王五"];//直接定义一个包含3个元素的数组 + ``` \ No newline at end of file diff --git "a/\346\235\216\346\231\250\346\273\224/20251124-\346\225\260\347\273\2042.md" "b/\346\235\216\346\231\250\346\273\224/20251124-\346\225\260\347\273\2042.md" new file mode 100644 index 0000000000000000000000000000000000000000..23dfe3e0d258c010508a088987968c2aaf10bb76 --- /dev/null +++ "b/\346\235\216\346\231\250\346\273\224/20251124-\346\225\260\347\273\2042.md" @@ -0,0 +1,256 @@ +# 笔记 +## 一、数组及集合操作(核心:遍历、转换、排序、扩展) +数组是前端存储有序数据的核心结构,掌握其内置方法和扩展技巧是处理批量数据的关键。 + +### 核心知识点 +#### 1. 数组基础拼接/截取(concat、slice) +| 方法 | 作用 | 注意点 | +|---------------------|----------------------------------------------------------------------|---------------------------------| +| `arr1.concat(arr2)` | 合并多个数组,返回**新数组**,原数组不变 | 可合并多个参数(如`concat(arr2, arr3)`) | +| `arr.slice(start, end)` | 截取数组片段(含start,不含end),返回新数组 | start/end为索引,支持负数(-1=最后一位);无end则截取到末尾 | + +#### 2. 数组反转/转字符串(reverse、join) +- `arr.reverse()`:**原地反转**数组(修改原数组),返回反转后的数组; +- `arr.join(分隔符)`:将数组转为字符串,分隔符默认逗号(如`join(' ')`用空格分隔); +- 组合用法:先反转再join,实现数组元素反向拼接(如途经站→反向站)。 + +#### 3. 数组最大值获取(三种核心方式) +| 方式 | 实现逻辑 | 优缺点 | +|---------------------|--------------------------------------------------------------------------|---------------------------------| +| 原型扩展+遍历对比 | `Array.prototype.getMax = function(){ 遍历数组对比赋值 }` | 可校验非数字,兼容性强,代码稍多 | +| Math.max+展开运算符 | `Math.max(...arr)` | 极简(一行代码),仅适用于纯数字数组 | +| sort+slice截取 | `arr.sort().slice(最后一位索引)` | 注意:sort默认按**字符串排序**(数字需自定义比较器),练习中`sort()`未传参存在隐式坑 | + +#### 4. 数组高阶方法(map/sort/forEach/filter) +| 方法 | 作用 | 适用场景 | +|---------------------|----------------------------------------------------------------------|---------------------------------| +| `arr.map((item, index)=>{})` | 遍历数组,返回新数组(每个元素为回调返回值) | 数据结构转换(如品牌+份额转为对象数组) | +| `arr.sort((a,b)=>{})` | 排序,回调返回`b-a`降序/`a-b`升序 | 数字/对象属性排序(如按市场份额降序) | +| `arr.forEach((item, index)=>{})` | 遍历数组执行回调,无返回值 | 批量渲染(如动态生成表格行) | +| `arr.filter((item)=>{})` | 过滤数组,返回满足条件的新数组 | 数据筛选(如含0431的手机号) | + +### 练习要点 +- 途经站反向案例:`reverse()` 原地修改数组,需先`join`原数组,再反转后`join`; +- 品牌份额排序案例: + 1. `map` 将两个数组(品牌、份额)转为对象数组(含可排序的数值型份额); + 2. `sort((a,b)=>b.value - a.value)` 按份额降序; + 3. `forEach` 动态生成表格行,index+1 实现排名自增; +- 最大值获取注意:`sort()` 未传参时,数字数组会按字符串排序(如`[9,2]`排序后为`[2,9]`是巧合,`[10,2]`会排为`[10,2]`),数字排序必须传比较器。 + +## 二、String 对象操作(核心:查找、截取、转换、筛选) +String 对象封装了字符串的所有操作,是处理文本、校验、格式化的核心工具。 + +### 核心知识点 +#### 1. 字符串基础判断/查找 +- `str.length`:获取字符串长度(中文/符号均算1个长度,如“《天龙八部》”长度为6); +- `str.indexOf(字符)`:查找字符首次出现的索引(无则返回-1),用于简单校验(如邮箱@/.的位置); +- `str.includes(字符)`:判断是否包含指定字符,返回布尔值(比indexOf更直观,如筛选含0431的手机号)。 + +#### 2. 字符串截取/拆分 +- `str.substr(start, length)`:截取字符串(start起始索引,length截取长度),如`substr(0,10)`截取前10位; +- `str.split(分隔符)`:将字符串转为数组(分隔符为空则拆分为单个字符,如随机字符串拆分为字符数组)。 + +#### 3. 字符串实战技巧 +- **指定长度字符串筛选**:遍历数组+判断`str.length`,拼接符合条件的字符串; +- **随机字符串生成**: + 1. 定义字符池(如`0123456789ABCDEFG`); + 2. 循环6次,`Math.floor(Math.random() * 字符池长度)` 取随机索引; + 3. 拼接随机字符生成最终字符串; +- **数字千分位格式化(经典面试题)**: + 1. 数字转字符串→反转(便于从后往前加逗号); + 2. 遍历反转后的字符串,每3位添加逗号; + 3. 再次反转恢复顺序,得到千分位格式(如13625966→13,625,966)。 + +### 练习要点 +- 金庸小说筛选案例:判断字符串长度为6(《天龙八部》这类带书名号的四字书名,长度=6); +- 邮箱校验案例:通过`indexOf("@") == 3 && indexOf(".") == 8` 做简单位置校验(实际项目需正则,此为入门级校验); +- 千分位格式化核心:反转字符串后按3位分割,避免从前往后处理位数不足的问题。 + +--- + +### 总结 +1. **数组操作**: + - 基础方法(concat/slice/reverse/join)侧重数据拼接、截取、格式转换; + - 高阶方法(map/sort/forEach/filter)是批量数据处理的核心,需掌握回调函数的参数和返回值; + - 求最大值优先用`Math.max(...arr)`,sort排序必须传数字比较器。 +2. **字符串操作**: + - 查找用`includes`(布尔)/`indexOf`(索引),截取用`substr`,拆分用`split`; + - 实战技巧(随机字符串、千分位格式化)需结合循环+随机数+字符串反转; + - 简单校验可通过`indexOf`判断字符位置,复杂校验需正则(后续拓展)。 +3. **核心注意点**: + - `reverse()`/`sort()` 会修改原数组,需注意数据备份; + - `prompt`/数组元素若为字符串型数字,需转数值后再排序/计算。 + +# 练习 +## 数组及集合 +1. p104 +- +```bash + let arr1 = new Array("2025-11-24"); + let arr2 = new Array("星期一"); + document.write(arr1.concat(arr2)); +``` + +- +```bash + 1. Array.prototype.getMax = function () { + if (this.length === 0) { + console.warn('数组为空,无法获取最大值'); + return null; + } + let max = this[0]; + for(let i = 1;i max ?this[i]:max; + } + } + return max; + }; + let number = [5,7,6,3,9,2]; + let maxValue = number.getMax(); + document.write('数组中的最大值是:',maxValue); + + 2. Array.prototype.getMax = function(){ + return this.length ? Math.max(...this):null; + }; + let number = [5,7,6,3,9,2]; + document.write('数组中的最大值是:'+number.getMax()); + + 3. let arr1 = new Array(5,7,6,3,9,2); + let arr2 = arr1.sort(); + document.write('数组中的最大值是:'+arr2.slice(5,6)); +``` + +- +```bash + let arr1 = new Array(1,2,3,4,5,6); + document.write(arr1.slice(1,5)); +``` + +2. p116 +- +```bash + let arr1 = ["长春","昌图西","铁岭西","沈阳北","绥中北","北京"]; + let arr2= arr1.join(' '); + let arr3 = arr1.reverse(); + let arr4 = arr3.join(' '); + document.write(`途经站:${arr2}
`); + document.write(`反向站:${arr4}`); +``` + +- +```bash + + + + + + + +
排名品牌市场份额
+``` + +## String对象 +1. p127 +- +```bash + let arr = ["《雪山飞狐》", "《连城诀》", "《天龙八部》", "《射雕英雄传》", "《鹿鼎记》", "《笑傲江湖》", "《书剑恩仇记》", "《神雕侠侣》", "《倚天屠龙记》", "《碧血剑》"]; + let fourname = ""; + for (let i = 0; i < arr.length; i++) { + if (arr[i].length == 6) { + fourname += arr[i] + " " + } + } + document.write("四个字的书籍为:" + fourname); +``` +- +```bash + let contacts = [ + '1330431****', + '1567766****', + '1304316****', + '1526567****', + '1580433****', + '139****0431' + ]; + let resulet = contacts.filter(phone => phone.includes('0431')); + document.write('含有0431的手机号:
'); + resulet.forEach( + (phone, index) => { + document.write(`${index + 1}. ${phone}
`); + } + ); +``` +- +```bash + let number = '4006****66@qq.com'; + document.write('QQ号为:' + number.substr(0, 10)); +``` + +2. p128实践与练习 +- +```bash + let str = "abc@sina.com"; + if (str.indexOf("@") == 3 && str.indexOf(".") == 8) { + alert("此网站为有效邮箱网站"); + } else { + alert("此网站为无效邮箱网站"); + } +``` + +- +```bash + let charPool = '0123456789ABCDEFG'; + let randomStr = ''; + for (let i = 0; i < 6; i++) { + let randomIndex = Math.floor(Math.random() * charPool.length); + randomStr += charPool[randomIndex]; + } + let strArray = randomStr.split(''); + document.write('生成的6位随机字符串:', randomStr + '
'); + document.write('split()拆分后的数组:', strArray); +``` + +- +```bash + 1. (AI) + function formatNumber(num) { + // 将数字转为字符串并反转 + const str = num.toString().split('').reverse().join(''); + let result = ''; + // 每3位添加逗号 + for (let i = 0; i < str.length; i++) { + if (i > 0 && i % 3 === 0) { + result += ','; + } + result += str[i]; + } + // 再次反转恢复顺序并返回 + return result.split('').reverse().join(''); + } + + // 测试 + console.log(formatNumber(13625966)); // 输出:13,625,966 +``` \ No newline at end of file diff --git "a/\346\235\216\346\231\250\346\273\224/20251126-\346\255\243\345\210\231\350\241\250\350\276\276\345\274\217.md" "b/\346\235\216\346\231\250\346\273\224/20251126-\346\255\243\345\210\231\350\241\250\350\276\276\345\274\217.md" new file mode 100644 index 0000000000000000000000000000000000000000..a2e0944c1be4b89a9a059da87ddb974579b6db33 --- /dev/null +++ "b/\346\235\216\346\231\250\346\273\224/20251126-\346\255\243\345\210\231\350\241\250\350\276\276\345\274\217.md" @@ -0,0 +1,171 @@ +# 笔记 +- 字符串.match(正则) 返回匹配到的字符串 +- 字符串.replace(正则,'要替换的字符串') 返回替换后的完整字符串 +- 正则.exec(字符串) 返回匹配到的字符串、所在的位置,完整字符串 +- 正则.test(字符串) 返回匹配字符串的结果:true false +# 练习 +1. p144 +- +```bash + let str = "JavaScript从入门到精通"; + // - [A-Z] 匹配任意一个大写字母 + // - [a-z] 匹配任意一个小写字母 + // - (?=...) 是正向预查,用于匹配后面紧跟着的模式 + // - | 表示“或”逻辑 + let regex = /[A-Z](?=[a-z])|[a-z](?=[A-Z])/; + let hasAdjacentCase = regex.test(str); + document.write(`字符串"${str}"中是否存在大小写字母相邻的模式?${hasAdjacentCase}`); +``` + +- +```bash + let str = "1234-567"; + // - ^ 表示字符串的开始 + // - \d{4} 匹配 exactly 4 位数字 + // - - 匹配一个字面上的连字符 "-" + // - \d{3} 匹配 exactly 3 位数字 + // - $ 表示字符串的结束 + let regex = /^\d{4}-\d{3}$/; + let isValidFormat = regex.test(str); + document.write(`字符串"${str}"是否符合"4位数字-3位数字"的格式?${isValidFormat}`); +``` + +2. p147 +- +```bash + let originalStr = "aA12cD34eF56"; + // - [a-zA-Z] 是一个字符类,匹配任意一个英文字母(不区分大小写) + // - g 是全局匹配标志 (global),表示查找所有匹配项,而不是只找第一个 + let regex=/[a-zA-Z]/g; + let replacedStr = originalStr.replace(regex,"*"); + document.write(`原始字符串:${originalStr}
`); + document.write(`替换后字符串:${replacedStr}`); +``` + +- +```bash + let str = "一1按2我5帮8您"; + let result =str.split(/\d/); + document.write(result); +``` + +3. p147实践与练习 +- +```bash + 1. (AI) + + +

+ +``` + +- +```bash + 1. (AI) +
+ + +

+
+
+ + +

+
+ + +``` + +- +```bash + +
+ + +
姓名格式错误(2-10个汉字)
+ +

+ + + +
手机号格式错误(11位有效号码)
+ +

+ + +
+ + +``` + diff --git "a/\346\235\216\346\231\250\346\273\224/20251127-\345\274\202\345\270\270\345\244\204\347\220\206\345\217\212\351\253\230\347\272\247\347\274\226\347\250\213.md" "b/\346\235\216\346\231\250\346\273\224/20251127-\345\274\202\345\270\270\345\244\204\347\220\206\345\217\212\351\253\230\347\272\247\347\274\226\347\250\213.md" new file mode 100644 index 0000000000000000000000000000000000000000..af0cd76adf3ea90ad5926a6d14812b40e4d2c1a9 --- /dev/null +++ "b/\346\235\216\346\231\250\346\273\224/20251127-\345\274\202\345\270\270\345\244\204\347\220\206\345\217\212\351\253\230\347\272\247\347\274\226\347\250\213.md" @@ -0,0 +1,305 @@ +# 笔记 +## 一、错误处理(try-catch 语句) +### 核心知识点 +1. **作用**:捕获代码执行过程中的异常,避免程序崩溃,可自定义错误提示逻辑。 +2. **基础语法**: + ```javascript + try { + // 可能抛出错误的代码(如调用不存在的方法、参数错误等) + } catch (error) { + // 捕获错误并处理 + console.error("错误信息:", error); // 打印完整错误对象 + alert(`错误类型:${error.name}\n错误信息:${error.message}`); // 常用错误属性 + } + ``` +3. **error 对象关键属性**: + - `error.name`:错误类型(如 ReferenceError、TypeError 等); + - `error.message`:错误的具体描述信息。 + +### 练习要点 +- 即使代码逻辑本身无错误(如 `substr` 截取字符串),也可通过 try-catch 做“容错兜底”; +- 错误处理需兼顾控制台调试(`console.error`)和用户友好提示(`alert`)。 + +## 二、正则表达式(RegExp)- 表单验证 +### 核心知识点 +1. **基础用法**:`/正则规则/.test(待检测字符串)`,返回布尔值(匹配为 true,不匹配为 false)。 +2. **常用验证规则(高频)**: + | 验证场景 | 正则表达式 | 规则说明 | + |----------------|---------------------------|-------------------------------------------| + | 1-5 的数字 | `/^[1-5]$/` | 仅匹配 1、2、3、4、5 单个数字 | + | 用户名 | `/^[a-zA-Z]\w{3,15}$/` | 以字母开头,后跟 3-15 位字母/数字/下划线 | + | 密码 | `/^(?=.*[a-zA-Z])(?=.*\d).{6,20}$/` | 6-20 位,必须包含字母 + 数字 | +3. **手动抛错**:`throw "自定义错误信息"`,结合 try-catch 实现自定义验证逻辑。 + +### 练习要点 +- 表单验证需先校验输入合法性,不通过则清空结果、提示用户并终止函数(`return`); +- 密码正则中 `(?=.*xxx)` 是“正向预查”,确保包含指定字符类型。 + +## 三、ES6 类(class)与对象 +### 核心知识点 +1. **类的定义与实例化**: + ```javascript + class 类名 { + // 构造函数:初始化实例属性 + constructor(属性1, 属性2) { + this.属性1 = 属性1; + this.属性2 = 属性2; + } + // 类的方法(实例可直接调用) + 方法名() { + // 方法逻辑(可通过 this 访问实例属性) + } + } + // 实例化:创建类的具体对象 + const 实例名 = new 类名(参数1, 参数2); + ``` +2. **类的方法特性**:方法直接定义在类内部,无需加 `function` 关键字,所有实例共享方法逻辑。 + +### 练习要点 +- `constructor` 是类的“构造器”,必须通过 `new` 关键字实例化才能执行; +- 访问实例属性需用 `this.属性名`(类内部)或 `实例名.属性名`(类外部)。 + +## 四、原型(prototype)与原型方法 +### 核心知识点 +1. **构造函数 + 原型**(ES6 class 底层实现逻辑): + ```javascript + // 构造函数:定义实例属性 + function 构造函数名(属性) { + this.属性 = 属性; + } + // 原型方法:所有实例共享(节省内存) + 构造函数名.prototype.方法名 = function() { + // 方法逻辑(this 指向当前实例) + } + ``` +2. **核心优势**:原型上的方法不会在每个实例中重复创建,适合多个实例共用的逻辑(如计算圆的周长/面积)。 + +### 练习要点 +- ES6 `class` 是构造函数+原型的语法糖,本质仍基于原型链; +- 原型方法中 `this` 指向调用该方法的实例(如 `circle.perimeter()` 中 `this` 是 `circle`)。 + +## 五、DOM 操作实战 +### 1. 动态生成表格 +```javascript +// 核心步骤:创建元素 → 设置样式/内容 → 追加到页面 +const table = document.createElement('table'); // 创建表格 +table.style.border = '1px solid #000'; // 设置样式 +const tr = document.createElement('tr'); // 创建行 +const td = document.createElement('td'); // 创建单元格 +td.textContent = '单元格内容'; // 设置内容 +tr.appendChild(td); // 单元格追加到行 +table.appendChild(tr); // 行追加到表格 +document.body.appendChild(table); // 表格追加到页面 +``` +**要点**:生成前需校验参数(如行数/列数必须是大于0的整数),避免无效操作。 + +### 2. 表单交互(Enter 键提交) +```javascript +// 1. 定义提交函数 +function submitForm() { + // 获取输入框值 → 校验 → 业务逻辑 +} +// 2. 监听键盘按下事件 +document.addEventListener('keydown', (e) => { + if (e.key === 'Enter') { // 检测是否按下Enter键 + submitForm(); // 触发提交逻辑 + } +}); +``` +**要点**: +- 获取输入框值:`document.getElementById('id').value`; +- 只读输入框:``,禁止用户编辑。 + +--- + +### 总结 +1. **错误处理**:try-catch 捕获异常,利用 `error.name/message` 区分和提示错误,throw 可自定义验证错误; +2. **正则验证**:掌握表单常用正则(用户名/密码/数字),`test()` 方法做匹配检测; +3. **类与原型**:ES6 class 是原型的语法糖,构造函数初始化属性,原型方法实现实例共享逻辑; +4. **DOM 操作**:动态生成元素用 `createElement`+`appendChild`,表单 Enter 提交监听 `keydown` 事件。 + + +# 练习 +1. p155 +- +```bash + let str = "我喜欢JavaScript"; + try{ + let result = str.substr(2,5); + console.log("截取结果:",result); + }catch(error){ + alert("对象不支持此方法"); + console.error("原生错误:",error.message); + } +``` + +- +```bash + let str = "我喜欢JavaScript"; + try { + let result = str.substr(2,5); + console.log("截取结果",result);; + + } catch (error) { + alert(`错误类型:${error.name}\n错误信息:${error.message}`); + console.error("完整错误信息:",error); + + } +``` + +2. p157实践与练习 +- +```bash + 输入数字(1-5):
+ 结果:
+ + + +``` + +- +```bash + 用户名:
+ 密码:
+ + + +``` + +3. p166 +- +```bash + class Actor { + constructor(chineseName, pofession, representativeWorks, mainAchievements) { + this.chineseName = chineseName; + this.pofession = pofession; + this.representativeWorks = representativeWorks; + this.mainAchievements = mainAchievements; + } + } + let a = new Actor("小明","演员","小明历险记","神马也没有"); + document.write("中文名:"+a.chineseName); + document.write("
职业:"+a.pofession); + document.write("
代表作品:"+a.representativeWorks); + document.write("
主要成就:"+a.mainAchievements); +``` + +- +```bash + class Book { + constructor(bookTitle, type, price) { + this.bookTitle = bookTitle; + this.type = type; + this.price = price; + } + total() { + document.write("书名:" + this.bookTitle); + document.write("
类型:" + this.type); + document.write("
价格:" + this.price); + } + } + let b = new Book("不处思慕记","惊悚",999); + b.total(); +``` + +4. p170 +- +```bash + function Circle(radius) { + this.radius = radius; + } + Circle.prototype.bj = function () { + document.write("圆的半径为:" +this.radius); + } + Circle.prototype.perimeter = function () { + document.write("
圆的周长为:" + 2 * this.radius+"π"); + } + Circle.prototype.area = function () { + document.write("
圆的面积为:" + this.radius * this.radius +"π"); + } + let circle = new Circle(10); + circle.bj(); + circle.perimeter(); + circle.area(); +``` + +- +```bash + class Table { + // 生成表格核心方法:仅接收行数、列数,直接插入body + generateTable(rows, cols) { + // 基础参数校验 + if (!Number.isInteger(rows) || rows <= 0 || !Number.isInteger(cols) || cols <= 0) { + alert('行数和列数必须是大于0的整数'); + return; + } + // 创建表格并设置基础样式 + const table = document.createElement('table'); + table.style.border = '1px solid #000'; + table.style.borderCollapse = 'collapse'; + // 循环创建行和单元格 + for (let i = 0; i < rows; i++) { + const tr = document.createElement('tr'); + for (let j = 0; j < cols; j++) { + const td = document.createElement('td'); + td.style.border = '1px solid #000'; + td.style.padding = '5px'; + td.textContent = `${i + 1}-${j + 1}`; // 单元格默认内容:行号-列号 + tr.appendChild(td); + } + table.appendChild(tr); + } + // 插入页面body(固定容器,简化逻辑) + document.body.appendChild(table); + } + } + // 使用示例:生成5行6列表格 + new Table().generateTable(5, 6); +``` + +5. 表单提交以enter键为事件提交方式 +- +```bash + 用户名:
+ 密码:
+ + function submitForm() { + let user = document.getElementById('user').value; + let pwd = document.getElementById('pwd').value; + if (user && pwd) alert(`提交成功!\n用户名:${user}\n密码:${pwd}`); + else alert('请填写完整信息'); + } + + // 监听Enter键 + document.addEventListener('keydown', e => { + if (e.key === 'Enter') submitForm(); + }); +``` diff --git "a/\346\235\216\346\231\250\346\273\224/20251128-\347\204\246\347\202\271&\350\241\250\345\215\225\344\272\213\344\273\266.md" "b/\346\235\216\346\231\250\346\273\224/20251128-\347\204\246\347\202\271&\350\241\250\345\215\225\344\272\213\344\273\266.md" new file mode 100644 index 0000000000000000000000000000000000000000..95ac677418518ac8db9dd22507ec7f1ca3dbc567 --- /dev/null +++ "b/\346\235\216\346\231\250\346\273\224/20251128-\347\204\246\347\202\271&\350\241\250\345\215\225\344\272\213\344\273\266.md" @@ -0,0 +1,253 @@ +# 笔记 +## 一、鼠标事件处理 +### 核心知识点 +1. **常用鼠标事件**: + - `mouseover`:鼠标移入元素时触发; + - `mouseout`:鼠标移出元素时触发。 +2. **事件绑定方式(推荐)**: + ```javascript + // 获取目标元素 + const elem = document.getElementById('元素ID'); + // 绑定事件(addEventListener 支持为同一元素绑定多个同类型事件) + elem.addEventListener('事件名', function() { + // 函数内 this 指向触发事件的当前元素 + this.style.样式属性 = '样式值'; + }); + ``` +3. **核心特性**:事件处理函数中 `this` 默认为触发事件的DOM元素,可直接修改其样式/属性。 + +### 练习要点 +- 鼠标移入/移出图片时,通过修改 `border` 样式实现视觉反馈(如红色边框高亮); +- `addEventListener` 是更灵活的事件绑定方式,优于直接写在HTML标签上的事件属性(如 `onmouseover`)。 + +## 二、键盘事件处理 +### 核心知识点 +1. **常用键盘事件**: + - `keydown`:键盘按键按下时触发(可检测所有按键)。 +2. **事件对象关键属性**: + - `keyCode`:按键对应的ASCII码(如 67 对应字母 C/c,不区分大小写); + > 注意:`keyCode` 属于旧属性,现代开发推荐用 `event.key`(如 `event.key === 'c'`)。 +3. **全局键盘事件绑定**: + ```javascript + // 监听整个文档的按键操作 + document.onkeydown = 事件处理函数名; + ``` + +### 练习要点 +- 全局监听键盘按键,通过 `keyCode` 判断按下的具体按键(如 67 对应C),实现答题交互逻辑; +- `keyCode` 对大小写字母返回相同数值,如需区分大小写需结合 `event.shiftKey` 属性。 + +## 三、页面/窗口事件 +### 核心知识点 +1. **页面加载事件**: + - `onload`:页面(含图片、脚本等所有资源)完全加载后触发,绑定方式:`` 或 `window.onload = 函数`; + - 作用:确保代码在DOM/资源加载完成后执行,避免“获取不到元素”的错误。 +2. **窗口尺寸事件**: + - `onresize`:浏览器窗口大小改变时触发; + - 窗口尺寸获取: + ```javascript + window.innerWidth; // 可视区域宽度 + window.innerHeight; // 可视区域高度 + ``` +3. **Date 对象基础**: + - `new Date()`:创建包含当前系统时间的Date对象,直接打印会显示本地格式的时间字符串。 + +### 练习要点 +- `onload` 是页面初始化逻辑的常用入口(如加载完成后展示当前时间); +- `onresize` 可用于响应式开发,实时获取窗口尺寸并调整页面布局。 + +## 四、表单交互事件 +### 1. 焦点事件(focus/blur) +#### 核心知识点 +- `onfocus`:元素获取焦点时触发(如点击输入框); +- `onblur`:元素失去焦点时触发(如点击输入框外区域); +- `event.target`:事件对象的核心属性,指向触发事件的具体元素(无需通过ID获取,适配多元素复用函数)。 + +#### 练习要点 +- 利用焦点事件修改输入框边框样式(如获取焦点时红色粗边框),提升用户交互体验; +- `event.target` 替代 `getElementById`,减少硬编码ID,实现一个函数适配多个输入框。 + +### 2. 下拉选择框(select)交互 +#### 核心知识点 +- 下拉框结构:``)时触发,需绑定在 `
` 标签上; +- `window.confirm()`:弹出确认对话框,点击“确定”返回 `true`,“取消”返回 `false`; +- 重置控制:重置事件函数返回 `true` 执行重置,返回 `false` 阻止重置。 + +#### 练习要点 +- 重置前通过 `confirm` 询问用户,实现“确认重置”的交互逻辑,避免误操作; +- `onreset` 绑定在 `` 标签上,而非重置按钮本身。 + +--- + +### 总结 +1. **事件核心**:`addEventListener` 是推荐的事件绑定方式,`this`/`event.target` 可快速定位触发事件的元素; +2. **常用事件**:鼠标(mouseover/mouseout)、键盘(keydown)、页面(onload)、窗口(onresize)、表单(focus/blur/onreset); +3. **表单交互**:下拉框通过 `value` 获取选中值,重置事件可通过 `confirm` 控制执行,焦点事件优化输入框视觉反馈; +4. **辅助知识点**:`new Date()` 获取当前时间,`window.innerWidth/innerHeight` 获取窗口可视尺寸。 + + +# 练习 +1. p183 +- +```bash + + + +``` + +- +```bash + 中国的“国球”是()。
+ A.篮球 B.排球 C.乒乓球 D.羽毛球 + +``` + +2. p185 +- +```bash + + + +``` + +- +```bash + + + +``` + +3. p189 +- +```bash + + +
+ + +
+
+ + +
+
+ +``` + +- +```bash + + + + +``` + +- +```bash +
+
+ + +
+
+ + +
+
+ +
+
+ +``` \ No newline at end of file diff --git "a/\346\235\216\346\231\250\346\273\224/20251201-\347\274\226\350\276\221&\346\213\226\346\224\276\344\272\213\344\273\266.md" "b/\346\235\216\346\231\250\346\273\224/20251201-\347\274\226\350\276\221&\346\213\226\346\224\276\344\272\213\344\273\266.md" new file mode 100644 index 0000000000000000000000000000000000000000..c25069873ea187ae608a1bf3df8c9202e61c66c0 --- /dev/null +++ "b/\346\235\216\346\231\250\346\273\224/20251201-\347\274\226\350\276\221&\346\213\226\346\224\276\344\272\213\344\273\266.md" @@ -0,0 +1,262 @@ +# 笔记 +## 一、HTML5 拖放(Drag & Drop)机制 +拖放是HTML5新增的核心交互能力,可实现元素在页面内的拖拽+放置操作,是文件上传、模块排序等功能的基础。 + +### 核心知识点 +1. **开启拖拽**: + - 图片/链接默认可拖拽,普通元素(div/文本)需添加 `draggable="true"` 属性; + - 示例:`
可拖拽文本
`。 + +2. **拖放核心事件(分两类)**: + | 事件类型 | 触发时机 | 所属对象 | 关键操作 | + |----------------|---------------------------|----------------|---------------------------| + | `dragstart` | 开始拖拽元素时 | 拖拽源(被拖元素) | 存储拖拽数据(`dataTransfer`) | + | `dragenter` | 拖拽元素进入放置区时 | 放置区 | 阻止默认行为(允许放置) | + | `dragover` | 拖拽元素在放置区内移动时 | 放置区 | 阻止默认行为(核心!否则`drop`不触发) | + | `dragleave` | 拖拽元素离开放置区时 | 放置区 | 恢复放置区样式 | + | `drop` | 拖拽元素放置到放置区时 | 放置区 | 获取拖拽数据,执行放置逻辑 | + +3. **数据传递(dataTransfer 对象)**: + - 存储数据:`e.dataTransfer.setData('数据类型', 数据)`(常用 `text`/`text/plain` 类型); + - 获取数据:`e.dataTransfer.getData('数据类型')`; + - 示例:存储图片地址 `e.dataTransfer.setData('text', e.target.src)`。 + +4. **必做操作**:阻止默认行为 + 浏览器默认禁止元素被放置,因此需在 `dragenter`/`dragover` 中执行: + ```javascript + ev.preventDefault(); // 允许放置 + ev.stopPropagation(); // 防止事件冒泡(可选,视场景) + ``` + +### 练习要点 +1. 图片拖放案例: + - 用 `classList.add/remove('active')` 给放置区添加视觉反馈(如边框变色); + - 结合 `setTimeout` 实现页面标题的临时提示并自动恢复; +2. 文本拖放案例: + - 用 `data-text` 自定义属性存储文本,解耦HTML结构和业务数据; + - 放置后通过 `createElement` 动态创建元素,将拖拽内容插入页面; + - 批量绑定事件:`querySelectorAll` 获取所有可拖拽元素,遍历绑定 `dragstart`。 + +## 二、鼠标精细交互事件 +针对鼠标操作的细分事件,实现更精准的交互反馈。 + +### 核心知识点 +1. **鼠标移入/移出(无冒泡版)**: + - `mouseenter`:鼠标进入元素时触发(**不冒泡**,仅作用于当前元素); + - `mouseleave`:鼠标离开元素时触发(**不冒泡**); + > 区别于 `mouseover/mouseout`:后两者会冒泡(子元素触发时父元素也响应),`mouseenter/mouseleave` 更精准。 +2. **鼠标按下/松开**: + - `mousedown`:鼠标按键按下时触发(左键/右键/中键均可); + - `mouseup`:鼠标按键松开时触发; + - 组合使用可实现“按下变样式,松开恢复”的即时交互。 +3. **样式变换技巧**: + - `transform: scale(n)`:元素缩放(如 `scale(1.2)` 放大1.2倍); + - 恢复默认样式:给样式属性赋值空字符串(`style.transform = ''`)。 + +### 练习要点 +1. 鼠标移入缩放文本: + - `querySelectorAll` 批量获取同类元素,遍历绑定事件,实现“一处定义,多处生效”; + - 移入时修改颜色和缩放,移出时清空样式自动恢复初始状态; +2. 按钮按下/松开样式切换: + - 简单场景可直接在标签上绑定 `onmousedown/onmouseup`,复杂场景推荐 `addEventListener`; + - 按下时修改按钮背景色/文字色,松开时恢复。 + +## 三、状态切换(开关类)交互逻辑 +实现“关灯/开灯”这类二态切换的核心思路,是前端高频交互模式。 + +### 核心知识点 +1. **状态标记**:定义布尔变量(如 `let Cha = true`)作为状态开关; +2. **状态翻转**:`变量 = !变量`(如 `Cha = !Cha`),一行代码实现“开→关/关→开”; +3. **逻辑控制**:通过 `if/else` 判断状态,修改DOM样式/元素属性。 + +### 练习要点 +关灯/开灯案例核心逻辑: +```javascript +let Cha = true; // 初始状态:关灯前 +function change() { + let btn = document.querySelector('input[name="light"]'); + if (Cha) { + document.body.style.backgroundColor = 'black'; // 关灯:背景变黑 + btn.value = '开灯'; + } else { + document.body.style.backgroundColor = 'white'; // 开灯:背景变白 + btn.value = '关灯'; + } + Cha = !Cha; // 状态翻转,为下一次点击做准备 +} +``` + +--- + +### 总结 +1. **拖放功能**:需开启 `draggable="true"`,阻止 `dragenter/dragover` 默认行为,通过 `dataTransfer` 传递数据,`drop` 完成放置逻辑; +2. **鼠标交互**:`mouseenter/mouseleave` 精准处理移入移出(无冒泡),`mousedown/mouseup` 实现按下/松开的即时样式变化; +3. **状态切换**:布尔变量标记状态,`!变量` 翻转状态,结合条件判断实现开关类交互(如关灯/开灯)。 + + +# 练习 +1. p193 +- +```bash + + + + + +
拖放至此
+ + +``` + +- +```bash +

可拖拽文本

+ +
文本1
+
文本2
+
文本3
+ +
+ + +
+ 指定放置区域 +
+
+ + +``` + +2. p194实践与练习 +- +```bash +
鼠标移动改变
+ +``` + +- +```bash + + +``` + +- +```bash + + +``` \ No newline at end of file diff --git "a/\346\235\216\346\231\250\346\273\224/20251203-Document\345\257\271\350\261\241.md" "b/\346\235\216\346\231\250\346\273\224/20251203-Document\345\257\271\350\261\241.md" new file mode 100644 index 0000000000000000000000000000000000000000..b674cf4fedbee2824d305653c088cb1ae02b3400 --- /dev/null +++ "b/\346\235\216\346\231\250\346\273\224/20251203-Document\345\257\271\350\261\241.md" @@ -0,0 +1,240 @@ +# 笔记 +## 一、状态切换与页面样式动态修改 +### 核心知识点 +1. **布尔变量作为状态标记**:用单个布尔变量(如 `isDefault = true`)标记页面/元素的初始状态,是实现“切换类”交互的核心方式,适用于二态(开/关)切换场景。 +2. **状态翻转技巧**:`变量 = !变量`(如 `isDefault = !isDefault`),一行代码完成“开→关/关→开”的状态切换,无需重复写赋值逻辑,简化代码。 +3. **页面样式动态修改**: + - 修改 body 全局样式:`document.body.style.backgroundColor`(背景色)、`document.body.style.color`(文字色); + - 恢复默认样式:给样式属性赋值空字符串(`style.backgroundColor = ''`),自动回退到 CSS 定义的默认样式。 + +### 练习要点 +- 交互颜色案例:点击按钮切换 body 黑/白背景+文字色,核心逻辑是通过 `if/else` 判断布尔状态,执行不同样式赋值,最后翻转状态; +- 优势:仅需一个变量即可控制二态切换,逻辑简洁,无冗余条件判断。 + +## 二、Document 对象核心属性与方法 +### 核心知识点 +1. **Document 基础属性**: + - `document.URL`:获取当前页面的完整 URL 地址(包含协议、域名、路径等); + - 用法:`document.write('当前文档:'+document.URL)`,可快速打印页面地址,适用于调试或页面信息展示。 +2. **DOM 元素获取**: + - 精准获取(高频):`document.getElementById('元素ID')`,直接定位唯一元素; + - 批量获取:`document.querySelectorAll('选择器')`(类、标签、属性选择器等)。 + +### 练习要点 +- `document.write` 可直接向页面输出文本/变量,但注意:页面加载完成后使用会覆盖整个页面,仅适合简单展示、调试场景。 + +## 三、动态创建/添加 DOM 元素(文本/图片) +### 核心知识点 +1. **动态创建元素**: + - 创建文本元素:`document.createElement('p')`; + - 创建图片元素:`document.createElement('img')`。 +2. **元素属性/内容设置**: + - 文本内容:`元素.textContent = '文本'`(推荐,仅处理纯文本,避免 XSS 风险); + - 图片属性:`img.src = '图片地址'`、`img.alt = '替代文本'`(语义化,图片加载失败时显示); + - 添加类名:`元素.classList.add('类名')`,便于通过 CSS 统一控制样式。 +3. **元素添加到页面**:`父元素.appendChild(子元素)`,将创建的元素插入指定容器。 +4. **遍历添加控制**: + - 数组存储待添加内容(文本/图片地址); + - 计数器变量(如 `current = 0`):每次点击递增,控制添加顺序; + - 边界判断:`if (current < 数组.length)` 避免重复添加,遍历完成后给出提示(`alert`)。 + +### 练习要点 +1. 动态添加文字案例:数组 `texts = ['我', '儿', '子']` 存储文本,点击按钮逐个创建 `

` 标签并插入容器,计数器确保按序添加且不超界; +2. 动态添加头像案例:数组存储多张头像地址,创建 `` 时添加统一类名 `added-img` 便于样式控制,设置 `alt` 属性提升语义化。 + +## 四、下拉选择框 onchange 事件与主题切换 +### 核心知识点 +1. **select 核心事件**:`onchange`,当下拉框选中项变化时**即时触发**(无需点击按钮),是表单即时交互的常用事件。 +2. **获取选中值**:`document.getElementById('下拉框ID').value`,获取选中 `

+ +``` + +2. p204实践与练习 +- +```bash + +

李白《行路难·其一》

+

金樽清酒斗十千,玉盘珍羞直万钱

+

金樽清酒斗十千,玉盘珍羞直万钱

+

金樽清酒斗十千,玉盘珍羞直万钱

+

金樽清酒斗十千,玉盘珍羞直万钱

+

金樽清酒斗十千,玉盘珍羞直万钱

+

金樽清酒斗十千,玉盘珍羞直万钱

+ +``` + +- +```bash + + + + 打开图片对话框 +
+ +
+ + +``` + +- +```bash + + +
+ +``` + diff --git "a/\346\235\216\346\231\250\346\273\224/20251204-\346\226\207\346\241\243\345\257\271\350\261\241\346\250\241\345\236\213.md" "b/\346\235\216\346\231\250\346\273\224/20251204-\346\226\207\346\241\243\345\257\271\350\261\241\346\250\241\345\236\213.md" new file mode 100644 index 0000000000000000000000000000000000000000..ffb9b91d405533866377ed90996e19b76ff90337 --- /dev/null +++ "b/\346\235\216\346\231\250\346\273\224/20251204-\346\226\207\346\241\243\345\257\271\350\261\241\346\250\241\345\236\213.md" @@ -0,0 +1,437 @@ +# 笔记 +歌词对比插入: + +![](https://gitee.com/ak-47-combustible-ice/pic-go/raw/master/20251214172000491.JPG) + +年月日变化而变化: + +![](https://gitee.com/ak-47-combustible-ice/pic-go/raw/master/20251214172035526.JPG) + +# 练习 +1. p215 +- +```bash + 1.(myselef+AI) + + + + + + +
+ + + 2.(myself+teacher) + + + +
+ +``` + +- +```bash + 输入歌名: +
+ 歌词: +
+
+ + +``` + +- +```bash +

最新电影资讯

+
    +
  • 1.《金蚕脱壳》两大动作巨星联手
  • +
  • 2.《阿甘正传》励志而传奇的一生
  • +
  • 3.《爱乐之城》爱情和梦想的交织
  • +
  • 4.《头号玩家》游戏梦想照进现实
  • +
+
+ 输入影片资讯编号: + +
+ +``` + +2. p218 +- +```bash +
    +
  • 西瓜
  • +
  • 蜜橘
  • +
  • 萝卜
  • +
+
    +
  • 黄瓜
  • +
  • 茄子
  • +
  • 杧果
  • +
+ + +``` + +- +```bash +

在《倚天屠龙记》中,张三丰是___派的掌门?

+ A 少林 + B 武当 + C 峨眉 + D 昆仑 + + +``` + +3. p221 +- +```bash + 点我试试 + + +``` + +- +```bash + +
+ +``` + +4. p221实践与练习 +- +```bash + 一生只爱一个人 + 将粗体改为斜体 + +``` + +- +```bash + 1.(AI) + + + + +``` + +- +```bash + 1.(AI) + 请选择图片: +
+ +
+ +``` diff --git "a/\346\235\216\346\231\250\346\273\224/20251205-Windows\345\257\271\350\261\241.md" "b/\346\235\216\346\231\250\346\273\224/20251205-Windows\345\257\271\350\261\241.md" new file mode 100644 index 0000000000000000000000000000000000000000..4b111f0517c7b84446f3d15162a2e58b54d682e7 --- /dev/null +++ "b/\346\235\216\346\231\250\346\273\224/20251205-Windows\345\257\271\350\261\241.md" @@ -0,0 +1,1948 @@ +# 笔记 +## JavaScript Window 对象全面知识点总结 + +## 📋 目录 + +1. [Window 对象简介](#window-对象简介) +2. [对话框方法](#对话框方法) +3. [窗口的打开与关闭](#窗口的打开与关闭) +4. [控制窗口](#控制窗口) +5. [窗口事件](#窗口事件) +6. [窗口导航与历史](#窗口导航与历史) +7. [窗口尺寸与位置](#窗口尺寸与位置) +8. [定时器与动画](#定时器与动画) + +--- + +## Window 对象简介 + +### 1. Window 对象是什么? + +**知识点**:Window 对象代表浏览器窗口,是 JavaScript 的全局对象,包含所有全局变量、函数和对象。 + +```javascript +// Window 对象是全局对象 +console.log(window === this); // 在全局作用域中为 true + +// 全局变量自动成为 window 的属性 +var globalVar = "全局变量"; +console.log(window.globalVar); // "全局变量" + +// 全局函数也是 window 的方法 +function sayHello() { + return "Hello"; +} +console.log(window.sayHello()); // "Hello" +``` + +### 2. Window 对象与其他对象的关系 + +**知识点**:Window 对象包含 document、location、history、navigator 等子对象。 + +```javascript +// Window 的子对象 +console.log(window.document); // Document 对象 +console.log(window.location); // Location 对象 +console.log(window.history); // History 对象 +console.log(window.navigator); // Navigator 对象 +console.log(window.screen); // Screen 对象 +console.log(window.localStorage); // Storage 对象 + +// 访问时可以省略 window 前缀 +console.log(document === window.document); // true +console.log(location === window.location); // true +``` + +### 3. 全局作用域 + +**知识点**:在浏览器中,全局作用域就是 Window 对象。 + +```javascript +// 检查变量是否在全局作用域中 +var x = 10; +let y = 20; // let/const 声明的变量不会成为 window 的属性 +const z = 30; + +console.log(window.x); // 10 +console.log(window.y); // undefined +console.log(window.z); // undefined + +// 在严格模式下,this 在全局作用域中为 undefined +("use strict"); +console.log(this); // undefined (非严格模式下为 window) +``` + +--- + +## 对话框方法 + +### 4. alert() 方法 + +**知识点**:显示一个警告对话框,包含指定的消息和一个"确定"按钮。 + +```javascript +// 基本用法 +alert("这是一个警告信息"); + +// 显示变量值 +let userName = "张三"; +alert(`欢迎, ${userName}!`); + +// 显示对象信息 +let user = { name: "李四", age: 25 }; +alert(JSON.stringify(user, null, 2)); + +// 注意:alert 会阻塞代码执行 +console.log("这行代码在 alert 关闭后执行"); +``` + +### 5. confirm() 方法 + +**知识点**:显示一个确认对话框,包含指定的消息和"确定"/"取消"按钮,返回布尔值。 + +```javascript +// 基本用法 +let result = confirm("您确定要删除此项吗?"); +console.log("用户选择:", result); // true 或 false + +// 根据选择执行不同操作 +if (confirm("是否继续?")) { + console.log("用户选择了继续"); + // 执行继续操作 +} else { + console.log("用户选择了取消"); + // 执行取消操作 +} + +// 使用在三元表达式中 +let action = confirm("启用高级功能?") ? "启用" : "禁用"; +console.log("操作:", action); +``` + +### 6. prompt() 方法 + +**知识点**:显示一个提示对话框,包含输入框和"确定"/"取消"按钮,返回输入值或 null。 + +```javascript +// 基本用法 +let name = prompt("请输入您的姓名:"); +console.log("输入的姓名:", name); + +// 带默认值 +let age = prompt("请输入您的年龄:", "25"); +console.log("输入的年龄:", age); + +// 验证输入 +let input; +do { + input = prompt("请输入一个数字(1-10):"); +} while (input === null || isNaN(input) || input < 1 || input > 10); + +console.log("有效的输入:", input); + +// 处理取消操作 +let email = prompt("请输入邮箱:"); +if (email === null) { + console.log("用户取消了输入"); +} else if (email.trim() === "") { + console.log("用户输入了空字符串"); +} else { + console.log("用户输入:", email); +} +``` + +### 7. 自定义对话框 + +**知识点**:使用 DOM 创建更灵活的自定义对话框。 + +```javascript +// 创建自定义确认对话框 +function customConfirm(message, callback) { + // 创建对话框元素 + const dialog = document.createElement("div"); + dialog.style.cssText = ` + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + background: white; + padding: 20px; + border: 2px solid #333; + border-radius: 5px; + z-index: 1000; + `; + + dialog.innerHTML = ` +

${message}

+ + + `; + + document.body.appendChild(dialog); + + // 添加事件处理 + document.getElementById("confirmOk").onclick = function () { + document.body.removeChild(dialog); + callback(true); + }; + + document.getElementById("confirmCancel").onclick = function () { + document.body.removeChild(dialog); + callback(false); + }; +} + +// 使用自定义对话框 +customConfirm("是否确认操作?", function (result) { + console.log("用户选择:", result); +}); +``` + +--- + +## 窗口的打开与关闭 + +### 8. window.open() 方法 + +**知识点**:打开一个新的浏览器窗口或标签页。 + +```javascript +// 基本用法 - 在新标签页中打开 +const newWindow = window.open("https://www.example.com"); + +// 指定窗口名称(可用于 target 属性) +window.open("page.html", "myWindow"); + +// 在新窗口中打开(不是新标签页) +const popup = window.open("popup.html", "popup", "width=400,height=300"); + +// 控制是否显示浏览器控件 +const minimalWindow = window.open( + "minimal.html", + "minimal", + "menubar=no,toolbar=no,location=no,status=no" +); + +// 获取打开的窗口引用 +const myWindow = window.open("", "myWindow"); +if (myWindow) { + myWindow.document.write("

Hello from opener!

"); +} +``` + +### 9. 窗口打开参数 + +**知识点**:window.open() 的第三个参数控制窗口特性。 + +```javascript +// 完整的窗口特性参数 +const features = [ + "width=800", // 窗口宽度 + "height=600", // 窗口高度 + "left=100", // 距离屏幕左边缘 + "top=100", // 距离屏幕上边缘 + "resizable=yes", // 是否可调整大小 + "scrollbars=yes", // 是否显示滚动条 + "toolbar=no", // 是否显示工具栏 + "menubar=no", // 是否显示菜单栏 + "location=no", // 是否显示地址栏 + "status=no", // 是否显示状态栏 + "fullscreen=no", // 是否全屏(需要用户交互) +].join(","); + +const configuredWindow = window.open("config.html", "config", features); + +// 检查窗口是否成功打开 +if (!configuredWindow) { + alert("弹出窗口被浏览器阻止了!请允许弹出窗口。"); +} +``` + +### 10. window.close() 方法 + +**知识点**:关闭当前窗口或指定的窗口。 + +```javascript +// 关闭当前窗口 +function closeCurrentWindow() { + if (confirm("确定要关闭窗口吗?")) { + window.close(); + } +} + +// 关闭由 window.open() 打开的窗口 +let openedWindow = null; + +function openAndClose() { + // 打开新窗口 + openedWindow = window.open("", "testWindow", "width=400,height=300"); + + // 在新窗口中写入内容 + openedWindow.document.write("

这个窗口将在5秒后关闭

"); + + // 5秒后关闭窗口 + setTimeout(() => { + if (openedWindow && !openedWindow.closed) { + openedWindow.close(); + console.log("窗口已关闭"); + } + }, 5000); +} + +// 检查窗口是否已关闭 +if (openedWindow && openedWindow.closed) { + console.log("窗口已经关闭了"); +} +``` + +### 11. 窗口状态检测 + +**知识点**:检测窗口的打开和关闭状态。 + +```javascript +let childWindow = null; + +// 打开子窗口 +function openChildWindow() { + childWindow = window.open("child.html", "child", "width=400,height=300"); + + // 定期检查子窗口是否关闭 + const checkInterval = setInterval(() => { + if (childWindow.closed) { + console.log("子窗口已关闭"); + clearInterval(checkInterval); + // 执行清理操作 + childWindow = null; + } + }, 1000); +} + +// 与子窗口通信 +function sendMessageToChild() { + if (childWindow && !childWindow.closed) { + // 向子窗口传递数据 + childWindow.postMessage("Hello from parent!", "*"); + + // 调用子窗口的函数(如果同源) + try { + childWindow.someFunction(); + } catch (e) { + console.log("跨域限制或函数不存在"); + } + } else { + console.log("子窗口未打开或已关闭"); + } +} +``` + +--- + +## 控制窗口 + +### 12. 移动窗口 + +**知识点**:移动窗口到指定位置。 + +```javascript +// 移动当前窗口 +function moveWindowTo(x, y) { + // 注意:现代浏览器出于安全考虑,通常不允许脚本移动主窗口 + // 但可以移动由 window.open() 打开的窗口 + + if (window.opener) { + // 如果这是由其他窗口打开的 + window.moveTo(x, y); + } +} + +// 移动由脚本打开的窗口 +let movableWindow = null; + +function createMovableWindow() { + movableWindow = window.open("", "movable", "width=300,height=200"); + + // 添加控制按钮 + movableWindow.document.write(` +

可移动窗口

+ + + `); +} + +// 相对移动 +function moveWindowRelative(dx, dy) { + if (movableWindow && !movableWindow.closed) { + movableWindow.moveBy(dx, dy); + } +} +``` + +### 13. 调整窗口大小 + +**知识点**:调整窗口的尺寸。 + +```javascript +// 调整当前窗口大小 +function resizeCurrentWindow(width, height) { + // 注意:通常不能调整主窗口大小 + // 但可以调整由 window.open() 打开的窗口 + window.resizeTo(width, height); +} + +// 调整由脚本打开的窗口 +let resizableWindow = null; + +function createResizableWindow() { + resizableWindow = window.open( + "", + "resizable", + "width=400,height=300,resizable=yes" + ); + + // 添加控制按钮 + resizableWindow.document.write(` +

可调整大小的窗口

+ + + + `); +} + +// 检查窗口是否可以调整大小 +function checkIfResizable() { + if (resizableWindow) { + // 注意:没有直接的方法检查,但可以尝试调整 + try { + resizableWindow.resizeBy(1, 1); + resizableWindow.resizeBy(-1, -1); // 恢复 + console.log("窗口可以调整大小"); + return true; + } catch (e) { + console.log("窗口不能调整大小"); + return false; + } + } + return false; +} +``` + +### 14. 窗口滚动控制 + +**知识点**:控制窗口的滚动位置。 + +```javascript +// 滚动到指定位置 +function scrollToPosition(x, y) { + window.scrollTo(x, y); + + // 或使用选项对象 + window.scrollTo({ + top: y, + left: x, + behavior: "smooth", // 'auto' 或 'smooth' + }); +} + +// 滚动到元素 +function scrollToElement(elementId) { + const element = document.getElementById(elementId); + if (element) { + element.scrollIntoView({ + behavior: "smooth", + block: "start", // 'start', 'center', 'end', 'nearest' + }); + } +} + +// 相对滚动 +function scrollByAmount(dx, dy) { + window.scrollBy(dx, dy); + + // 平滑滚动 + window.scrollBy({ + top: dy, + left: dx, + behavior: "smooth", + }); +} + +// 获取当前滚动位置 +function getScrollPosition() { + return { + x: window.pageXOffset || document.documentElement.scrollLeft, + y: window.pageYOffset || document.documentElement.scrollTop, + }; +} + +// 滚动到页面顶部 +function scrollToTop() { + window.scrollTo({ top: 0, behavior: "smooth" }); +} + +// 滚动到页面底部 +function scrollToBottom() { + window.scrollTo({ + top: document.documentElement.scrollHeight, + behavior: "smooth", + }); +} +``` + +### 15. 窗口焦点控制 + +**知识点**:控制窗口的焦点状态。 + +```javascript +// 将焦点设置到当前窗口 +function focusWindow() { + window.focus(); + console.log("窗口已获得焦点"); +} + +// 使窗口失去焦点 +function blurWindow() { + window.blur(); + console.log("窗口已失去焦点"); +} + +// 检查窗口是否有焦点 +function checkWindowFocus() { + if (document.hasFocus()) { + console.log("当前窗口有焦点"); + return true; + } else { + console.log("当前窗口没有焦点"); + return false; + } +} + +// 焦点变化示例 +let lastFocusTime = Date.now(); + +window.addEventListener("focus", () => { + const now = Date.now(); + const awayTime = now - lastFocusTime; + console.log(`窗口重新获得焦点,离开时间:${awayTime}ms`); +}); + +window.addEventListener("blur", () => { + lastFocusTime = Date.now(); + console.log("窗口失去焦点"); +}); + +// 自动聚焦输入框 +function autoFocusInput() { + const input = document.getElementById("myInput"); + if (input) { + input.focus(); + // 选中文本(可选) + input.select(); + } +} +``` + +--- + +## 窗口事件 + +### 16. load 事件 + +**知识点**:当整个页面及所有依赖资源(如图片、样式表)已完全加载时触发。 + +```javascript +// 使用 addEventListener +window.addEventListener("load", function () { + console.log("所有资源已完全加载"); + // 可以安全地操作DOM和资源 + const images = document.getElementsByTagName("img"); + console.log(`页面包含 ${images.length} 张图片`); +}); + +// 传统方式 +window.onload = function () { + console.log("页面加载完成(传统方式)"); + // 初始化应用 + initApp(); +}; + +// 图片加载完成后执行 +const img = new Image(); +img.src = "large-image.jpg"; +img.onload = function () { + console.log("大图片加载完成"); + document.body.appendChild(img); +}; +``` + +### 17. DOMContentLoaded 事件 + +**知识点**:当初始 HTML 文档完全加载和解析完成(不等待样式表、图片等)时触发。 + +```javascript +// 推荐使用 - 比 load 事件更快 +document.addEventListener("DOMContentLoaded", function () { + console.log("DOM 已完全加载和解析"); + // DOM 已就绪,可以操作元素 + const buttons = document.querySelectorAll("button"); + console.log(`找到 ${buttons.length} 个按钮`); + + // 添加事件监听器等 + buttons.forEach((btn) => { + btn.addEventListener("click", handleClick); + }); +}); + +// 传统方式 +document.onreadystatechange = function () { + if (document.readyState === "interactive") { + console.log("DOM 准备就绪(readystatechange)"); + } +}; +``` + +### 18. beforeunload 事件 + +**知识点**:在窗口、文档即将卸载时触发,可用于提示用户保存更改。 + +```javascript +// 提示用户离开前保存数据 +window.addEventListener("beforeunload", function (event) { + // 如果有未保存的更改 + if (hasUnsavedChanges) { + // 标准方式 + event.preventDefault(); + // Chrome 需要设置 returnValue + event.returnValue = "您有未保存的更改,确定要离开吗?"; + return "您有未保存的更改,确定要离开吗?"; + } +}); + +// 传统方式 +window.onbeforeunload = function () { + if (hasUnsavedChanges) { + return "您有未保存的更改,确定要离开吗?"; + } +}; + +// 清除 beforeunload 处理程序 +function clearBeforeUnload() { + window.onbeforeunload = null; + // 或使用 removeEventListener +} +``` + +### 19. unload 事件 + +**知识点**:当文档或子资源正在被卸载时触发,用于清理操作。 + +```javascript +// 在页面卸载时执行清理 +window.addEventListener("unload", function () { + // 发送统计数据 + if (navigator.sendBeacon) { + const data = new FormData(); + data.append("event", "page_unload"); + data.append("time", Date.now()); + navigator.sendBeacon("/analytics", data); + } + + // 清理资源 + cleanupResources(); + + console.log("页面正在卸载"); +}); + +// 注意:unload 事件中不能使用同步的 alert/confirm/prompt +// 也不能阻止页面卸载 +``` + +### 20. resize 事件 + +**知识点**:当窗口大小改变时触发。 + +```javascript +// 监听窗口大小变化 +let resizeTimeout; +window.addEventListener("resize", function () { + // 防抖处理,避免频繁触发 + clearTimeout(resizeTimeout); + resizeTimeout = setTimeout(() => { + console.log("窗口大小已改变"); + console.log("新尺寸:", window.innerWidth, "x", window.innerHeight); + + // 根据窗口大小调整布局 + adjustLayoutForScreenSize(); + }, 250); // 250ms 防抖延迟 +}); + +// 获取窗口尺寸 +function getWindowSize() { + return { + width: window.innerWidth || document.documentElement.clientWidth, + height: window.innerHeight || document.documentElement.clientHeight, + outerWidth: window.outerWidth, + outerHeight: window.outerHeight, + }; +} + +// 响应式设计检查 +function checkResponsiveBreakpoint() { + const width = window.innerWidth; + + if (width >= 1200) { + console.log("超大屏幕"); + } else if (width >= 992) { + console.log("大屏幕"); + } else if (width >= 768) { + console.log("中等屏幕"); + } else if (width >= 576) { + console.log("小屏幕"); + } else { + console.log("超小屏幕"); + } +} +``` + +### 21. scroll 事件 + +**知识点**:当窗口滚动时触发。 + +```javascript +// 监听滚动事件 +let lastScrollTop = 0; +window.addEventListener("scroll", function () { + const scrollTop = window.pageYOffset || document.documentElement.scrollTop; + + // 检查滚动方向 + if (scrollTop > lastScrollTop) { + console.log("向下滚动"); + } else { + console.log("向上滚动"); + } + + lastScrollTop = scrollTop; + + // 无限滚动示例 + if (isNearBottom()) { + loadMoreContent(); + } + + // 固定导航栏 + toggleFixedNavbar(scrollTop); +}); + +// 检查是否接近底部 +function isNearBottom() { + const scrollTop = window.pageYOffset || document.documentElement.scrollTop; + const scrollHeight = document.documentElement.scrollHeight; + const clientHeight = document.documentElement.clientHeight; + + // 距离底部 200px 时触发 + return scrollTop + clientHeight >= scrollHeight - 200; +} + +// 节流滚动事件(性能优化) +function throttleScroll(callback, delay) { + let isThrottled = false; + + return function () { + if (!isThrottled) { + callback(); + isThrottled = true; + setTimeout(() => { + isThrottled = false; + }, delay); + } + }; +} + +window.addEventListener( + "scroll", + throttleScroll(() => { + console.log("节流后的滚动处理"); + }, 100) +); // 每100ms最多执行一次 +``` + +### 22. focus 和 blur 事件 + +**知识点**:当窗口获得或失去焦点时触发。 + +```javascript +// 窗口获得焦点 +window.addEventListener("focus", function () { + console.log("窗口获得焦点"); + + // 恢复应用状态 + if (isAppPaused) { + resumeApp(); + } + + // 更新页面标题 + document.title = document.title.replace(" [未激活]", ""); +}); + +// 窗口失去焦点 +window.addEventListener("blur", function () { + console.log("窗口失去焦点"); + + // 暂停应用活动 + pauseApp(); + + // 更新页面标题提示 + if (!document.title.includes("[未激活]")) { + document.title += " [未激活]"; + } +}); + +// 检查当前焦点状态 +function checkFocusStatus() { + if (document.hasFocus()) { + console.log("当前窗口处于活动状态"); + return true; + } else { + console.log("当前窗口处于非活动状态"); + return false; + } +} + +// 页面可见性 API(更现代的替代方案) +document.addEventListener("visibilitychange", function () { + if (document.hidden) { + console.log("页面隐藏"); + } else { + console.log("页面可见"); + } +}); +``` + +### 23. hashchange 事件 + +**知识点**:当 URL 的哈希部分(#后面)改变时触发。 + +```javascript +// 监听哈希变化 +window.addEventListener("hashchange", function (event) { + console.log("哈希已改变"); + console.log("旧URL:", event.oldURL); + console.log("新URL:", event.newURL); + console.log("当前哈希:", window.location.hash); + + // 根据哈希更新页面内容 + const hash = window.location.hash.substring(1); // 去掉 # + if (hash) { + loadContent(hash); + } else { + loadDefaultContent(); + } +}); + +// 手动触发哈希变化 +function navigateToSection(sectionId) { + window.location.hash = sectionId; + // 或使用 history.pushState(不触发 hashchange) + // history.pushState(null, '', '#' + sectionId); +} + +// 初始化时检查哈希 +if (window.location.hash) { + const section = window.location.hash.substring(1); + loadContent(section); +} +``` + +### 24. message 事件 + +**知识点**:当窗口收到来自其他窗口的消息时触发(跨文档通信)。 + +```javascript +// 接收来自其他窗口的消息 +window.addEventListener("message", function (event) { + // 安全检查:检查消息来源 + const allowedOrigin = "https://trusted-site.com"; + if (event.origin !== allowedOrigin) { + console.warn("收到来自不受信任来源的消息:", event.origin); + return; + } + + console.log("收到消息:", event.data); + console.log("来源:", event.origin); + console.log("来源窗口:", event.source); + + // 处理消息 + if (event.data.type === "updateData") { + updateData(event.data.payload); + } + + // 可选:发送回复 + event.source.postMessage( + { + type: "acknowledge", + message: "消息已收到", + }, + event.origin + ); +}); + +// 向其他窗口发送消息 +function sendMessageToIframe() { + const iframe = document.getElementById("myIframe"); + if (iframe && iframe.contentWindow) { + iframe.contentWindow.postMessage( + { + type: "command", + action: "refresh", + }, + "https://iframe-origin.com" + ); + } +} + +// 向父窗口发送消息(如果在 iframe 中) +if (window.parent !== window) { + window.parent.postMessage( + { + type: "ready", + content: "iframe 已加载完成", + }, + "*" + ); // 注意:使用 '*' 有安全风险,生产环境应指定具体来源 +} +``` + +### 25. storage 事件 + +**知识点**:当 localStorage 或 sessionStorage 发生变化时触发(仅在同源的其他窗口中)。 + +```javascript +// 监听存储变化 +window.addEventListener("storage", function (event) { + console.log("存储发生变化:"); + console.log("键:", event.key); + console.log("旧值:", event.oldValue); + console.log("新值:", event.newValue); + console.log("URL:", event.url); + console.log("存储区域:", event.storageArea); + + // 更新应用状态 + if (event.key === "userPreferences") { + updatePreferences(JSON.parse(event.newValue)); + } +}); + +// 示例:在一个标签页中设置,在另一个标签页中监听 +function saveUserSettings(settings) { + localStorage.setItem("userPreferences", JSON.stringify(settings)); + console.log("设置已保存"); +} + +// 当前窗口的变化不会触发自己的 storage 事件 +// 只会在同源的其他窗口中触发 +``` + +--- + +## 窗口导航与历史 + +### 26. location 对象 + +**知识点**:window.location 对象包含当前 URL 的信息,并可用于导航。 + +```javascript +// 获取当前URL信息 +console.log("完整URL:", window.location.href); +console.log("协议:", window.location.protocol); // https: +console.log("主机:", window.location.host); // example.com:8080 +console.log("主机名:", window.location.hostname); // example.com +console.log("端口:", window.location.port); // 8080 +console.log("路径:", window.location.pathname); // /path/to/page +console.log("搜索参数:", window.location.search); // ?id=123 +console.log("哈希:", window.location.hash); // #section +console.log("来源:", window.location.origin); // https://example.com:8080 + +// 导航到新页面 +function navigateTo(url) { + window.location.href = url; // 最常用 + // 或 window.location = url; + // 或 window.location.assign(url); +} + +// 重定向到新页面(替换当前历史记录) +function redirectTo(url) { + window.location.replace(url); // 当前页面不会留在历史记录中 +} + +// 重新加载页面 +function reloadPage() { + window.location.reload(); // 重新加载 + // window.location.reload(true); // 强制从服务器重新加载(忽略缓存) +} + +// 获取URL参数 +function getUrlParams() { + const params = new URLSearchParams(window.location.search); + const id = params.get("id"); // 获取id参数 + const name = params.get("name"); // 获取name参数 + + console.log("ID:", id); + console.log("所有参数:", Object.fromEntries(params)); + return { id, name }; +} +``` + +### 27. history 对象 + +**知识点**:window.history 对象允许操作浏览器会话历史记录。 + +```javascript +// 前进和后退 +function goBack() { + window.history.back(); // 等同于点击后退按钮 + // 或 window.history.go(-1); +} + +function goForward() { + window.history.forward(); // 等同于点击前进按钮 + // 或 window.history.go(1); +} + +// 跳转到历史记录中的特定位置 +function goToHistory(index) { + window.history.go(index); // 正数前进,负数后退 +} + +// 添加历史记录(不会加载新页面) +function addHistoryState(state, title, url) { + window.history.pushState(state, title, url); + console.log("历史记录已添加:", url); +} + +// 替换当前历史记录 +function replaceHistoryState(state, title, url) { + window.history.replaceState(state, title, url); + console.log("历史记录已替换:", url); +} + +// 监听历史记录变化 +window.addEventListener("popstate", function (event) { + console.log("位置变化:", window.location.href); + console.log("状态:", event.state); + + // 根据状态更新页面内容 + if (event.state) { + loadContentBasedOnState(event.state); + } +}); + +// 单页应用(SPA)路由示例 +function navigateToPage(page) { + const state = { page: page, timestamp: Date.now() }; + const url = `/${page}`; + + // 添加历史记录 + history.pushState(state, "", url); + + // 加载页面内容(不刷新页面) + loadPageContent(page); +} +``` + +### 28. navigator 对象 + +**知识点**:window.navigator 对象包含有关浏览器的信息。 + +```javascript +// 浏览器信息 +console.log("用户代理:", navigator.userAgent); +console.log("平台:", navigator.platform); +console.log("语言:", navigator.language); +console.log("浏览器语言:", navigator.languages); +console.log("Cookie 启用:", navigator.cookieEnabled); +console.log("在线状态:", navigator.onLine); + +// 检测设备类型 +function detectDevice() { + const ua = navigator.userAgent; + + if (/mobile/i.test(ua)) { + return "mobile"; + } else if (/tablet/i.test(ua)) { + return "tablet"; + } else { + return "desktop"; + } +} + +// 检测浏览器 +function detectBrowser() { + const ua = navigator.userAgent; + + if (/chrome/i.test(ua) && !/edge/i.test(ua)) { + return "Chrome"; + } else if (/firefox/i.test(ua)) { + return "Firefox"; + } else if (/safari/i.test(ua) && !/chrome/i.test(ua)) { + return "Safari"; + } else if (/edge/i.test(ua)) { + return "Edge"; + } else if (/msie/i.test(ua) || /trident/i.test(ua)) { + return "IE"; + } else { + return "Unknown"; + } +} + +// 检查网络状态 +function checkNetworkStatus() { + if (navigator.onLine) { + console.log("设备在线"); + return true; + } else { + console.log("设备离线"); + return false; + } +} + +// 监听网络状态变化 +window.addEventListener("online", () => { + console.log("设备已连接到网络"); + // 重新同步数据 +}); + +window.addEventListener("offline", () => { + console.log("设备已断开网络"); + // 显示离线提示 +}); +``` + +--- + +## 窗口尺寸与位置 + +### 29. 获取窗口尺寸 + +**知识点**:获取窗口和屏幕的尺寸信息。 + +```javascript +// 获取视口尺寸(显示网页的区域) +function getViewportSize() { + return { + width: window.innerWidth, + height: window.innerHeight, + // 兼容性处理 + widthAlt: document.documentElement.clientWidth, + heightAlt: document.documentElement.clientHeight, + }; +} + +// 获取整个窗口尺寸(包括浏览器界面) +function getWindowOuterSize() { + return { + width: window.outerWidth, + height: window.outerHeight, + }; +} + +// 获取屏幕尺寸 +function getScreenSize() { + return { + width: screen.width, + height: screen.height, + availWidth: screen.availWidth, // 可用宽度(不包括任务栏等) + availHeight: screen.availHeight, // 可用高度 + colorDepth: screen.colorDepth, // 颜色深度 + pixelDepth: screen.pixelDepth, // 像素深度 + }; +} + +// 获取文档尺寸(整个页面内容) +function getDocumentSize() { + return { + width: document.documentElement.scrollWidth, + height: document.documentElement.scrollHeight, + }; +} + +// 响应式设计辅助函数 +function getBreakpoint() { + const width = window.innerWidth; + + if (width >= 1400) return "xxl"; + if (width >= 1200) return "xl"; + if (width >= 992) return "lg"; + if (width >= 768) return "md"; + if (width >= 576) return "sm"; + return "xs"; +} + +// 监听窗口尺寸变化 +function watchWindowSize(callback) { + let lastSize = getViewportSize(); + + window.addEventListener("resize", () => { + const newSize = getViewportSize(); + + if ( + newSize.width !== lastSize.width || + newSize.height !== lastSize.height + ) { + callback(newSize, lastSize); + lastSize = newSize; + } + }); +} +``` + +### 30. 获取窗口位置 + +**知识点**:获取窗口在屏幕上的位置。 + +```javascript +// 获取窗口相对于屏幕的位置 +function getWindowPosition() { + return { + screenX: window.screenX, // 窗口左上角X坐标 + screenY: window.screenY, // 窗口左上角Y坐标 + screenLeft: window.screenLeft, // 兼容性别名 + screenTop: window.screenTop, // 兼容性别名 + }; +} + +// 获取滚动位置 +function getScrollPosition() { + return { + x: window.pageXOffset || document.documentElement.scrollLeft, + y: window.pageYOffset || document.documentElement.scrollTop, + }; +} + +// 元素相对于视口的位置 +function getElementViewportPosition(element) { + const rect = element.getBoundingClientRect(); + return { + top: rect.top, + right: rect.right, + bottom: rect.bottom, + left: rect.left, + width: rect.width, + height: rect.height, + }; +} + +// 检查元素是否在视口中 +function isElementInViewport(element) { + const rect = element.getBoundingClientRect(); + const windowHeight = + window.innerHeight || document.documentElement.clientHeight; + const windowWidth = window.innerWidth || document.documentElement.clientWidth; + + return ( + rect.top >= 0 && + rect.left >= 0 && + rect.bottom <= windowHeight && + rect.right <= windowWidth + ); +} + +// 检查元素是否部分可见 +function isElementPartiallyVisible(element) { + const rect = element.getBoundingClientRect(); + const windowHeight = + window.innerHeight || document.documentElement.clientHeight; + const windowWidth = window.innerWidth || document.documentElement.clientWidth; + + const vertInView = rect.top <= windowHeight && rect.bottom >= 0; + const horInView = rect.left <= windowWidth && rect.right >= 0; + + return vertInView && horInView; +} +``` + +--- + +## 定时器与动画 + +### 31. setTimeout() + +**知识点**:在指定的毫秒数后执行一次函数。 + +```javascript +// 基本用法 +setTimeout(() => { + console.log("3秒后执行"); +}, 3000); + +// 带参数的函数 +function greet(name) { + console.log(`Hello, ${name}!`); +} +setTimeout(greet, 2000, "张三"); + +// 清除定时器 +const timeoutId = setTimeout(() => { + console.log("这个不会执行"); +}, 5000); + +// 在2秒后清除定时器 +setTimeout(() => { + clearTimeout(timeoutId); + console.log("定时器已清除"); +}, 2000); + +// 模拟异步操作 +function simulateAsyncTask(duration) { + console.log(`任务开始,需要 ${duration}ms`); + + return new Promise((resolve) => { + setTimeout(() => { + console.log("任务完成"); + resolve("结果"); + }, duration); + }); +} +``` + +### 32. setInterval() + +**知识点**:按照指定的周期(毫秒)重复执行函数。 + +```javascript +// 基本用法 +let counter = 0; +const intervalId = setInterval(() => { + counter++; + console.log(`计数器: ${counter}`); + + if (counter >= 10) { + clearInterval(intervalId); + console.log("定时器已停止"); + } +}, 1000); // 每秒执行一次 + +// 时钟示例 +function startClock() { + const clockElement = document.getElementById("clock"); + + const updateClock = () => { + const now = new Date(); + const timeString = now.toLocaleTimeString(); + clockElement.textContent = timeString; + }; + + // 立即更新一次 + updateClock(); + + // 每秒更新一次 + return setInterval(updateClock, 1000); +} + +// 动画示例(简单实现) +function animateElement(element, duration) { + const start = Date.now(); + const startPosition = 0; + const endPosition = 300; + + const intervalId = setInterval(() => { + const elapsed = Date.now() - start; + const progress = Math.min(elapsed / duration, 1); + + // 线性动画 + const currentPosition = + startPosition + (endPosition - startPosition) * progress; + element.style.left = currentPosition + "px"; + + if (progress >= 1) { + clearInterval(intervalId); + console.log("动画完成"); + } + }, 16); // 约60fps +} + +// 轮询示例 +function pollServer() { + const pollInterval = 5000; // 5秒 + + const poll = () => { + fetch("/api/status") + .then((response) => response.json()) + .then((data) => { + console.log("服务器状态:", data); + // 处理数据 + }) + .catch((error) => { + console.error("轮询错误:", error); + }); + }; + + // 立即执行一次 + poll(); + + // 然后每5秒执行一次 + return setInterval(poll, pollInterval); +} +``` + +### 33. requestAnimationFrame() + +**知识点**:为动画优化的定时器,在浏览器重绘之前执行。 + +```javascript +// 基本用法 +function animate() { + // 动画逻辑 + updateAnimation(); + + // 请求下一帧 + requestAnimationFrame(animate); +} + +// 启动动画 +requestAnimationFrame(animate); + +// 平滑动画示例 +function smoothAnimate(element, property, startValue, endValue, duration) { + const startTime = performance.now(); + + function animateFrame(currentTime) { + const elapsed = currentTime - startTime; + const progress = Math.min(elapsed / duration, 1); + + // 使用缓动函数 + const easeProgress = easeInOutCubic(progress); + const currentValue = startValue + (endValue - startValue) * easeProgress; + + element.style[property] = currentValue + "px"; + + if (progress < 1) { + requestAnimationFrame(animateFrame); + } + } + + requestAnimationFrame(animateFrame); +} + +// 缓动函数 +function easeInOutCubic(t) { + return t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2; +} + +// FPS计数器 +function createFPSCounter() { + let frameCount = 0; + let lastTime = performance.now(); + let fps = 0; + + function countFrame() { + frameCount++; + const currentTime = performance.now(); + + if (currentTime - lastTime >= 1000) { + fps = frameCount; + frameCount = 0; + lastTime = currentTime; + console.log(`FPS: ${fps}`); + } + + requestAnimationFrame(countFrame); + } + + requestAnimationFrame(countFrame); +} + +// 取消动画帧 +let animationFrameId; + +function startCustomAnimation() { + let position = 0; + + function animate() { + position += 1; + element.style.left = position + "px"; + + if (position < 300) { + animationFrameId = requestAnimationFrame(animate); + } + } + + animationFrameId = requestAnimationFrame(animate); +} + +function stopAnimation() { + if (animationFrameId) { + cancelAnimationFrame(animationFrameId); + console.log("动画已停止"); + } +} +``` + +--- + +## 📌 最佳实践总结 + +### 34. 窗口操作安全注意事项 + +```javascript +// 1. 弹出窗口通常会被浏览器阻止 +function safeOpenWindow(url) { + const newWindow = window.open(url); + + if ( + !newWindow || + newWindow.closed || + typeof newWindow.closed === "undefined" + ) { + // 弹出窗口被阻止 + console.warn("弹出窗口被浏览器阻止"); + // 提供备用方案 + window.location.href = url; // 在当前窗口打开 + return null; + } + + return newWindow; +} + +// 2. 用户交互后才能打开弹出窗口 +document.getElementById("openBtn").addEventListener("click", function () { + // 只有响应用户点击事件,弹出窗口才不会被阻止 + window.open("popup.html"); +}); + +// 3. 检查是否支持某些窗口特性 +function checkWindowFeaturesSupport() { + const features = { + localStorage: !!window.localStorage, + sessionStorage: !!window.sessionStorage, + geolocation: !!navigator.geolocation, + notifications: !!window.Notification, + serviceWorker: "serviceWorker" in navigator, + webSocket: "WebSocket" in window, + }; + + console.log("浏览器特性支持:", features); + return features; +} +``` + +### 35. 性能优化建议 + +```javascript +// 1. 防抖和节流窗口事件 +function debounce(func, wait) { + let timeout; + return function executedFunction(...args) { + const later = () => { + clearTimeout(timeout); + func(...args); + }; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + }; +} + +// 使用防抖的resize事件 +window.addEventListener( + "resize", + debounce(() => { + console.log("窗口大小已稳定"); + }, 250) +); + +// 2. 使用requestAnimationFrame替代setTimeout做动画 +function smoothAnimation() { + let start = null; + + function step(timestamp) { + if (!start) start = timestamp; + const progress = timestamp - start; + + // 更新动画 + element.style.left = Math.min(progress / 10, 200) + "px"; + + if (progress < 2000) { + requestAnimationFrame(step); + } + } + + requestAnimationFrame(step); +} + +// 3. 清理定时器防止内存泄漏 +class TimerManager { + constructor() { + this.timers = new Set(); + } + + setTimeout(callback, delay, ...args) { + const id = setTimeout( + () => { + this.timers.delete(id); + callback(...args); + }, + delay, + ...args + ); + + this.timers.add(id); + return id; + } + + clearAll() { + this.timers.forEach((id) => clearTimeout(id)); + this.timers.clear(); + } +} +``` + +--- + +## 🎯 Window 对象核心要点速查表 + +| 类别 | 方法/属性/事件 | 描述 | +| ------------ | ------------------------- | -------------- | +| **对话框** | `alert()` | 警告对话框 | +| | `confirm()` | 确认对话框 | +| | `prompt()` | 提示输入对话框 | +| **窗口控制** | `open()` | 打开新窗口 | +| | `close()` | 关闭窗口 | +| | `resizeTo()` | 调整窗口大小 | +| | `moveTo()` | 移动窗口 | +| **事件** | `load` | 页面完全加载 | +| | `DOMContentLoaded` | DOM 加载完成 | +| | `resize` | 窗口大小改变 | +| | `scroll` | 窗口滚动 | +| | `beforeunload` | 页面卸载前 | +| **定时器** | `setTimeout()` | 延迟执行 | +| | `setInterval()` | 间隔执行 | +| | `requestAnimationFrame()` | 动画帧 | +| **导航** | `location` | URL 操作 | +| | `history` | 历史记录 | +| | `navigator` | 浏览器信息 | +| **尺寸** | `innerWidth/Height` | 视口尺寸 | +| | `outerWidth/Height` | 窗口尺寸 | +| | `screen` | 屏幕信息 | + +--- + + + +# 练习 +1. p228 +- +```bash + + +``` + +- +```bash + 退出登录 + +``` + +2. p231 +- +```bash +

影片列表

+ + +
+
+ 星际穿越 +
星际穿越
+
+
+ 盗梦空间 +
盗梦空间
+
+
+ 阿甘正传 +
阿甘正传
+
+
+ 楚门的世界 +
楚门的世界
+
+
+ + + + + + + + +``` + +- +```bash + + +``` + +3. p235 +- +```bash + + +``` + +- +```bash + +
00:00:00
+ + + + +``` + +4. p235实践与练习 +- +```bash + let num1 = Math.floor(Math.random() * 10); + let num2 = Math.floor(Math.random() * 10); + let daan = prompt(num1 + '+' + num2 + '='); + let num3 = num1 + num2; + if (daan == num3) { + let bool = confirm('正确!是否继续?'); + if(bool == true){ + location.reload(); + }else{ + window.close(); + } + } else{ + alert('回答错误,再接再厉哦!'); + window.close(); + } +``` + +- +```bash + let Elvalue = prompt('2024年奥运会在哪座城市举办?\n'+'A.罗马\n'+'B.北京\n'+'C.伦敦\n'+'D.巴黎'); + if(Elvalue =='D'){ + document.write('回答正确!'); + }else{ + document.write('回答错误!'); + } +``` + +- +```bash + +
+ + +``` diff --git "a/\346\235\216\346\231\250\346\273\224/20251208-\346\265\217\350\247\210\345\231\250\345\257\271\350\261\241\346\250\241\345\236\213.md" "b/\346\235\216\346\231\250\346\273\224/20251208-\346\265\217\350\247\210\345\231\250\345\257\271\350\261\241\346\250\241\345\236\213.md" new file mode 100644 index 0000000000000000000000000000000000000000..ff1af9e974877b55041d4ecd87b73c90ff229237 --- /dev/null +++ "b/\346\235\216\346\231\250\346\273\224/20251208-\346\265\217\350\247\210\345\231\250\345\257\271\350\261\241\346\250\241\345\236\213.md" @@ -0,0 +1,191 @@ +# 笔记 +## 一、Location 对象(页面跳转/刷新) +Location 对象是 `window.location` 的简写,专门用于控制浏览器 URL 相关操作,是页面导航的核心工具。 + +### 核心知识点 +1. **核心方法**: + | 方法 | 作用 | + |---------------------|----------------------------------------------------------------------| + | `location.assign(URL)` | 跳转到指定 URL 地址,保留浏览器历史记录(用户可点击“返回”回到原页面) | + | `location.reload()` | 刷新当前页面,等效于浏览器的刷新按钮 | +2. **延时跳转**:结合 `setTimeout` 实现“延迟 N 秒后跳转”,提升交互体验(如“3秒后自动跳转”),语法: + ```javascript + setTimeout(() => { + location.assign("目标URL"); + }, 延迟毫秒数); // 1秒=1000毫秒,如3000表示3秒 + ``` + +### 练习要点 +- 基础跳转:点击按钮直接调用 `location.assign("https://www.baidu.com/")` 跳转到百度; +- 延时跳转:3秒后跳转,核心是 `setTimeout` 包裹跳转逻辑,确保延迟执行。 + +## 二、定时器(setTimeout/setInterval) +定时器是 JavaScript 实现“延时执行/重复执行”逻辑的核心,分为单次定时器和循环定时器。 + +### 核心知识点 +1. **两类定时器对比**: + | 定时器类型 | 执行逻辑 | 清除方法 | 适用场景 | + |------------------|---------------------------|------------------------|------------------------| + | `setTimeout()` | 延迟指定时间**执行一次** | `clearTimeout(定时器ID)` | 延时跳转、延时提示等 | + | `setInterval()` | 每隔指定时间**重复执行** | `clearInterval(定时器ID)` | 计时器、实时刷新数据等 | +2. **关键特性**: + - 定时器调用后会返回一个**定时器ID**(数字),需存储该ID才能后续清除; + - 清除定时器是必做操作:暂停/重置计时器时,必须先清除定时器,否则会导致逻辑错乱(如多个定时器同时运行)。 + +### 练习要点 +- `setTimeout` 延时跳转:回调函数用箭头函数简洁,3000毫秒(3秒)后执行跳转; +- `setInterval` 实现计时器:每秒累加秒数,是循环定时器的典型应用。 + +## 三、计时器(秒表)功能实现(综合案例) +这是定时器+状态管理+DOM操作的综合应用,核心是实现“开始/暂停/重置”的完整秒表逻辑。 + +### 核心知识点 +1. **状态管理变量**(秒表核心): + - `seconds = 0`:存储累计秒数,是计时的核心数据; + - `timerId = null`:存储 `setInterval` 返回的定时器ID,用于清除定时器; + - `isRunning = false`:布尔值标记计时器“运行/暂停”状态,切换时用 `isRunning = !isRunning` 翻转状态。 +2. **时间格式化函数**(秒数转 HH:MM:SS): + ```javascript + function formatTime(sec) { + const hours = String(Math.floor(sec / 3600)).padStart(2, '0'); // 小时:总秒数÷3600 + const minutes = String(Math.floor((sec % 3600) / 60)).padStart(2, '0'); // 分钟:剩余秒数÷60 + const secs = String(sec % 60).padStart(2, '0'); // 秒:剩余秒数取余 + return `${hours}:${minutes}:${secs}`; + } + ``` + - `Math.floor()`:向下取整(避免小数); + - `padStart(2, '0')`:补零,确保小时/分钟/秒都是两位(如 1→01,9→09)。 +3. **核心逻辑**: + - 开始/暂停:判断 `isRunning`,运行则清除定时器+改按钮文字,暂停则启动定时器+改按钮文字,最后翻转状态; + - 重置:清除定时器 → 重置秒数 → 重置状态 → 重置显示和按钮文字(四步缺一不可)。 + +### 练习要点 +- 事件绑定:用 `addEventListener` 绑定按钮点击事件,解耦 HTML 和 JS(优于标签内 `onclick`); +- 健壮性:重置时必须清除定时器,否则即使重置秒数,旧定时器仍会继续累加,导致显示错误。 + +## 四、window.open 打开新窗口 +### 核心知识点 +1. **语法**:`window.open(URL, 窗口名称, 窗口参数)`; +2. **参数详解**: + - URL:新窗口要打开的页面地址(本地 HTML 文件/外网 URL); + - 窗口名称:自定义名称(如 'new'),可省略; + - 窗口参数:字符串形式,指定新窗口的尺寸、位置,常用参数: + - `width=数值`:窗口宽度; + - `height=数值`:窗口高度; + - `left=数值`:窗口距离屏幕左侧的距离; + - `top=数值`:窗口距离屏幕顶部的距离(参数间用逗号分隔)。 +3. **注意事项**:部分浏览器会拦截弹窗,需确保 `window.open` 由用户主动触发(如点击链接/按钮),避免被拦截。 + +### 练习要点 +- 点击 `` 标签打开新窗口,窗口尺寸 500×200,左侧位置 450,参数需严格按字符串格式书写(如 `'width=500,height=200,left=450'`)。 + +--- + +### 总结 +1. **页面导航**:`location.assign()` 实现跳转(可结合 `setTimeout` 延时),`location.reload()` 刷新页面; +2. **定时器**:`setTimeout` 单次延时执行,`setInterval` 重复执行,需用 `clearXXX` 清除,避免内存泄漏; +3. **计时器功能**:布尔变量管理运行状态,`padStart` 补零格式化时间,重置需清除定时器+恢复初始值; +4. **新窗口**:`window.open` 指定 URL 和窗口参数,需用户主动触发避免被浏览器拦截。 + + +# 练习 +1. p240 +- +```bash + + + +``` + +- +```bash + +
00:00:00
+ + + + +``` + +2. p243实践与练习 +- +```bash + + +``` + +- +```bash +
abc + +``` + diff --git "a/\346\235\216\346\231\250\346\273\224/20251210-Style\345\257\271\350\261\241.md" "b/\346\235\216\346\231\250\346\273\224/20251210-Style\345\257\271\350\261\241.md" new file mode 100644 index 0000000000000000000000000000000000000000..a6d463af8ea3994315381ef208365f4e5f244c7a --- /dev/null +++ "b/\346\235\216\346\231\250\346\273\224/20251210-Style\345\257\271\350\261\241.md" @@ -0,0 +1,223 @@ +# 笔记 +## 一、动态修改元素样式(字体、颜色、边框、尺寸) +### 核心知识点 +1. **样式值获取的两种核心方式**: + - 内联样式获取:`element.style.属性名`(仅能获取直接写在元素 `style` 属性里的样式,无值时返回空); + - 计算样式获取:`getComputedStyle(element).属性名`(获取元素最终渲染的样式,包含CSS类、浏览器默认样式,**推荐用于获取初始样式**); + - 数值处理:用 `parseFloat()` 提取样式中的数字(如 `16px` → `16`),结合 `||` 兜底默认值(如 `parseFloat(elem.style.fontSize)||parseFloat(getComputedStyle(elem).fontSize)`)。 +2. **随机十六进制颜色生成(高频实用技巧)**: + ```javascript + // 核心公式,生成 #xxxxxx 格式的随机颜色 + const randomColor = '#' + Math.floor(Math.random()*0xffffff).toString(16).padStart(6,'0'); + ``` + - 解析: + - `Math.random()*0xffffff`:生成 0~16777215(对应十六进制 `ffffff`)的随机数; + - `Math.floor()`:向下取整,去除小数; + - `toString(16)`:转为十六进制字符串; + - `padStart(6,'0')`:补零到6位(避免随机数不足6位导致颜色值无效)。 +3. **样式重置技巧**:给 `style.属性` 赋值空字符串(如 `elem.style.border = ''`),自动回退到CSS定义的默认样式,无需手动还原初始值。 + +### 练习要点 +- 字体放大+随机颜色案例:点击按钮时,先获取文字当前字号(内联无值则取计算样式),每次+2px,同时生成随机颜色赋值给文字色; +- 图片边框交互:鼠标移入(`mouseenter`)添加蓝色双边框,移出(`mouseleave`)重置边框,利用无冒泡的鼠标事件实现精准交互。 + +## 二、CSS 过渡(transition)与鼠标交互动画 +### 核心知识点 +1. **CSS transition 实现平滑动画**: + - 语法:`transition: 过渡属性 时长 缓动函数;`(可同时指定多个属性); + - 示例:`transition: width 0.3s ease,background-color 0.3s ease;`(宽度、背景色变化均0.3秒平滑过渡); + - 缓动函数 `ease`:默认值,效果为“先慢→快→慢”,是最符合直觉的过渡效果。 +2. **批量元素事件绑定**: + - 用 `document.querySelectorAll('.类名')` 获取所有同类元素; + - 通过 `forEach` 遍历元素,批量绑定事件(避免重复写事件绑定代码)。 +3. **样式切换逻辑**:鼠标移入修改目标样式(尺寸/背景色),移出恢复初始值,结合 `transition` 让样式变化无卡顿,提升交互体验。 + +### 练习要点 +- 讨论区模块交互案例: + - CSS 定义初始样式(宽度200px、背景色#ffd700)和过渡属性; + - 鼠标移入时宽度改为220px、背景色改为#fff176,移出恢复初始值; + - 核心优势:动画由CSS `transition` 处理,JS仅需修改样式值,代码简洁且动画更流畅。 + +## 三、自定义拖拽功能实现(绝对定位+鼠标事件) +拖拽是前端高频交互需求,核心依赖**绝对定位**和**鼠标事件组合**实现。 + +### 核心知识点 +1. **基础样式前提**: + - 拖拽元素必须设置 `position: absolute`(只有绝对定位才能通过 `top/left` 自由修改位置); + - 可选:`cursor: move` 提示用户元素可拖拽,提升交互友好性。 +2. **拖拽核心三步逻辑**: + ```mermaid + graph TD + A[鼠标按下(mousedown)] -->|1.记录初始值| B(记录鼠标坐标clientX/clientY、元素初始top/left,提升z-index避免遮挡) + B --> C[鼠标移动(mousemove)] -->|2.计算偏移| D(更新元素top=初始top+Y偏移,left=初始left+X偏移) + D --> E[鼠标松开(mouseup)] -->|3.清理事件| F(移除mousemove/mouseup事件,恢复z-index) + ``` +3. **关键细节**: + - `e.preventDefault()`:阻止浏览器默认行为(如文本选中、图片默认拖拽),避免干扰; + - `getComputedStyle(elem).top/left`:获取CSS定义的初始位置(而非内联样式),确保初始值准确; + - `parseInt()`:将 `100px` 这类带单位的样式值转为数字,便于计算偏移量。 + +### 练习要点 +- 多张图片拖拽案例: + - 遍历所有拖拽图片,给每张绑定独立的拖拽逻辑; + - 拖动时提升 `z-index` 让当前图片在最上层,松开后恢复,避免遮挡; + - `transform: rotate(角度)`:给图片添加旋转效果,不影响绝对定位和拖拽逻辑,丰富视觉表现。 + +--- + +### 总结 +1. **样式操作**:`getComputedStyle` 获取最终渲染样式,`parseFloat` 处理数值,空字符串重置样式;随机颜色需掌握十六进制生成公式并补零; +2. **交互动画**:CSS `transition` 实现平滑过渡,`mouseenter/mouseleave` 实现精准的移入移出交互,批量元素用 `querySelectorAll+forEach` 绑定事件; +3. **拖拽功能**:绝对定位是基础,mousedown记录初始值、mousemove计算偏移、mouseup清理事件是核心三步,注意阻止默认行为和z-index层级管理。 + + +# 练习 +1. p262 +- +```bash +

魏老帅很师

+ + +``` + +- +```bash + 示例图片 + +``` + +2. p262 +- +```bash + + +
HTML/CSS讨论区
+
JavaScript讨论区
+
C语言讨论区
+
Java讨论区
+
Android讨论区
+
Python讨论区
+ +``` + +- +```bash + 1.(AI) + + + 示例图片1 + 示例图片2 + 示例图片3 + + +``` diff --git "a/\346\235\216\346\231\250\346\273\224/20251211-From\345\257\271\350\261\241.md" "b/\346\235\216\346\231\250\346\273\224/20251211-From\345\257\271\350\261\241.md" new file mode 100644 index 0000000000000000000000000000000000000000..ad55f6d1419abf243eea44ef7a6cb9e71b9f1b3f --- /dev/null +++ "b/\346\235\216\346\231\250\346\273\224/20251211-From\345\257\271\350\261\241.md" @@ -0,0 +1,275 @@ +# 笔记 +## 一、表单基础元素操作(输入框/文本域) +### 核心知识点 +1. **表单元素取值方式**: + - 表单关联取值:`document.表单name.元素name.value`(如 `document.myform.textvelue.value`),适用于表单内元素快速取值,无需单独获取元素; + - ID精准取值:`document.getElementById('id').value`,通用且不受表单结构限制,是**推荐优先使用**的方式; +2. **文本域(textarea)动态尺寸修改**: + - 获取当前尺寸:`parseInt(window.getComputedStyle(textarea).height)`,提取带单位(如95px)的数值部分,便于计算; + - 修改尺寸:`textarea.style.height = `${新值}px``,直接赋值内联样式覆盖初始样式; + - 边界控制:修改前添加下限判断(如 `if (curheight > 30)`),避免尺寸无限缩小导致交互异常; +3. **文本域溢出优化**:CSS设置 `overflow: auto`,当内容超出文本域尺寸时自动显示滚动条,保证内容可查看。 + +### 练习要点 +- 电影票兑换码验证:通过表单name快速获取输入框值,与固定兑换码对比,核心体现“取值→判断→提示”的基础表单验证逻辑; +- 文本域尺寸调整:点击“增加/减少”按钮修改高度,减少操作时加下限判断(最小30px),避免尺寸异常。 + +## 二、单选框(radio)交互 +### 核心知识点 +1. **单选框核心特性**:`name` 属性相同的单选框为一组,同一时间仅能选中一个,是实现“唯一选择”的基础; +2. **选中项获取**:`document.querySelector('input[name="xxx"]:checked')`,返回当前选中的单选框元素; + - 关键注意:未选中任何选项时返回 `null`,需先判断是否存在选中项,再获取 `value`; +3. **验证逻辑三步法**: + 1. 判断是否选中(`if (!selected)`),提示用户选择; + 2. 对比选中值与正确答案; + 3. 根据对比结果给出提示。 + +### 练习要点 +- 选择题验证案例:先检查是否选中选项,再判断值是否为“C”,覆盖单选框交互的核心场景(空值判断+值对比)。 + +## 三、复选框(checkbox)交互 +### 核心知识点 +1. **复选框批量操作(全选/全不选/反选)**: + - 获取所有复选框:`document.querySelectorAll('.类名')`(返回伪数组),通过 `forEach` 遍历实现批量修改; + - 全选:`forEach(box => box.checked = true)`; + - 全不选:`forEach(box => box.checked = false)`; + - 反选:`forEach(box => box.checked = !box.checked)`(利用 `!` 翻转选中状态,极简实现); +2. **复选框数量限制**: + - 绑定 `change` 事件:选中/取消时实时触发,统计当前选中数量; + - 统计选中数:`Array.from(checkboxes).filter(cb => cb.checked).length`(伪数组转数组后过滤选中项); + - 超出限制处理:将当前复选框 `checked` 设为 `false` 阻止选中,同时弹窗提示; +3. **表单内复选框获取**:`form.elements['name']`(通过form对象按name获取复选框组),更贴合表单上下文。 + +### 练习要点 +- 兴趣爱好选择:仅需3行forEach逻辑实现全选、全不选、反选,是复选框批量操作的典型应用; +- 课程选择限制:最多选6个,在change事件中统计数量,超出则取消当前选中,解决“多选限制”的常见需求。 + +## 四、下拉选择框(select)交互(省市联动) +### 核心知识点 +1. **下拉框核心操作**: + - 初始化选项:通过 `innerHTML` 拼接 ``).join('')`,遍历数组生成选项并拼接成字符串,避免多次修改innerHTML; +2. **联动核心逻辑**: + - 给省份下拉框绑定 `onchange` 事件,选中值变化时即时触发; + - 根据选中省份,从数据对象中获取对应城市列表,动态更新城市选项; + - 无省份选中时,城市下拉框恢复“请选省份”提示项; +3. **数据结构**:用对象存储省市映射(键:省份名,值:城市数组),结构清晰,便于联动取值。 + +### 练习要点 +- 省市联动案例: + - 初始化:拼接默认提示项 + 省份选项; + - 联动:省份切换时动态更新城市选项,无选中则恢复提示项,是下拉框联动的经典实战场景。 + +--- + +### 总结 +1. **表单取值**:优先用ID取值(通用精准),form对象取值适用于表单内快速操作,所有输入类元素均通过 `.value` 获取值; +2. **单选/复选框**:单选框需先判断是否选中,复选框批量操作依赖 `forEach`,数量限制需在 `change` 事件中统计并拦截; +3. **下拉框联动**:基于 `onchange` 事件,结合对象数据结构动态生成子选项,`map+join` 提升选项拼接效率; +4. **边界控制**:文本域尺寸、复选框数量等需添加边界判断,避免交互异常,提升用户体验。 + + +# 练习 +1. p275 +- +```bash +
+ + +
+ +``` + +- +```bash + + +
+ +
+
+ + +
+ +``` + +- +```bash + 1.(AI) +
+

请选择课程(最多选6个)

+
+ + + + + + + + +
+
+ + +``` + +2. p275实践与练习 +- +```bash +

选择题:请选择“C”

+ A
+ B
+ C
+ D
+ + + + +``` + +- +```bash +

选择兴趣爱好

+ + 阅读
+ 运动
+ 听歌
+ 编程
+ 旅游
+ + + + + + + +``` + +- +```bash + 省份: + 城市: + + +``` + diff --git "a/\346\235\216\346\231\250\346\273\224/20251212-API.md" "b/\346\235\216\346\231\250\346\273\224/20251212-API.md" new file mode 100644 index 0000000000000000000000000000000000000000..d4e8a19aca55bbc5f55795142cfac83c521e4045 --- /dev/null +++ "b/\346\235\216\346\231\250\346\273\224/20251212-API.md" @@ -0,0 +1,24 @@ +# JS 核心知识点笔记(JSON + Fetch API) +## 一、JSON +### 1. 核心概念 +JSON(JavaScript Object Notation):轻量级数据交换格式,跨语言、易读易解析,是前后端数据交互的主流格式。 + +### 2. 核心方法(必记) +| 方法 | 作用 | 示例 | +|------|------|------| +| `JSON.parse()` | 把JSON字符串 → JS对象/数组(处理后端返回数据) | `const obj = JSON.parse('{"name":"张三","age":20}')` | +| `JSON.stringify()` | 把JS对象/数组 → JSON字符串(向后端发送数据) | `const str = JSON.stringify({name:"张三",age:20})` | + +### 3. 关键注意点 +- 键名必须用**双引号**包裹(单引号/无引号均无效); +- 不支持函数、undefined 类型(序列化时会被忽略)。 + +## 二、Fetch API +### 1. 核心概念 +现代浏览器原生异步网络请求接口,替代传统 XMLHttpRequest,基于 Promise 实现,语法更简洁。 + +### 2. 关键要点(避坑核心) +1. 响应处理:Response 对象需手动解析(`json()`/`text()` 等),且解析操作是异步的; +2. 错误处理:仅网络错误/请求无法完成时触发 `catch`,HTTP 错误(404/500等)需通过 `response.ok` 判断; +3. Cookie 配置:默认不携带 Cookie,需手动配置 `credentials: 'include'`; +4. 请求中断:支持 `AbortController` 中断正在进行的请求。 \ No newline at end of file diff --git "a/\346\235\216\346\231\250\346\273\224/20251215-200\347\273\203\344\271\240.md" "b/\346\235\216\346\231\250\346\273\224/20251215-200\347\273\203\344\271\240.md" new file mode 100644 index 0000000000000000000000000000000000000000..45bd5c4d8f82007fce975e24ad00fe1ea17d0bf2 --- /dev/null +++ "b/\346\235\216\346\231\250\346\273\224/20251215-200\347\273\203\344\271\240.md" @@ -0,0 +1,21 @@ +## jQuery基础 +1. +```bash + $(document).ready(function(){ + console.log("jQuery 已就绪"); + }); +``` + +2. +```bash + $(function(){ + let isSame = $ ===jQuery; + console.log(isSame); + }); +``` + +3. +```bash + let $demo = $("#demo"); + console.log($demo); +``` \ No newline at end of file diff --git "a/\346\235\216\346\231\250\346\273\224/20251217-200\347\273\203\344\271\240.md" "b/\346\235\216\346\231\250\346\273\224/20251217-200\347\273\203\344\271\240.md" new file mode 100644 index 0000000000000000000000000000000000000000..07157a109e23ac9a0b448dbdc15a12810008bfa8 --- /dev/null +++ "b/\346\235\216\346\231\250\346\273\224/20251217-200\347\273\203\344\271\240.md" @@ -0,0 +1,76 @@ +## 流程控制 +1. +```bash + let score = 85; + if (score > 90) { + document.write('优秀'); + } + if(score>=80&&score<=89){ + document.write('良好'); + } + if(score>=60&&score<=79){ + document.write('及格'); + } + if(score<60){ + document.write('不及格'); + } +``` + +2. +```bash + let n = 100; + let num1 = 0; + for(let num = 1; num<=n;num++){ + num1+=num; + } + document.write(num1); +``` + +3. +```bash + let arr =[ + 1,2,3,4,5,6,7,8 + ]; + for(let i = 0;i<=arr.length;i++){ + if(arr[i]%2==0){ + document.write(arr[i]); + } + } +``` + +4. +```bash + let num = 17; + if (num > 1) { + if (num % 1 == 0 && num%num==0) { + document.write('true'); + } + } +``` + +5. +```bash + let num = 1; + while(num<20){ + if(num%3==0){ + document.write(num); + } + num++; + } +``` + +6. +```bash + let dayOfWeek = Number(prompt()); + switch(dayOfWeek){ + case 1: + document.write("今天是工作日,要上班"); + break; + case 2: + document.write("今天是工作日,不要上班"); + break; + case 3: + document.write("今天是工作日,不要上班"); + break; + } +``` \ No newline at end of file diff --git "a/\346\235\216\346\231\250\346\273\224/20251218-200\347\273\203\344\271\240.md" "b/\346\235\216\346\231\250\346\273\224/20251218-200\347\273\203\344\271\240.md" new file mode 100644 index 0000000000000000000000000000000000000000..819a68346177badc5a60bb73780d8b04499ec6bc --- /dev/null +++ "b/\346\235\216\346\231\250\346\273\224/20251218-200\347\273\203\344\271\240.md" @@ -0,0 +1,41 @@ +## 数组 +1. +```bash + let arr = [1, 2, 3, 4]; + function sum(arr) { + let s = 0; + for (let i = 0; i < arr.length; i++) { + s+=arr[i]; + } + return s; + } + console.log(sum(arr)); +``` + +2. +```bash + function mergeArrays() { + return [...arr1,...arr2]; + } + let arr1 = [1, 2, 3, 4]; + let arr2 = ['a', 'b', 'c', 1]; + let arr3 = mergeArrays(arr1,arr2); + console.log(arr3); +``` + +3. +```bash + let item = 4; + let arr = [1, 2, 4, 4, 3, 4, 3]; + function counts(arr, item) { + let count = 0; + for (let i = 0; i < arr.length; i++) { + if(arr[i]===item){ + count++; + } + } + return count; + } + console.log(counts(arr,item)); + +``` \ No newline at end of file diff --git "a/\346\235\216\346\231\250\346\273\224/20251219-200\347\273\203\344\271\240.md" "b/\346\235\216\346\231\250\346\273\224/20251219-200\347\273\203\344\271\240.md" new file mode 100644 index 0000000000000000000000000000000000000000..5a418cc2f3ba4c4060147cfbe61c99eb7fc7c2e1 --- /dev/null +++ "b/\346\235\216\346\231\250\346\273\224/20251219-200\347\273\203\344\271\240.md" @@ -0,0 +1,37 @@ +## 数组高阶函数(重点) +7. +```bash + let arr = [1, 2, 3, 4, 5]; + function num1(arr) { + return arr.map(num => num * 2); + } + console.log(num1(arr)); +``` + +8. +```bash + let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]; + function oddNumber(arr) { + return arr.filter(num => num % 2 !== 0) + } + console.log(oddNumber(arr)); +``` + +9. +```bash + let arr = [10, 20, 30, 40, 50]; + function sum(arr) { + // 累加器(acc)和当前元素(curr)参数,设置初始值0 + return arr.reduce((acc, curr) => acc + curr, 0); + } + console.log(sum(arr)); +``` + +10. +```bash + let arr = [3, 7, 2, 9, 1, 5]; + function maxNum(arr) { + return arr.reduce((prev, curr) => Math.max(prev, curr), arr[0]); + } + console.log(maxNum(arr)); +``` \ No newline at end of file diff --git "a/\346\235\216\346\231\250\346\273\224/20251222-200\347\273\203\344\271\240.md" "b/\346\235\216\346\231\250\346\273\224/20251222-200\347\273\203\344\271\240.md" new file mode 100644 index 0000000000000000000000000000000000000000..9184f19389e61a23889690d34dc90c2d67b3c8ce --- /dev/null +++ "b/\346\235\216\346\231\250\346\273\224/20251222-200\347\273\203\344\271\240.md" @@ -0,0 +1,86 @@ +7. +```bash + let arr = [ + '苹果', '香蕉', '橙子' + ]; + for(let value of arr){ + document.write(value); + } +``` + +8. +```bash + let object = { name: '张三', age: 20, city: '北京' }; + for (const property in object) { + console.log(`${property}: ${object[property]}`); + } +``` + +9. +```bash + let arr = [-5, 1, 4, 50, 60]; + for (const num of arr) { + if (num < 0) { + continue; + } + if (num > 50) { + document.write(num); + break; + } + } +``` + +10. +```bash + for(let i = 1 ;i<=9;i++){ + for(let j = 1;j<=9;j++){ + document.write(`${i}*${j}=${i*j}
`); + } + } +``` + +11. +```bash + let age = 18; + let status1,status2; + + status1 = age >=18?'成年':'未成年'; + + if (age >= 18) { + status2 = '成年'; + } else { + status2 = '未成年'; + } + + console.log("三元运算符实现:"); + console.log(`let status1 = age >= 18 ? '成年' : '未成年'; 结果:${status1}`); + + console.log("\nif-else 实现:"); + console.log(`if (age >= 18) { status2 = '成年'; } else { status2 = '未成年'; } 结果:${status2}`); +``` + +12. +```bash + let num = Math.floor(Math.random() * 100) + 1; + while (true) { + let guess = prompt('请输入你猜测的数字(1-100):'); + if(guess ===null){ + alert('游戏已取消'); + continue; + } + if (guess < 1 || guess > 100) { + alert('请输入区域内的数字!'); + } else { + if (guess > num) { + alert('太大啦!'); + } + if (guess == num) { + alert('恭喜你猜对啦!'); + break; + } + if (guess < num) { + alert('太小啦!'); + } + } + } +``` \ No newline at end of file diff --git "a/\346\235\216\346\231\250\346\273\224/20251224-200\347\273\203\344\271\240.md" "b/\346\235\216\346\231\250\346\273\224/20251224-200\347\273\203\344\271\240.md" new file mode 100644 index 0000000000000000000000000000000000000000..86ff9f5b23a065341b2b1ab328f6fef419c11d37 --- /dev/null +++ "b/\346\235\216\346\231\250\346\273\224/20251224-200\347\273\203\344\271\240.md" @@ -0,0 +1,41 @@ +4. +```bash + let arr = [1,2,4,4,3,3,1,5,3]; + function find(arr){ + const countMap = new Map(); + const duplicates = []; + + for (const item of arr){ + countMap.set(item,(countMap.get(item)||0)+1); + } + + for(const [key,value] of countMap){ + if(value>=2){ + duplicates.push(key); + } + } + return duplicates; + } + console.log(find(arr)); +``` + +5. +```bash + let arr = [1,2,3,4,2,5] + let item = 2; + function remove(arr,item){ + return arr.filter(element => element !==item); + } + console.log(remove(arr,item)); +``` + +6. +```bash + let arr = [{ name: "小明", score: 85 }, { name: "小红", score: 55 }, { name: "小刚", score: 90 }]; + function getPassed(arr) { + return arr + .filter(arr => arr.score >= 60) + .map(arr => arr.name); + } + console.log(getPassed(arr)); +``` \ No newline at end of file diff --git "a/\346\235\216\346\231\250\346\273\224/20251225-200\347\273\203\344\271\240.md" "b/\346\235\216\346\231\250\346\273\224/20251225-200\347\273\203\344\271\240.md" new file mode 100644 index 0000000000000000000000000000000000000000..b9f3d2606c1a63aaf7f94cdbf108fef955da667c --- /dev/null +++ "b/\346\235\216\346\231\250\346\273\224/20251225-200\347\273\203\344\271\240.md" @@ -0,0 +1,111 @@ +14. +```bash + let arr = [1, 2, 3, 4, 5]; + function allNum(arr) { + return arr.every(num => num > 0); + } + console.log(allNum(arr)); +``` + +15. +```bash + let arr = [40, 100, 1, 5, 25, 10]; + function allNum(arr) { + return arr.sort((a, b) => a - b); + } + console.log(allNum(arr)); +``` + +16. +```bash + let arr = [{ name: "小明", age: 20 }, { name: "小红", age: 18 }, { name: "小刚", age: 22 }]; + function allNum(arr) { + return [...arr].sort((a, b) => a.age - b.age); + } + console.log(allNum(arr)); +``` + +17. +```bash + let arr = ['apple', 'banana', 'orange']; + function printArr(arr) { + let output = ''; + arr.forEach((item, index) => { + output += `索引${index}: ${item} `; + }); + console.log(output.trim()); + } + printArr(arr); +``` + +18. +```bash + let arr = [[1, 2], [3, 4], [5, 6]]; + function flattening(arr) { + return arr.reduce((acc, curr) => acc.concat(curr), []); + } + console.log(flattening(arr)); +``` + +19. +```bash + let arr = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple']; + function appear(arr) { + return arr.reduce((acc, curr) => { + acc[curr] = (acc[curr] ?? 0) + 1; + return acc; + }, {}); + } + console.log(appear(arr)); +``` +20. +```bash + let arr = [{ name: "鼠标", price: 29 }, { name: "键盘", price: 89 }, { name: "显示器", price: 899 }, { name: "耳机", price: 199 }]; + function name(arr) { + return arr + .filter(arr => arr.price > 50) + .sort((a, b) => a.price - b.price); + } + console.log(name(arr)); +``` +21. +```bash + let arr = [2, 5, 8, 3, 9]; + function name(arr) { + return arr + .map(num => num * 2) + .filter(num => num > 10); + } + console.log(name(arr)); +``` +22. +```bash + let arr = [1, 2, 2, 3, 4, 4, 5, 1]; + function deduplication(arr) { + return arr.reduce((acc, curr) => { + !acc.includes(curr) && acc.push(curr); + return acc; + }, []); + } + console.log(deduplication(arr)); +``` +23. +```bash + let arr = [{ name: "小明", score: 85 }, { name: "小红", score: 92 }, { name: "小刚", score: 78 }, { name: "小丽", score: 88 }]; + function averageScore(arr) { + if (arr.length === 0) return 0; + const totalScore = arr.reduce((acc, curr) => acc + curr.score, 0); + return totalScore / arr.length + } + console.log(averageScore(arr)); +``` +24. +```bash + let arr = [{ name: "张三", age: 17 }, { name: "李四", age: 20 }, { name: "王五", age: 25 }, { name: "赵六", age: 16 }]; + function adults() { + return arr + .filter(arr => arr.age > 18) + .map(item => `${item.name}(${item.age}岁)`); + } + console.log(adults(arr)); +``` \ No newline at end of file diff --git "a/\346\235\216\346\231\250\346\273\224/20251226-200\347\273\203\344\271\240.md" "b/\346\235\216\346\231\250\346\273\224/20251226-200\347\273\203\344\271\240.md" new file mode 100644 index 0000000000000000000000000000000000000000..aaeed9e4500acf7e32ce6d40858e526b16244f8e --- /dev/null +++ "b/\346\235\216\346\231\250\346\273\224/20251226-200\347\273\203\344\271\240.md" @@ -0,0 +1,26 @@ +11. +```bash + let arr = [2, 5, 8, 12, 15, 7]; + function firstMaxNum(arr) { + return arr.find(num => num > 10); + } + console.log(firstMaxNum(arr)); +``` + +12. +```bash + let arr = [1, 5, 3, -2, 8, -5]; + function firstNegativeNum(arr) { + return arr.findIndex(num => num < 0); + } + console.log(firstNegativeNum(arr)); +``` + +13. +```bash + let arr = [1, 3, 5, 7, 8]; + function evenNum(arr) { + return arr.some(num => num % 2 == 0); + } + console.log(evenNum(arr)); +``` \ No newline at end of file diff --git "a/\346\235\216\346\231\250\346\273\224/20251229-200\347\273\203\344\271\240.md" "b/\346\235\216\346\231\250\346\273\224/20251229-200\347\273\203\344\271\240.md" new file mode 100644 index 0000000000000000000000000000000000000000..a04498aab5a38f1b49a0e05214cc5dbf1d8641a4 --- /dev/null +++ "b/\346\235\216\346\231\250\346\273\224/20251229-200\347\273\203\344\271\240.md" @@ -0,0 +1,159 @@ +## 函数 +1. +```bash + function greet(name) { + return `你好,${name}!`; + } + document.write(greet("小明")); +``` + +2. +```bash + function max(num1, num2) { + if (num1 > num2) { + return num1; + } + if (num2 > num1) { + return num2; + } + } + document.write(max(15, 23)); +``` + +3. +```bash + function calculateArea(num) { + return `正方形的面积为${num * num}`; + } + document.write(calculateArea(5)); +``` + +4. +```bash + let filterEven = (arr) => { + return arr.filter(num => num % 2 == 0); + }; + document.write(filterEven([1, 2, 3, 4, 5, 6])); +``` + +5. +```bash + function sumAll(...num) { + let s = 0; + for (let i = 0; i < num.length; i++) { + s += num[i]; + } + return s; + } + document.write(sumAll(1, 2, 3, 4, 5)); +``` + +6. +```bash + // ========== 1. 函数声明:可以在定义前调用(函数提升) ========== + // 先调用函数声明(此时函数还未定义,但依然能执行) + console.log("函数声明调用结果:", callDeclaration()); + + // 定义函数声明 + function callDeclaration() { + return "函数声明可以在定义前调用(函数提升)"; + } + + // ========== 2. 函数表达式:只能在定义后调用(无函数提升) ========== + // ❌ 错误示范:如果在定义前调用函数表达式,会报错 + // console.log(callExpression()); // 执行这行会报错:callExpression is not a function + + // 定义函数表达式(将函数赋值给变量) + const callExpression = function() { + return "函数表达式只能在定义后调用"; + }; + + // ✅ 正确示范:在定义后调用函数表达式 + console.log("函数表达式调用结果:", callExpression()); +``` + +7. +```bash + function jsq() { + let count = 0; + return function () { + count++; + return count; + }; + } + let counter = jsq(); + console.log("第一次调用:", counter()); + console.log("第二次调用:", counter()); + console.log("第三次调用:", counter()); +``` + +8. +```bash + // ========== 1. 定义全局变量 ========== + // 全局变量:在所有函数外部定义,作用域覆盖整个脚本 + let globalVar = "我是全局变量"; + + // ========== 2. 定义函数,演示变量访问规则 ========== + function testScope() { + // 局部变量:在函数内部定义,仅作用于函数内部 + let localVar = "我是局部变量"; + + // 函数内部:既能访问局部变量,也能访问全局变量 + console.log("函数内部访问 → " + localVar); // 输出:函数内部访问 → 我是局部变量 + console.log("函数内部访问 → " + globalVar); // 输出:函数内部访问 → 我是全局变量 + } + + // ========== 3. 执行函数 ========== + testScope(); + + // ========== 4. 函数外部验证访问规则 ========== + console.log("------------------------"); + // 全局作用域:能访问全局变量 + console.log("函数外部访问 → " + globalVar); // 输出:函数外部访问 → 我是全局变量 + + // 全局作用域:无法访问函数内的局部变量(执行这行会报错) + try { + console.log("函数外部访问 → " + localVar); + } catch (error) { + console.log("函数外部访问局部变量 → 报错:" + error.message); + // 输出:函数外部访问局部变量 → 报错:localVar is not defined + } + + // ========== 补充:块级作用域(let/const) ========== + console.log("------------------------"); + if (true) { + let blockVar = "我是块级局部变量(if块内)"; + console.log("if块内部访问 → " + blockVar); // 输出:if块内部访问 → 我是块级局部变量(if块内) + } + // if块外部无法访问块级变量 + try { + console.log("if块外部访问 → " + blockVar); + } catch (error) { + console.log("if块外部访问块级变量 → 报错:" + error.message); + // 输出:if块外部访问块级变量 → 报错:blockVar is not defined + } +``` + +9. +```bash + function processArray(arr, callback) { + const news = []; + for (let i = 0; i < arr.length; i++) { + news.push(callback(arr[i])); + } + return news; + } + document.write(processArray([1, 2, 3, 4], (num) => num * 2)); +``` + +10. +```bash + function factorial(n) { + let s = 1; + for (let i = 1; i <= n; i++) { + s *= i; + } + return s; + } + document.write(factorial(5)); +``` \ No newline at end of file diff --git "a/\346\235\216\346\231\250\346\273\224/24\347\272\247\345\205\250\346\240\210\345\274\200\345\217\221\346\226\271\345\220\221js\347\273\203\344\271\240\351\233\206.md" "b/\346\235\216\346\231\250\346\273\224/24\347\272\247\345\205\250\346\240\210\345\274\200\345\217\221\346\226\271\345\220\221js\347\273\203\344\271\240\351\233\206.md" new file mode 100644 index 0000000000000000000000000000000000000000..db06d2a97f1dc329f1f6dc62a53952c5a51f0a2e --- /dev/null +++ "b/\346\235\216\346\231\250\346\273\224/24\347\272\247\345\205\250\346\240\210\345\274\200\345\217\221\346\226\271\345\220\221js\347\273\203\344\271\240\351\233\206.md" @@ -0,0 +1,794 @@ +# 一、JavaScript基础 +## 变量、常量与基础数据类型 +1. +```bash + let name = "lct"; + const SCHOOL = "某某职业学院"; + document.write(name+SCHOOL); +``` + +2. +```bash + let value = 123; + document.write( typeof value); +``` + +3. +```bash + let age = 18; + age =20; + document.write(age); +``` + +4. +```bash + let name = '李四'; + let age = 19; + let grade = true; + document.write(name + typeof name); + document.write('
' + age + typeof age); + document.write('
' + grade + typeof grade); +``` + +5. +```bash + let nu = null; + let un; + document.write('undefinde变量:'+un+',类型:'+typeof un); + document.write('
null变量:'+nu+',类型:'+typeof nu); +``` + +6. +```bash + let num1 = 123; + const num2 =456; + var num3 = 789; + document.write(`${num1}
${num2}
${num3}
let和const有块级作用域var只有函数作用域`); +``` + +7. +```bash + document.write(num1); + var num1 = 1; + document.write(num2); + let num2 = 1; + document.write(num3); + const num3 = 1; +``` + +8. +```bash + let name = "张三"; + let age = 20; + let score = 85; + document.write(`${name}今年${age}岁,考了${score}分,${score>=60?'及格':'不及格'}`); +``` + +9. +```bash + // 基本数据类型和引用数据类型区别 + // 基本类型 + let num = 123; + let str = "hello"; + let bool = true; + let undef = undefined; + let nul = null; + let sym = Symbol("sym"); + let bigInt = 123n; + + // 引用类型 + let obj = { name: "test" }; + let arr = [1, 2, 3]; + let func = function () { }; + + console.log("基本类型:Number、String、Boolean、Undefined、Null、Symbol、BigInt"); + console.log("引用类型:Object、Array、Function"); + + // 验证类型 + console.log("\n类型验证:"); + console.log(typeof num); // number + console.log(typeof str); // string + console.log(typeof bool); // boolean + console.log(typeof undef); // undefined + console.log(typeof nul); // object(历史遗留问题) + console.log(typeof sym); // symbol + console.log(typeof bigInt); // bigint + console.log(typeof obj); // object + console.log(typeof arr); // object + console.log(typeof func); // function +``` + +## 运算符与类型转换 +1. +```bash + let a = 10; + let b = 3; + document.write(`加:${a+b},减:${a-b},乘:${a*b},除:${a/b},余:${a%b}`); +``` + +2. +```bash + let num1 = Number('123'); + let num2 = String(456); + document.write(`转换后的数字: ${num1}, 类型: ${typeof num1}`); + document.write(`
转换后的数字: ${num2}, 类型: ${typeof num2}`); +``` + +3. +```bash + let a = 5; + let b = 3; + let c1 = Boolean(a>b); + let c2 = Boolean(a==b); + let c3 = Boolean(a!=b); + document.write(`大于:${c1},等于:${c2},不等于:${c3}`); +``` + +4. +```bash + let x = "5"; + let y = 5; + let z = "5"; + document.write(`x==y:${Boolean(x==y)},x===y:${Boolean(x===y)},x==z:${Boolean(x==z)},x===z:${Boolean(x===z)}`); +``` + +5. +```bash + let age = 25; + let hasLicense = true; + document.write(`${Boolean(18<=age&&age<=60&&hasLicense==true)}(可以开车)`); +``` + +6. +```bash + let a1 = "5" + 3; + let a2 = "5" - 3; + let a3 = true + 1; + let a4 = "10" * "2"; + document.write(`${a1},${a2},${a3},${a4}`); +``` + +7. +```bash + let a1 = +"123"; + let a2 = -"45"; + let a3 = !!"hello"; + document.write(`${a1},${a2},${a3}`); +``` + +8. +```bash + document.write(`NaN === NaN // ${NaN === NaN}`); + document.write(`
isNaN(NaN) // ${isNaN(NaN)}`); + document.write(`
Number.isNaN(NaN) // ${Number.isNaN(NaN)}`); +``` + +9. +```bash + let input = "5.8,7"; + let [f,n]=input.split(',').map(x => x.trim()); + let round = ~~f; + let odd = n & 1; + console.log(`~~${f} = ${round} (取整) ${n} & 1 = ${odd} (判断奇偶,结果为${odd}表示${odd ? '奇数' : '偶数'})`); +``` + +10. +```bash + let score = 85; + let userName = ""; + let level = score >=60?'及格':'不及格'; + let name = userName ||'游客'; + console.log(`const level = score >= 60 ? '及格' : '不及格'; const name = userName || '游客';`); + console.log(`level = ${level},name =${name}`); +``` + +## 流程控制 +1. +```bash + let score = 85; + if (score > 90) { + document.write('优秀'); + } + if(score>=80&&score<=89){ + document.write('良好'); + } + if(score>=60&&score<=79){ + document.write('及格'); + } + if(score<60){ + document.write('不及格'); + } +``` + +2. +```bash + let n = 100; + let num1 = 0; + for(let num = 1; num<=n;num++){ + num1+=num; + } + document.write(num1); +``` + +3. +```bash + let arr =[ + 1,2,3,4,5,6,7,8 + ]; + for(let i = 0;i<=arr.length;i++){ + if(arr[i]%2==0){ + document.write(arr[i]); + } + } +``` + +4. +```bash + let num = 17; + if (num > 1) { + if (num % 1 == 0 && num%num==0) { + document.write('true'); + } + } +``` + +5. +```bash + let num = 1; + while(num<20){ + if(num%3==0){ + document.write(num); + } + num++; + } +``` + +6. +```bash + let dayOfWeek = Number(prompt()); + switch(dayOfWeek){ + case 1: + document.write("今天是工作日,要上班"); + break; + case 2: + document.write("今天是工作日,不要上班"); + break; + case 3: + document.write("今天是工作日,不要上班"); + break; + } +``` + +7. +```bash + let arr = [ + '苹果', '香蕉', '橙子' + ]; + for(let value of arr){ + document.write(value); + } +``` + +8. +```bash + let object = { name: '张三', age: 20, city: '北京' }; + for (const property in object) { + console.log(`${property}: ${object[property]}`); + } +``` + +9. +```bash + let arr = [-5, 1, 4, 50, 60]; + for (const num of arr) { + if (num < 0) { + continue; + } + if (num > 50) { + document.write(num); + break; + } + } +``` + +10. +```bash + for(let i = 1 ;i<=9;i++){ + for(let j = 1;j<=9;j++){ + document.write(`${i}*${j}=${i*j}
`); + } + } +``` + +11. +```bash + let age = 18; + let status1,status2; + + status1 = age >=18?'成年':'未成年'; + + if (age >= 18) { + status2 = '成年'; + } else { + status2 = '未成年'; + } + + console.log("三元运算符实现:"); + console.log(`let status1 = age >= 18 ? '成年' : '未成年'; 结果:${status1}`); + + console.log("\nif-else 实现:"); + console.log(`if (age >= 18) { status2 = '成年'; } else { status2 = '未成年'; } 结果:${status2}`); +``` + +12. +```bash + let num = Math.floor(Math.random() * 100) + 1; + while (true) { + let guess = prompt('请输入你猜测的数字(1-100):'); + if(guess ===null){ + alert('游戏已取消'); + continue; + } + if (guess < 1 || guess > 100) { + alert('请输入区域内的数字!'); + } else { + if (guess > num) { + alert('太大啦!'); + } + if (guess == num) { + alert('恭喜你猜对啦!'); + break; + } + if (guess < num) { + alert('太小啦!'); + } + } + } +``` +# 二、核心数据结构与函数 +## 数组 +1. +```bash + let arr = [1, 2, 3, 4]; + function sum(arr) { + let s = 0; + for (let i = 0; i < arr.length; i++) { + s+=arr[i]; + } + return s; + } + console.log(sum(arr)); +``` + +2. +```bash + function mergeArrays() { + return [...arr1,...arr2]; + } + let arr1 = [1, 2, 3, 4]; + let arr2 = ['a', 'b', 'c', 1]; + let arr3 = mergeArrays(arr1,arr2); + console.log(arr3); +``` + +3. +```bash + let item = 4; + let arr = [1, 2, 4, 4, 3, 4, 3]; + function counts(arr, item) { + let count = 0; + for (let i = 0; i < arr.length; i++) { + if(arr[i]===item){ + count++; + } + } + return count; + } + console.log(counts(arr,item)); + +``` + +4. +```bash + let arr = [1,2,4,4,3,3,1,5,3]; + function find(arr){ + const countMap = new Map(); + const duplicates = []; + + for (const item of arr){ + countMap.set(item,(countMap.get(item)||0)+1); + } + + for(const [key,value] of countMap){ + if(value>=2){ + duplicates.push(key); + } + } + return duplicates; + } + console.log(find(arr)); +``` + +5. +```bash + let arr = [1,2,3,4,2,5] + let item = 2; + function remove(arr,item){ + return arr.filter(element => element !==item); + } + console.log(remove(arr,item)); +``` + +6. +```bash + let arr = [{ name: "小明", score: 85 }, { name: "小红", score: 55 }, { name: "小刚", score: 90 }]; + function getPassed(arr) { + return arr + .filter(arr => arr.score >= 60) + .map(arr => arr.name); + } + console.log(getPassed(arr)); +``` + +## 数组高阶函数(重点) +7. +```bash + let arr = [1, 2, 3, 4, 5]; + function num1(arr) { + return arr.map(num => num * 2); + } + console.log(num1(arr)); +``` + +8. +```bash + let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]; + function oddNumber(arr) { + return arr.filter(num => num % 2 !== 0) + } + console.log(oddNumber(arr)); +``` + +9. +```bash + let arr = [10, 20, 30, 40, 50]; + function sum2(arr) { + return arr.reduce((a, b) => a + b, 0); + } + console.log(sum2(arr)); // 输出 150 +``` + +10. +```bash + let arr = [3, 7, 2, 9, 1, 5]; + function findMax(arr) { + return arr.reduce((a, b) => a > b ? a : b, arr[0]); + } + console.log(findMax(arr)); +``` + +11. +```bash + let arr = [2, 5, 8, 12, 15, 7]; + function firstMaxNum(arr) { + return arr.find(num => num > 10); + } + console.log(firstMaxNum(arr)); +``` + +12. +```bash + let arr = [1, 5, 3, -2, 8, -5]; + function firstNegativeNum(arr) { + return arr.findIndex(num => num < 0); + } + console.log(firstNegativeNum(arr)); +``` + +13. +```bash + let arr = [1, 3, 5, 7, 8]; + function evenNum(arr) { + return arr.some(num => num % 2 == 0); + } + console.log(evenNum(arr)); +``` + +14. +```bash + let arr = [1, 2, 3, 4, 5]; + function allNum(arr) { + return arr.every(num => num > 0); + } + console.log(allNum(arr)); +``` + +15. +```bash + let arr = [40, 100, 1, 5, 25, 10]; + function allNum(arr) { + return arr.sort((a, b) => a - b); + } + console.log(allNum(arr)); +``` + +16. +```bash + let arr = [{ name: "小明", age: 20 }, { name: "小红", age: 18 }, { name: "小刚", age: 22 }]; + function allNum(arr) { + return [...arr].sort((a, b) => a.age - b.age); + } + console.log(allNum(arr)); +``` + +17. +```bash + let arr = ['apple', 'banana', 'orange']; + function printArrWithIndex(arr) { + arr.forEach((item, index) => { + console.log(`索引${index}: ${item}`); + }); + } + printArrWithIndex(arr); +``` + +18. +```bash + let arr = [[1, 2], [3, 4], [5, 6]]; + function flattening(arr) { + return arr.reduce((a, b) => a.concat(b), []); + } + console.log(flattening(arr)); +``` + +19. +```bash + let arr = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple']; + function appear(arr) { + return arr.reduce((acc, curr) => { + acc[curr] = (acc[curr] ?? 0) + 1; + return acc; + }, {}); + } + console.log(appear(arr)); +``` +20. +```bash + let arr = [{ name: "鼠标", price: 29 }, { name: "键盘", price: 89 }, { name: "显示器", price: 899 }, { name: "耳机", price: 199 }]; + function name(arr) { + return arr + .filter(arr => arr.price > 50) + .sort((a, b) => a.price - b.price); + } + console.log(name(arr)); +``` +21. +```bash + let arr = [2, 5, 8, 3, 9]; + function name(arr) { + return arr + .map(num => num * 2) + .filter(num => num > 10); + } + console.log(name(arr)); +``` +22. +```bash + let arr = [1, 2, 2, 3, 4, 4, 5, 1]; + function deduplication(arr) { + return arr.reduce((acc, curr) => { + !acc.includes(curr) && acc.push(curr); + return acc; + }, []); + } + console.log(deduplication(arr)); +``` +23. +```bash + let arr = [{ name: "小明", score: 85 }, { name: "小红", score: 92 }, { name: "小刚", score: 78 }, { name: "小丽", score: 88 }]; + function averageScore(arr) { + if (arr.length === 0) return 0; + const totalScore = arr.reduce((acc, curr) => acc + curr.score, 0); + return totalScore / arr.length + } + console.log(averageScore(arr)); +``` +24. +```bash + let arr = [{ name: "张三", age: 17 }, { name: "李四", age: 20 }, { name: "王五", age: 25 }, { name: "赵六", age: 16 }]; + function adults() { + return arr + .filter(arr => arr.age > 18) + .map(item => `${item.name}(${item.age}岁)`); + } + console.log(adults(arr)); +``` + +## 函数 +1. +```bash + function greet(name) { + return `你好,${name}!`; + } + document.write(greet("小明")); +``` + +2. +```bash + function max(num1, num2) { + if (num1 > num2) { + return num1; + } + if (num2 > num1) { + return num2; + } + } + document.write(max(15, 23)); +``` + +3. +```bash + function calculateArea(num) { + return `正方形的面积为${num * num}`; + } + document.write(calculateArea(5)); +``` + +4. +```bash + let filterEven = (arr) => { + return arr.filter(num => num % 2 == 0); + }; + document.write(filterEven([1, 2, 3, 4, 5, 6])); +``` + +5. +```bash + function sumAll(...num) { + let s = 0; + for (let i = 0; i < num.length; i++) { + s += num[i]; + } + return s; + } + document.write(sumAll(1, 2, 3, 4, 5)); +``` + +6. +```bash + // ========== 1. 函数声明:可以在定义前调用(函数提升) ========== + // 先调用函数声明(此时函数还未定义,但依然能执行) + console.log("函数声明调用结果:", callDeclaration()); + + // 定义函数声明 + function callDeclaration() { + return "函数声明可以在定义前调用(函数提升)"; + } + + // ========== 2. 函数表达式:只能在定义后调用(无函数提升) ========== + // ❌ 错误示范:如果在定义前调用函数表达式,会报错 + // console.log(callExpression()); // 执行这行会报错:callExpression is not a function + + // 定义函数表达式(将函数赋值给变量) + const callExpression = function() { + return "函数表达式只能在定义后调用"; + }; + + // ✅ 正确示范:在定义后调用函数表达式 + console.log("函数表达式调用结果:", callExpression()); +``` + +7. +```bash + function jsq() { + let count = 0; + return function () { + count++; + return count; + }; + } + let counter = jsq(); + console.log("第一次调用:", counter()); + console.log("第二次调用:", counter()); + console.log("第三次调用:", counter()); +``` + +8. +```bash + // ========== 1. 定义全局变量 ========== + // 全局变量:在所有函数外部定义,作用域覆盖整个脚本 + let globalVar = "我是全局变量"; + + // ========== 2. 定义函数,演示变量访问规则 ========== + function testScope() { + // 局部变量:在函数内部定义,仅作用于函数内部 + let localVar = "我是局部变量"; + + // 函数内部:既能访问局部变量,也能访问全局变量 + console.log("函数内部访问 → " + localVar); // 输出:函数内部访问 → 我是局部变量 + console.log("函数内部访问 → " + globalVar); // 输出:函数内部访问 → 我是全局变量 + } + + // ========== 3. 执行函数 ========== + testScope(); + + // ========== 4. 函数外部验证访问规则 ========== + console.log("------------------------"); + // 全局作用域:能访问全局变量 + console.log("函数外部访问 → " + globalVar); // 输出:函数外部访问 → 我是全局变量 + + // 全局作用域:无法访问函数内的局部变量(执行这行会报错) + try { + console.log("函数外部访问 → " + localVar); + } catch (error) { + console.log("函数外部访问局部变量 → 报错:" + error.message); + // 输出:函数外部访问局部变量 → 报错:localVar is not defined + } + + // ========== 补充:块级作用域(let/const) ========== + console.log("------------------------"); + if (true) { + let blockVar = "我是块级局部变量(if块内)"; + console.log("if块内部访问 → " + blockVar); // 输出:if块内部访问 → 我是块级局部变量(if块内) + } + // if块外部无法访问块级变量 + try { + console.log("if块外部访问 → " + blockVar); + } catch (error) { + console.log("if块外部访问块级变量 → 报错:" + error.message); + // 输出:if块外部访问块级变量 → 报错:blockVar is not defined + } +``` + +9. +```bash + function processArray(arr, callback) { + const news = []; + for (let i = 0; i < arr.length; i++) { + news.push(callback(arr[i])); + } + return news; + } + document.write(processArray([1, 2, 3, 4], (num) => num * 2)); +``` + +10. +```bash + function factorial(n) { + let s = 1; + for (let i = 1; i <= n; i++) { + s *= i; + } + return s; + } + document.write(factorial(5)); +``` + + +# 五、jQuery入门 +## jQuery基础 +1. +```bash + $(document).ready(function(){ + console.log("jQuery 已就绪"); + }); +``` + +2. +```bash + $(function(){ + let isSame = $ ===jQuery; + console.log(isSame); + }); +``` + +3. +```bash + let $demo = $("#demo"); + console.log($demo); +``` + +4. +```bash + +``` \ No newline at end of file diff --git "a/\346\235\216\346\231\250\346\273\224/\346\200\235\347\273\264\345\257\274\345\233\276.md" "b/\346\235\216\346\231\250\346\273\224/\346\200\235\347\273\264\345\257\274\345\233\276.md" new file mode 100644 index 0000000000000000000000000000000000000000..2272b0576903a5970136ff9b2fcb6f3868ae181b --- /dev/null +++ "b/\346\235\216\346\231\250\346\273\224/\346\200\235\347\273\264\345\257\274\345\233\276.md" @@ -0,0 +1,445 @@ +# Javascript技术及应用 + +## Javascript基础 + +### 开发环境与初体验 +- 编辑器 + - 常用编辑器 + - 记事本 + - Sublime Text4 + - vim + - webstorm + - Trae + - HBuilderX + - DreamWeave + - 我们选用的编辑器 + - Visual Studio Code +- 运行环境 + - 浏览器环境 + - Chrome DevTools调试 + - Firefox开发者工具 + - Edge开发者工具 + - Node.js环境(可选) + - Node.js安装与配置 + - 终端运行JS脚本 +- 第一个JS程序 + - HTML中嵌入JS的方式 + - 内联脚本(script标签) + - 外部脚本(src引入) + - 行内事件脚本(onclick等) + - 基础输出方式 + - console.log()(控制台输出) + - document.write()(页面输出) + - alert()(弹窗输出) + +### 变量、常量和基础数据类型 +- 变量声明 + - var(ES5,函数作用域) + - let(ES6,块级作用域) + - 变量命名规则与规范 +- 常量声明 + - const(ES6,只读常量) + - 常量使用场景与注意事项 +- 基础数据类型 + - 基本数据类型 + - 字符串(String) + - 数字(Number) + - 布尔值(Boolean) + - 空值(Null) + - 未定义(Undefined) + - 符号(Symbol,ES6) + - 引用数据类型 + - 对象(Object) + - 数组(Array) + - 函数(Function) +- 数据类型检测 + - typeof 运算符 + - instanceof 运算符 + - Object.prototype.toString.call() + +### 运算符和数据类型转换 +- 运算符分类 + - 算术运算符(+、-、*、/、%、++、--) + - 赋值运算符(=、+=、-=、*=、/=) + - 比较运算符(==、===、!=、!==、>、<、>=、<=) + - 逻辑运算符(&&、||、!) + - 三元运算符(条件 ? 结果1 : 结果2) + - 逗号运算符、typeof运算符 +- 运算符优先级与结合性 +- 数据类型转换 + - 隐式转换(自动转换) + - 字符串与数字混合运算 + - 布尔值参与运算 + - 显式转换(手动转换) + - 转字符串(String()、toString()) + - 转数字(Number()、parseInt()、parseFloat()) + - 转布尔值(Boolean()) + +### 流程控制 +- 分支结构 + - 单分支(if) + - 双分支(if-else) + - 多分支(if-else if-else) + - switch-case语句(break的使用、default分支) +- 循环结构 + - for循环(基础循环、遍历数组) + - while循环(先判断后执行) + - do-while循环(先执行后判断,至少执行一次) + - 嵌套循环(二维结构遍历,如表格、座位表) +- 跳转语句 + - break(终止循环/switch) + - continue(跳过本次循环) + - return(终止函数执行并返回值) + +## 核心数据结构及用法 + +### 数组 +- 数组创建 + - 字面量方式([]) + - 构造函数方式(new Array()) +- 数组访问与遍历 + - 索引访问(arr[index]) + - 基础遍历(for循环、for-in循环) + - 高阶遍历(forEach、map、filter) +- 数组常用方法 + - 增删改查 + - push()/pop()(尾部增删) + - unshift()/shift()(头部增删) + - splice()(指定位置增删改) + - 拼接与截取 + - concat()(数组合并) + - slice()(数组截取) + - 排序与反转 + - sort()(排序,数字排序需传比较器) + - reverse()(数组反转) + - 其他常用方法 + - join()(数组转字符串) + - indexOf()/includes()(查找元素) + - reduce()(累加/聚合运算) +- 数组进阶 + - 数组去重 + - 数组扁平化 + - 数组原型扩展(自定义方法) + +### 函数 +- 函数基础 + - 函数声明(function 函数名() {}) + - 函数表达式(const fn = function() {}) + - 函数调用(普通调用、事件调用) +- 函数参数 + - 形参与实参 + - 默认参数(ES6) + - 剩余参数(...rest,ES6) + - 参数传递(值传递、引用传递) +- 函数返回值 + - return关键字 + - 无return的默认返回值(undefined) +- 函数作用域 + - 全局作用域 + - 函数作用域 + - 块级作用域(let/const) + - 作用域链与变量提升 +- 函数进阶 + - 箭头函数(ES6,this指向) + - 嵌套函数与闭包 + - 递归函数 + - 函数原型扩展(自定义数组/字符串方法) + +### 对象 +- 对象创建 + - 字面量方式({}) + - 构造函数方式(new Object()) + - 自定义构造函数(function Person() {}) +- 对象操作 + - 属性访问(obj.key / obj['key']) + - 属性添加/修改/删除 + - 方法定义与调用 +- 对象遍历 + - for-in循环 + - Object.keys()/Object.values() + - Object.entries() +- 内置对象 + - 数学对象(Math) + - 常用方法(random()、ceil()、floor()、abs()、max()、min()) + - 日期对象(Date) + - 日期创建与格式化 + - 时间戳与时间差计算 + - 字符串对象(String) + - 查找(indexOf()、includes()) + - 截取(substr()、slice()) + - 转换(split()、toUpperCase()、toLowerCase()) + +## Dom操作 + +### Dom基础 +- DOM核心概念 + - DOM树(文档对象模型) + - 节点类型 + - 元素节点(Element) + - 文本节点(Text) + - 属性节点(Attribute) +- 获取DOM元素 + - 精准获取 + - getElementById()(通过ID) + - getElementsByClassName()(通过类名) + - getElementsByTagName()(通过标签名) + - 灵活获取 + - querySelector()(单个元素,CSS选择器) + - querySelectorAll()(多个元素,CSS选择器) +- 节点关系 + - 父节点(parentNode) + - 子节点(childNodes、children) + - 兄弟节点(previousSibling、nextSibling) + +### 操作元素内容与属性 +- 操作元素内容 + - 文本内容(textContent、innerText) + - HTML内容(innerHTML) +- 操作元素属性 + - 标准属性(src、href、id、class) + - getAttribute()(获取属性) + - setAttribute()(设置属性) + - removeAttribute()(删除属性) + - 自定义属性(data-*) +- 操作元素样式 + - 行内样式(style属性,如elem.style.color) + - 类名操作(className、classList) + - classList.add()/remove()/toggle() + +### 处理用户交互-事件 +- 事件基础 + - 事件三要素 + - 事件源(触发事件的元素) + - 事件类型(click、mouseenter、change等) + - 事件处理程序(函数) + - 事件绑定方式 + - 行内绑定(onclick="fn()") + - 动态绑定(elem.onclick = fn) + - 监听绑定(addEventListener(),支持多事件) +- 事件对象(Event) + - 事件对象获取与常用属性 + - e.target(触发事件的目标元素) + - e.button(鼠标按键) + - e.key(键盘按键) + - 事件对象方法 + - preventDefault()(阻止默认行为) + - stopPropagation()(阻止事件冒泡) +- 常用事件类型 + - 鼠标事件(click、mousedown、mouseup、mouseenter、mouseleave) + - 键盘事件(keydown、keyup、keypress) + - 表单事件(change、submit、focus、blur) + - 页面事件(load、resize、scroll) +- 事件进阶 + - 事件冒泡与捕获 + - 事件委托(利用冒泡简化多元素事件绑定) + +### 动态创建与修改Dom元素 +- 创建元素 + - createElement()(创建元素节点) + - createTextNode()(创建文本节点) +- 添加元素 + - appendChild()(追加到子节点末尾) + - insertBefore()(插入到指定节点前) +- 删除与替换元素 + - remove()(删除元素) + - replaceChild()(替换元素) +- 克隆元素 + - cloneNode()(浅克隆/深克隆) +- 动态生成复杂结构 + - 动态表格(createElement + 嵌套循环) + - 动态列表(ul/li) + - 拖拽元素(结合事件与样式修改) + +## 数据交互与异步操作 + +### 异步编程入门 +- 同步与异步 + - 同步执行(阻塞,按顺序执行) + - 异步执行(非阻塞,不等待结果) +- 异步编程方式 + - 回调函数(基础异步方式) + - 定时器回调(setTimeout、setInterval) + - 事件回调(点击、加载完成) + - 回调地狱(多层回调嵌套问题) +- 异步执行机制 + - 事件循环(Event Loop) + - 宏任务与微任务 + +### Promise +- Promise核心概念 + - 三种状态(pending、fulfilled、rejected) + - 状态不可逆性 +- Promise基本用法 + - 创建Promise(new Promise((resolve, reject) => {})) + - 成功回调(then()) + - 失败回调(catch()) + - 最终回调(finally()) +- Promise进阶方法 + - Promise.all()(多Promise并行执行) + - Promise.race()(多Promise竞速执行) + - Promise.resolve()/Promise.reject()(快速创建Promise) + +### Fetch Api +- Fetch基础用法 + - 基本请求(fetch(url)) + - 响应处理 + - 转JSON(response.json()) + - 转文本(response.text()) +- 请求配置 + - 请求方法(GET、POST、PUT、DELETE) + - 请求头(headers) + - 请求体(body,POST请求) +- 错误处理 + - 网络错误捕获 + - HTTP错误处理(status码判断) + +### Json +- JSON基础规范 + - 数据格式(键值对、数组、字符串/数字/布尔/null) + - 与JS对象的区别(引号、数据类型限制) +- JSON序列化与反序列化 + - JSON.stringify()(JS对象转JSON字符串) + - JSON.parse()(JSON字符串转JS对象) +- JSON实战 + - 前后端数据交互格式 + - 本地存储JSON数据 + +## jQuery基础 + +### jQuery 基础 +- jQuery引入方式 + - CDN引入(在线链接) + - 本地文件引入 +- jQuery入口函数 + - $(document).ready(function() {}) + - 简写形式$(function() {}) +- jQuery对象与DOM对象 + - 相互转换($dom[0] / $(dom)) +- jQuery核心特性 + - 链式调用 + - 隐式迭代 + +### jQuery 选择器与操作 +- 基础选择器 + - ID选择器($("#id")) + - 类选择器($(".class")) + - 标签选择器($("tag")) + - 通配符选择器($("*")) +- 进阶选择器 + - 层级选择器(后代、子元素、相邻兄弟、通用兄弟) + - 过滤选择器(:first、:last、:eq()、:odd、:even) + - 属性选择器([attr]、[attr=value]) +- 元素属性操作 + - attr()/prop()(获取/设置属性) + - removeAttr()(删除属性) +- 元素样式操作 + - css()(获取/设置样式) + - addClass()/removeClass()/toggleClass()(类名操作) + +### jQuery 事件处理 +- 基础事件绑定 + - 简写绑定(click()、mouseenter()、change()) + - on()绑定(通用绑定方式) + - off()解绑 +- 事件委托 + - on()实现事件委托($("父元素").on("click", "子元素", fn)) +- 常用事件类型 + - 鼠标事件、键盘事件、表单事件、页面事件 +- 事件对象 + - e.preventDefault()/e.stopPropagation() + - e.target / $(e.target) + +### jQuery 动画与效果 +- 基础显示隐藏 + - show()/hide()/toggle()(带速度参数) +- 滑动效果 + - slideDown()/slideUp()/slideToggle() +- 淡入淡出效果 + - fadeIn()/fadeOut()/fadeToggle()/fadeTo() +- 自定义动画 + - animate()(自定义属性动画) +- 动画进阶 + - 动画队列 + - stop()(停止动画) + +### jQuery DOM 操作 +- DOM创建与添加 + - $("div")(创建元素) + - append()/prepend()(内部添加) + - after()/before()(外部添加) +- DOM删除与替换 + - remove()/empty()(删除元素/清空内容) + - replaceWith()(替换元素) +- DOM遍历 + - 父元素(parent()/parents()) + - 子元素(children()/find()) + - 兄弟元素(siblings()/next()/prev()) +- 内容操作 + - html()/text()/val()(对应innerHTML/textContent/value) + +## 综合应用与进阶 + +### 本地存储 +- localStorage + - 特性(永久存储,除非手动删除) + - 常用方法(setItem()、getItem()、removeItem()、clear()) +- sessionStorage + - 特性(会话存储,页面关闭即清空) + - 与localStorage的区别 +- 实战应用 + - 记住密码功能 + - 本地购物车 + - 页面状态保存 +- 存储注意事项 + - 仅支持字符串存储(JSON序列化复杂数据) + - 存储容量限制(约5MB) + +### 错误处理 +- 错误类型 + - 语法错误(书写错误,代码无法执行) + - 运行时错误(执行中出错,如引用未定义变量) + - 逻辑错误(代码执行但结果不符合预期) +- 错误捕获与处理 + - try-catch-finally语句 + - throw关键字(抛出自定义错误) +- 调试技巧 + - 控制台调试(console.log/debugger) + - 断点调试(Chrome DevTools) +- 错误监控 + - window.onerror(全局错误捕获) + +### 模块化(选修) +- 模块化概念 + - 模块化的意义(代码解耦、复用、维护) + - 模块化规范发展 +- CommonJS规范 + - 模块导出(module.exports/exports) + - 模块导入(require()) +- ES6 Module规范 + - 模块导出(export、export default) + - 模块导入(import) +- 模块化实战 + - 前端模块化打包(简介Webpack) + - 模块化开发规范 + +### 综合实战项目 +- 项目1:待办事项(TodoList) + - 需求分析与功能规划 + - 核心功能实现 + - 添加待办、删除待办、标记完成 + - 本地存储待办数据 + - 筛选(全部/已完成/未完成) +- 项目2:表单验证 + - 常用表单验证规则(手机号、邮箱、密码强度) + - 实时验证与错误提示 + - 提交拦截与异步提交 +- 项目3:轮播图 + - 自动轮播、手动切换 + - 指示器、左右箭头控制 + - 轮播动画与自动暂停(鼠标悬浮) +- 项目4:购物车(基础版) + - 商品添加/删除/数量修改 + - 总价计算 + - 本地存储购物车数据 +- 项目开发流程 + - 需求分析 → 页面布局 → 功能实现 → 调试优化 → 上线部署 \ No newline at end of file