Compare commits
11 Commits
b7c97d0f17
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 82324f6274 | |||
| 3531360974 | |||
| da188afd82 | |||
|
|
8ad5c45a42 | ||
|
|
bca2e0619c | ||
|
|
5d510b0433 | ||
| 2f55fc7184 | |||
| 474f335e94 | |||
|
|
2b9e5f9bd1 | ||
|
|
43aa3f07e5 | ||
|
|
c3e8cad947 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -7,3 +7,4 @@ docs/.vuepress/dist
|
||||
.trae/
|
||||
.DS_Store
|
||||
*.log
|
||||
_publish/
|
||||
|
||||
133
build-and-publish.bat
Normal file
133
build-and-publish.bat
Normal file
@@ -0,0 +1,133 @@
|
||||
@echo off
|
||||
setlocal EnableExtensions
|
||||
|
||||
chcp 65001 >nul
|
||||
|
||||
REM Paths and settings
|
||||
set "ROOT_DIR=%~dp0"
|
||||
set "PROJECT_DIR=%ROOT_DIR%"
|
||||
set "DIST_DIR=%PROJECT_DIR%docs\.vuepress\dist"
|
||||
set "PUBLISH_DIR=%PROJECT_DIR%_publish"
|
||||
set "REMOTE_URL=https://gitea.simengweb.com/si-meng-spec/build_notes_simengweb.git"
|
||||
set "BRANCH=main"
|
||||
|
||||
REM Args
|
||||
set "LIGHT_FLAG=%~1"
|
||||
set "COMMIT_MSG=%~2"
|
||||
|
||||
echo [Info] Working dir: %PROJECT_DIR%
|
||||
|
||||
REM Pre-checks
|
||||
where npm >nul 2>&1
|
||||
if errorlevel 1 goto :npm_missing
|
||||
where git >nul 2>&1
|
||||
if errorlevel 1 goto :git_missing
|
||||
|
||||
REM Install deps on first run
|
||||
if not exist "%PROJECT_DIR%node_modules" (
|
||||
echo [Info] Installing deps ^(npm ci^)...
|
||||
call npm ci
|
||||
if errorlevel 1 goto :fail
|
||||
) else (
|
||||
echo [Info] node_modules exists, skip install.
|
||||
)
|
||||
|
||||
REM Light build mode
|
||||
if /I "%LIGHT_FLAG%"=="light" (
|
||||
set "LIGHT_BUILD=1"
|
||||
echo [Info] LIGHT_BUILD=1 enabled
|
||||
)
|
||||
|
||||
set "NODE_OPTIONS=--max-old-space-size=4096"
|
||||
|
||||
echo [Info] Building docs...
|
||||
call npm run docs:build
|
||||
if errorlevel 1 goto :fail
|
||||
|
||||
if not exist "%DIST_DIR%" goto :no_dist
|
||||
|
||||
REM Prepare publish repo
|
||||
if not exist "%PUBLISH_DIR%\.git" (
|
||||
echo [Info] Cloning publish repo...
|
||||
git clone "%REMOTE_URL%" "%PUBLISH_DIR%"
|
||||
if errorlevel 1 goto :fail
|
||||
) else (
|
||||
echo [Info] Updating publish repo...
|
||||
pushd "%PUBLISH_DIR%"
|
||||
git fetch --all
|
||||
if errorlevel 1 goto :gitfail
|
||||
git checkout "%BRANCH%"
|
||||
if errorlevel 1 goto :gitfail
|
||||
git reset --hard "origin/%BRANCH%"
|
||||
if errorlevel 1 goto :gitfail
|
||||
popd
|
||||
)
|
||||
|
||||
echo [Info] Cleaning publish directory ^(keep .git^)...
|
||||
pushd "%PUBLISH_DIR%"
|
||||
for /f "delims=" %%F in ('dir /a /b') do (
|
||||
if /I not "%%F"==".git" (
|
||||
if exist "%%F" (
|
||||
attrib -R "%%F" >nul 2>&1
|
||||
rd /s /q "%%F" 2>nul
|
||||
del /f /q "%%F" 2>nul
|
||||
)
|
||||
)
|
||||
)
|
||||
popd
|
||||
|
||||
echo [Info] Copying dist to publish...
|
||||
robocopy "%DIST_DIR%" "%PUBLISH_DIR%" *.* /E /NFL /NDL /NP /NJH /NJS >nul
|
||||
if errorlevel 8 goto :fail
|
||||
|
||||
pushd "%PUBLISH_DIR%"
|
||||
if defined GIT_USERNAME git config user.name "%GIT_USERNAME%"
|
||||
if defined GIT_EMAIL git config user.email "%GIT_EMAIL%"
|
||||
|
||||
git add -A
|
||||
|
||||
if "%COMMIT_MSG%"=="" set "COMMIT_MSG=Build: %DATE% %TIME%"
|
||||
|
||||
set "HAS_CHANGES=1"
|
||||
git diff --cached --quiet
|
||||
if not errorlevel 1 set "HAS_CHANGES=0"
|
||||
|
||||
if "%HAS_CHANGES%"=="0" (
|
||||
echo [Info] No changes to commit; skipping push.
|
||||
) else (
|
||||
git commit -m "%COMMIT_MSG%"
|
||||
if errorlevel 1 (
|
||||
popd
|
||||
goto :fail
|
||||
)
|
||||
git push origin "%BRANCH%"
|
||||
if errorlevel 1 (
|
||||
popd
|
||||
goto :fail
|
||||
)
|
||||
echo [Info] Pushed to %REMOTE_URL% ^(branch %BRANCH%^).
|
||||
)
|
||||
popd
|
||||
|
||||
echo [Success] Build and publish done.
|
||||
exit /b 0
|
||||
|
||||
:npm_missing
|
||||
echo [ERROR] npm not found. Please install Node.js.
|
||||
goto :fail
|
||||
|
||||
:git_missing
|
||||
echo [ERROR] git not found. Please install Git.
|
||||
goto :fail
|
||||
|
||||
:no_dist
|
||||
echo [ERROR] Dist directory not found: %DIST_DIR%
|
||||
goto :fail
|
||||
|
||||
:gitfail
|
||||
echo [ERROR] Git operation failed.
|
||||
popd
|
||||
goto :fail
|
||||
|
||||
:fail
|
||||
exit /b 1
|
||||
@@ -18,6 +18,8 @@ export default defineUserConfig({
|
||||
shouldPrefetch: false,
|
||||
|
||||
theme: plumeTheme({
|
||||
/* 站点域名,启动 SEO 优化 */
|
||||
hostname: 'https://notes.simengweb.com',
|
||||
/* 博客文章页面链接前缀 */
|
||||
article: '/article/',
|
||||
|
||||
|
||||
@@ -151,6 +151,8 @@ const web = defineNoteConfig({
|
||||
text: "基础知识", prefix: "/basic-syntax", items: [
|
||||
{ text: "Web 前端基础讲解", link: "/programming/web/basic-syntax/html-css-js/" },
|
||||
{ text: "HTML 常用标签与属性", link: "/programming/web/basic-syntax/html-tags-attributes/" },
|
||||
{ text: "HTML 列表与语义布局", link: "/programming/web/basic-syntax/html-lists-and-semantic-layout/" },
|
||||
{ text: "JavaScript 基础知识", link: "/programming/web/basic-syntax/javascript-basics/" },
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
249
docs/blog/collect/free_model_pai.md
Normal file
249
docs/blog/collect/free_model_pai.md
Normal file
@@ -0,0 +1,249 @@
|
||||
---
|
||||
title: 便宜免费的大模型 API 整合 ( 2025年11月11日 )
|
||||
createTime: 2025/11/11 13:54:02
|
||||
permalink: /article/free_model_api/
|
||||
---
|
||||
|
||||
## 免费的大模型 API 整合
|
||||
|
||||
嗨~如果你在找既温柔又省荷包的小模型,就把它们悄悄收进这里吧!它们也许不是夜空最亮的那颗星,却能在摘要、划重点、轻声问答的小角落里,给你软软又稳稳的陪伴哦~
|
||||
|
||||
|
||||
### 百度千帆大模型平台
|
||||
|
||||
先从千帆开始吧~下面是常用模型的参考价格:
|
||||
|
||||
| 模型名称 | 版本名称 | 服务内容 | 子项 | 在线推理 | 批量推理 | 单位 |
|
||||
|---|---|---|---|---|---|---|
|
||||
| ERNIE Speed | ernie-speed-128k | 推理服务 | 输入 | 0 | 0.00012 | 元/千tokens |
|
||||
| ERNIE Speed | ernie-speed-128k | 推理服务 | 输出 | 0 | 0.00024 | 元/千tokens |
|
||||
| ERNIE Lite | ernie-lite-8k | 推理服务 | 输入 | 0 | 0.0012 | 元/千tokens |
|
||||
| ERNIE Lite | ernie-lite-8k | 推理服务 | 输出 | 0 | 0.0024 | 元/千tokens |
|
||||
| ERNIE Tiny | ernie-tiny-8k | 推理服务 | 输入 | 0 | 0.00008 | 元/千tokens |
|
||||
| ERNIE Tiny | ernie-tiny-8k | 推理服务 | 输出 | 0 | 0.00016 | 元/千tokens |
|
||||
|
||||
> 提示:单纯调用 API 接口属于在线推理,当前显示为 0 元;批量推理按量计费。
|
||||
|
||||
#### 快速上手
|
||||
|
||||
1. 访问控制台并获取 API Key。
|
||||
2. 使用下方示例进行快速测试。
|
||||
3. 若遇错误,请检查模型名称与凭证有效期。
|
||||
|
||||
控制台:[https://console.bce.baidu.com/qianfan/ais/console/apiKey](https://console.bce.baidu.com/qianfan/ais/console/apiKey)
|
||||
|
||||
```python
|
||||
import requests
|
||||
import json
|
||||
|
||||
def main():
|
||||
url = "https://qianfan.baidubce.com/v2/chat/completions"
|
||||
API_KEY = 'YOUR_API_KEY'
|
||||
payload = json.dumps({
|
||||
"model": "ernie-speed-128k",
|
||||
"messages": [
|
||||
{
|
||||
"role": "system",
|
||||
"content": "You are a helpful assistant."
|
||||
},
|
||||
{
|
||||
"role": "user",
|
||||
"content": "你好"
|
||||
}
|
||||
]
|
||||
})
|
||||
headers = {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': F'Bearer {API_KEY}'
|
||||
}
|
||||
response = requests.request("POST", url, headers=headers, data=payload)
|
||||
print(response.text)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
```
|
||||
|
||||
> 小贴士:将 `YOUR_API_KEY` 替换为你的密钥,建议使用环境变量管理凭证;请勿在公共仓库提交 Key。
|
||||
|
||||
更多文档:[https://cloud.baidu.com/doc/qianfan-api/s/3m9b5lqft](https://cloud.baidu.com/doc/qianfan-api/s/3m9b5lqft)
|
||||
|
||||
### 讯飞星火大模型
|
||||
|
||||
接着,我们轻盈地来到星火~
|
||||
|
||||
- 官网:[https://xinghuo.xfyun.cn/sparkapi](https://xinghuo.xfyun.cn/sparkapi)
|
||||
- 控制台:[https://console.xfyun.cn/services/cbm?from=desk](https://console.xfyun.cn/services/cbm?from=desk)
|
||||
- 模型说明:可见 Spark Lite,Token 余量为无限。
|
||||
|
||||
#### 快速上手
|
||||
|
||||
> 小贴士:如需联网检索,启用 `web_search`;流式输出可以提升交互体验。
|
||||
|
||||
1. 在控制台获取授权凭证并替换到示例中。
|
||||
2. 选择 `Lite` 模型,按需开启 `web_search` 与 `stream`。
|
||||
3. 若需要长内容输出,注意 8K tokens 限制,合理裁剪上下文。
|
||||
|
||||
```python
|
||||
# encoding:UTF-8
|
||||
import json
|
||||
import requests
|
||||
|
||||
|
||||
# 请替换XXXXXXXXXX为您的 APIpassword, 获取地址:https://console.xfyun.cn/services/bmx1
|
||||
api_key = "Bearer XXXXXXXXXX"
|
||||
url = "https://spark-api-open.xf-yun.com/v1/chat/completions"
|
||||
|
||||
# 请求模型,并将结果输出
|
||||
def get_answer(message):
|
||||
#初始化请求体
|
||||
headers = {
|
||||
'Authorization':api_key,
|
||||
'content-type': "application/json"
|
||||
}
|
||||
body = {
|
||||
"model": "Lite",
|
||||
"user": "user_id",
|
||||
"messages": message,
|
||||
# 下面是可选参数
|
||||
"stream": True,
|
||||
"tools": [
|
||||
{
|
||||
"type": "web_search",
|
||||
"web_search": {
|
||||
"enable": True,
|
||||
"search_mode":"deep"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
full_response = "" # 存储返回结果
|
||||
isFirstContent = True # 首帧标识
|
||||
|
||||
response = requests.post(url=url,json= body,headers= headers,stream= True)
|
||||
# print(response)
|
||||
for chunks in response.iter_lines():
|
||||
# 打印返回的每帧内容
|
||||
# print(chunks)
|
||||
if (chunks and '[DONE]' not in str(chunks)):
|
||||
data_org = chunks[6:]
|
||||
|
||||
# print(f"DEBUG: raw data_org: {data_org}")
|
||||
chunk = json.loads(data_org)
|
||||
text = chunk['choices'][0]['delta']
|
||||
|
||||
# 判断最终结果状态并输出
|
||||
if ('content' in text and '' != text['content']):
|
||||
content = text["content"]
|
||||
if (True == isFirstContent):
|
||||
isFirstContent = False
|
||||
print(content, end="")
|
||||
full_response += content
|
||||
return full_response
|
||||
|
||||
|
||||
# 管理对话历史,按序编为列表
|
||||
def getText(text,role, content):
|
||||
jsoncon = {}
|
||||
jsoncon["role"] = role
|
||||
jsoncon["content"] = content
|
||||
text.append(jsoncon)
|
||||
return text
|
||||
|
||||
# 获取对话中的所有角色的content长度
|
||||
def getlength(text):
|
||||
length = 0
|
||||
for content in text:
|
||||
temp = content["content"]
|
||||
leng = len(temp)
|
||||
length += leng
|
||||
return length
|
||||
|
||||
# 判断长度是否超长,当前限制8K tokens
|
||||
def checklen(text):
|
||||
while (getlength(text) > 11000):
|
||||
del text[0]
|
||||
return text
|
||||
|
||||
|
||||
#主程序入口
|
||||
if __name__ =='__main__':
|
||||
|
||||
#对话历史存储列表
|
||||
chatHistory = []
|
||||
#循环对话轮次
|
||||
while (1):
|
||||
# 等待控制台输入
|
||||
Input = input("\n" + "我:")
|
||||
question = checklen(getText(chatHistory,"user", Input))
|
||||
# 开始输出模型内容
|
||||
print("星火:", end="")
|
||||
getText(chatHistory,"assistant", get_answer(question))
|
||||
```
|
||||
|
||||
### 腾讯混元大模型
|
||||
|
||||
- 计费与价格:[https://cloud.tencent.com/document/product/1729/97731](https://cloud.tencent.com/document/product/1729/97731)
|
||||
- 文档与控制台:[https://cloud.tencent.com/document/product/1729/111008](https://cloud.tencent.com/document/product/1729/111008)
|
||||
- 模型说明:`hunyuan-lite` 免费可用,适合轻量任务。
|
||||
|
||||
```python
|
||||
import os
|
||||
from openai import OpenAI
|
||||
|
||||
# 构造 client(建议使用环境变量管理密钥)
|
||||
api_key = os.getenv("HUNYUAN_API_KEY", "YOUR_API_KEY")
|
||||
client = OpenAI(
|
||||
api_key=api_key, # 混元 APIKey
|
||||
base_url="https://api.hunyuan.cloud.tencent.com/v1", # 混元 endpoint
|
||||
)
|
||||
|
||||
completion = client.chat.completions.create(
|
||||
model="hunyuan-lite",
|
||||
messages=[
|
||||
{
|
||||
"role": "user",
|
||||
"content": "泥嚎"
|
||||
}
|
||||
],
|
||||
extra_body={
|
||||
"enable_enhancement": True,
|
||||
},
|
||||
)
|
||||
print(completion.choices[0].message.content)
|
||||
```
|
||||
|
||||
> 小贴士:请勿在公共仓库提交任何真实密钥;使用环境变量或密钥管理服务更安全。
|
||||
|
||||
## 低价大模型
|
||||
|
||||
### SCNet 平台
|
||||
|
||||
#### 简介
|
||||
SCNet 是一个面向人工智能和科学计算的一站式算力与 AI 平台,提供从数据管理、模型训练到部署的完整链路服务,同时结合国产超算硬件和多模态模型生态,让企业和开发者能更高效地使用 AI。
|
||||
|
||||
#### 链接与文档
|
||||
- 官网:[https://www.scnet.cn/](https://www.scnet.cn/)
|
||||
#### 价格一览
|
||||
| 模型 | 上下文长度 | 百万 tokens 输入价格 | 百万 tokens 输出价格 |
|
||||
|---|---|---|---|
|
||||
| Qwen3-235B-A22B | 32K | 0.1 元 | 0.1 元 |
|
||||
| DeepSeek-R1-Distill-Qwen-7B | 32K | 0.1 元 | 0.1 元 |
|
||||
| DeepSeek-R1-Distill-Qwen-32B | 32K | 1 元 | 4 元 |
|
||||
| DeepSeek-R1-Distill-Llama-70B | 32K | 0.1 元 | 6 元 |
|
||||
| QwQ-32B | 32K | 1 元 | 4 元 |
|
||||
| Qwen3-30B-A3B | 128K | 1 元 | 6 元 |
|
||||
| Qwen3-Embedding-8B | - | 0.1 元 | - |
|
||||
|
||||
- 文档(计费与说明):[https://www.scnet.cn/ac/openapi/doc/2.0/moduleapi/tutorial/modulefee.html](https://www.scnet.cn/ac/openapi/doc/2.0/moduleapi/tutorial/modulefee.html)
|
||||
|
||||
目前看到的价格最低的 Qwen3-235B-A22B 模型的 API,相比前面的免费模型,性能更强。
|
||||
- API 接口使用样例:[https://www.scnet.cn/ac/openapi/doc/2.0/moduleapi/tutorial/apicall.html](https://www.scnet.cn/ac/openapi/doc/2.0/moduleapi/tutorial/apicall.html)
|
||||
|
||||
## 小结
|
||||
|
||||
把上面这些“零钱包”级别的模型都翻完啦~
|
||||
- 百度千帆、讯飞星火、腾讯混元都给出「免费在线额度」,日常轻量问答、摘要、润色完全够用;记得把 Key 藏进环境变量,别手滑推到 GitHub。
|
||||
- 如果任务量突然暴涨,SCNet 的 Qwen3-235B-A22B 只要 0.1 元/百万 tokens,性价比直接拉满,当“备胎”也安心。
|
||||
|
||||
一句话:先薅免费的,薅不动再掏 0.1 元,让荷包和模型一起“稳稳幸福”吧!
|
||||
@@ -0,0 +1,468 @@
|
||||
---
|
||||
title: html 列表与语义布局
|
||||
createTime: 2025/11/02 20:47:50
|
||||
permalink: /programming/web/basic-syntax/html-lists-and-semantic-layout/
|
||||
---
|
||||
## 四、列表(UL/OL/LI)
|
||||
|
||||
无序列表(圆点):
|
||||
```html title="index.html"
|
||||
<ul>
|
||||
<li>学习笔记</li>
|
||||
<li>工具推荐</li>
|
||||
<li>友情链接</li>
|
||||
</ul>
|
||||
```
|
||||
|
||||
有序列表(数字):
|
||||
```html title="index.html"
|
||||
<ol>
|
||||
<li>需求与原型</li>
|
||||
<li>API 设计</li>
|
||||
<li>联调与验收</li>
|
||||
</ol>
|
||||
```
|
||||
|
||||
**小案例:展示清单与步骤**
|
||||
::: code-tabs
|
||||
@tab index.html
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>列表案例</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<script defer src="app.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h2>我的清单</h2>
|
||||
<ul>
|
||||
<li>学习笔记</li>
|
||||
<li>工具推荐</li>
|
||||
<li>友情链接</li>
|
||||
</ul>
|
||||
<h2>项目步骤</h2>
|
||||
<ol>
|
||||
<li>需求与原型</li>
|
||||
<li>API 设计</li>
|
||||
<li>联调与验收</li>
|
||||
</ol>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
@tab style.css
|
||||
```css
|
||||
ul, ol { margin: .5rem 0 1rem; padding-left: 1.5rem; }
|
||||
li { margin: .25rem 0; }
|
||||
```
|
||||
@tab app.js
|
||||
```js
|
||||
document.querySelectorAll('li').forEach(li => li.addEventListener('click', () => li.classList.toggle('done')));
|
||||
```
|
||||
:::
|
||||
|
||||
**小作业:做一个“今日任务清单”**
|
||||
::: code-tabs
|
||||
@tab index.html
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>今日任务清单</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>今天要做的事</h1>
|
||||
<ul>
|
||||
<li>阅读 30 分钟</li>
|
||||
<li>练习 1 个算法题</li>
|
||||
<li>整理房间</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
@tab style.css
|
||||
```css
|
||||
body { font-family: system-ui; margin: 2rem; }
|
||||
li { cursor: pointer; }
|
||||
.done { text-decoration: line-through; color: #888; }
|
||||
```
|
||||
:::
|
||||
|
||||
## 五、语义化布局(Header/Nav/Main/Section/Article/Aside/Footer)
|
||||
|
||||
语义化标签让结构更清晰,搜索引擎更友好:
|
||||
```html title="index.html"
|
||||
<header>
|
||||
<h1>我的网站</h1>
|
||||
<nav>
|
||||
<a href="/blog/">博客</a>
|
||||
<a href="/notes/">笔记</a>
|
||||
</nav>
|
||||
<!-- 注意:更复杂的导航通常配合 CSS/JS 做响应式菜单 -->
|
||||
<!-- 小提示:块级容器的外层仍可使用 <div> 来做网格或栅格布局 -->
|
||||
<!-- 例如 <div class="container"> 包裹全站 -->
|
||||
<!-- 只是这些语义标签会让搜索引擎更理解结构 -->
|
||||
<!-- 语义标签与 <div> 并不冲突,可以配合使用 -->
|
||||
<!-- 选择语义标签能让你的 HTML 更“有含义”而非只是分区 -->
|
||||
<!-- 如果仅用于布局、无明确语义,用 <div> 即可 -->
|
||||
<!-- 这段说明旨在帮助你建立语义化与布局之间的直觉 -->
|
||||
<!-- 逐步养成好的结构化写法 -->
|
||||
<!-- 让内容更可维护,更易被机器理解 -->
|
||||
<!-- (继续往下看,还会介绍 Article/Section 等) -->
|
||||
```
|
||||
|
||||
> 语义化标签的要点:这些标签表达了“这是什么内容”,而不是“怎么显示”。更容易被搜索引擎和读屏工具理解。
|
||||
|
||||
**小案例:语义化布局入门**
|
||||
::: code-tabs
|
||||
@tab index.html
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>语义化布局案例</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<script defer src="app.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<h1>我的网站</h1>
|
||||
<nav>
|
||||
<a href="#home">首页</a>
|
||||
<a href="#blog">博客</a>
|
||||
</nav>
|
||||
</header>
|
||||
<main>
|
||||
<section>
|
||||
<h2>最新文章</h2>
|
||||
<article>
|
||||
<h3>用语义标签改造你的页面</h3>
|
||||
<p>示例段落:用 header/nav/main/section/article/aside/footer 组织结构。</p>
|
||||
</article>
|
||||
</section>
|
||||
<aside>
|
||||
<h2>侧栏</h2>
|
||||
<p>这里可以放导航、标签云或广告位。</p>
|
||||
</aside>
|
||||
</main>
|
||||
<footer>© 2025 祀梦</footer>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
@tab style.css
|
||||
```css
|
||||
body { font-family: system-ui; margin: 0; }
|
||||
header, footer { padding: 1rem 2rem; background: #f7f7f7; }
|
||||
nav { display: flex; gap: 1rem; }
|
||||
main { display: grid; grid-template-columns: 1fr 240px; gap: 1rem; padding: 1rem 2rem; }
|
||||
article { background: #fff; padding: 1rem; border: 1px solid #eee; border-radius: 8px; }
|
||||
aside { background: #fff; padding: 1rem; border: 1px solid #eee; border-radius: 8px; }
|
||||
```
|
||||
@tab app.js
|
||||
```js
|
||||
document.querySelectorAll('nav a').forEach(a => a.addEventListener('click', () => {
|
||||
document.querySelectorAll('nav a').forEach(x => x.classList.remove('active'));
|
||||
a.classList.add('active');
|
||||
}));
|
||||
```
|
||||
:::
|
||||
|
||||
**小作业:用语义标签搭一个博客首页**
|
||||
::: code-tabs
|
||||
@tab index.html
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>博客首页</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<h1>博客名称</h1>
|
||||
<nav>
|
||||
<a href="#">首页</a>
|
||||
<a href="#">归档</a>
|
||||
<a href="#">关于</a>
|
||||
</nav>
|
||||
</header>
|
||||
<main>
|
||||
<section>
|
||||
<article>
|
||||
<h2>第一篇文章标题</h2>
|
||||
<p>摘要内容……</p>
|
||||
</article>
|
||||
<article>
|
||||
<h2>第二篇文章标题</h2>
|
||||
<p>摘要内容……</p>
|
||||
</article>
|
||||
</section>
|
||||
<aside>
|
||||
<h2>侧栏</h2>
|
||||
<p>分类、标签或个人简介。</p>
|
||||
</aside>
|
||||
</main>
|
||||
<footer>© 2025 你的名字</footer>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
@tab style.css
|
||||
```css
|
||||
/* 与案例类似的栅格布局样式 */
|
||||
main { display: grid; grid-template-columns: 1fr 240px; gap: 1rem; padding: 1rem 2rem; }
|
||||
article { background: #fff; padding: 1rem; border: 1px solid #eee; border-radius: 8px; }
|
||||
aside { background: #fff; padding: 1rem; border: 1px solid #eee; border-radius: 8px; }
|
||||
```
|
||||
:::
|
||||
|
||||
## 六、表格(Table/TR/TH/TD)
|
||||
|
||||
```html title="index.html"
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>姓名</th>
|
||||
<th>职业</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>祀梦</td>
|
||||
<td>开发者</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
```
|
||||
小提示:表格样式通常用 CSS 来美化(边框、间距、对齐等)。
|
||||
|
||||
**小案例:信息表格**
|
||||
::: code-tabs
|
||||
@tab index.html
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>信息表格案例</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<script defer src="app.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>姓名</th><th>职业</th><th>城市</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>祀梦</td><td>开发者</td><td>上海</td></tr>
|
||||
<tr><td>小李</td><td>产品经理</td><td>杭州</td></tr>
|
||||
<tr><td>小王</td><td>设计师</td><td>北京</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
@tab style.css
|
||||
```css
|
||||
table { border-collapse: collapse; width: 100%; }
|
||||
th, td { border: 1px solid #ddd; padding: .5rem .75rem; text-align: left; }
|
||||
thead th { background: #f7f7f7; }
|
||||
tbody tr:nth-child(odd) { background: #fafafa; }
|
||||
```
|
||||
@tab app.js
|
||||
```js
|
||||
document.querySelectorAll('tbody tr').forEach(tr => tr.addEventListener('click', () => tr.classList.toggle('highlight')));
|
||||
```
|
||||
:::
|
||||
|
||||
**小作业:制作“课程表”**
|
||||
::: code-tabs
|
||||
@tab index.html
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>课程表</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>时间</th><th>课程</th><th>教室</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>周一 9:00</td><td>数学</td><td>A101</td></tr>
|
||||
<tr><td>周三 14:00</td><td>英语</td><td>B302</td></tr>
|
||||
<tr><td>周五 10:00</td><td>计算机</td><td>C210</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
@tab style.css
|
||||
```css
|
||||
table { border-collapse: collapse; width: 100%; }
|
||||
th, td { border: 1px solid #ddd; padding: .5rem .75rem; }
|
||||
thead th { background: #f0f0f0; }
|
||||
```
|
||||
:::
|
||||
|
||||
|
||||
## 七、媒体(Audio/Video/Source)
|
||||
|
||||
```html title="index.html"
|
||||
<audio src="bgm.mp3" controls loop></audio>
|
||||
|
||||
<video src="intro.mp4" controls width="480" poster="cover.jpg" muted></video>
|
||||
<!-- 常用属性:controls / autoplay / loop / muted / poster(封面) -->
|
||||
```
|
||||
|
||||
补充说明:
|
||||
- `controls` 提供播放控制;一般不建议隐藏,保证可用性。
|
||||
- `autoplay` 可能被浏览器限制;若需自动播放,通常需同时设置 `muted`。
|
||||
- `preload` 控制预加载策略(`none`/`metadata`/`auto`),根据页面性能需求选择。
|
||||
- `poster` 为视频未播放时的封面图;音频没有封面属性。
|
||||
- 使用 `<source>` 指定多种格式与 MIME 类型,提升兼容性:`<source src="xxx.mp4" type="video/mp4">`。
|
||||
|
||||
**小案例:嵌入音视频**
|
||||
::: code-tabs
|
||||
@tab index.html
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>媒体案例</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<h2>背景音乐</h2>
|
||||
<audio src="bgm.mp3" controls loop></audio>
|
||||
<h2>介绍视频</h2>
|
||||
<video src="intro.mp4" controls width="480" poster="cover.jpg" muted></video>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
@tab style.css
|
||||
```css
|
||||
video { display: block; margin-top: .5rem; }
|
||||
```
|
||||
:::
|
||||
|
||||
**小作业:添加一段你喜欢的音乐与视频**
|
||||
::: code-tabs
|
||||
@tab index.html
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>我的媒体</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<audio src="music.mp3" controls></audio>
|
||||
<video src="movie.mp4" controls width="480" poster="cover.jpg"></video>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
@tab style.css
|
||||
```css
|
||||
audio, video { display: block; margin: .5rem 0; }
|
||||
```
|
||||
:::
|
||||
|
||||
|
||||
## 八、全局常用属性(任何标签几乎都能用)
|
||||
|
||||
- `id`:唯一标识,用于 JS/CSS 精确选择。
|
||||
- `class`:分组与样式选择(上一课已讲)。
|
||||
- `style`:内联样式(不推荐大量使用,建议写到 CSS 文件)。
|
||||
- `title`:悬停提示文字。
|
||||
- `data-*`:自定义数据属性(如 `data-user-id="42"`)。
|
||||
- `aria-*`:无障碍相关属性,帮助读屏工具理解(如 `aria-label`)。
|
||||
|
||||
**小案例:使用 id/class/data/title/aria**
|
||||
::: code-tabs
|
||||
@tab index.html
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>全局属性案例</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<script defer src="app.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<button id="likeBtn" class="btn" title="点赞一下" data-count="0" aria-label="点赞">👍 喜欢</button>
|
||||
<p id="msg" class="note" aria-live="polite">点击按钮试试。</p>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
@tab style.css
|
||||
```css
|
||||
.btn { padding: .5rem .75rem; border: 1px solid #ccc; border-radius: 6px; background: #fff; }
|
||||
.note { color: #555; }
|
||||
```
|
||||
@tab app.js
|
||||
```js
|
||||
const btn = document.getElementById('likeBtn');
|
||||
const msg = document.getElementById('msg');
|
||||
btn.addEventListener('click', () => {
|
||||
const count = Number(btn.dataset.count || 0) + 1;
|
||||
btn.dataset.count = String(count);
|
||||
msg.textContent = `已点赞 ${count} 次`;
|
||||
});
|
||||
```
|
||||
:::
|
||||
|
||||
**小作业:做一个带计数的按钮**
|
||||
::: code-tabs
|
||||
@tab index.html
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>计数按钮</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<script defer src="app.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<button id="counter" class="btn" title="点击增加" data-count="0">点击我</button>
|
||||
<p id="status" class="note">当前计数:0</p>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
@tab style.css
|
||||
```css
|
||||
.btn { padding: .5rem .75rem; border: 1px solid #ccc; border-radius: 6px; background: #fff; }
|
||||
.note { margin-top: .5rem; }
|
||||
```
|
||||
@tab app.js
|
||||
```js
|
||||
const counter = document.getElementById('counter');
|
||||
const statusEl = document.getElementById('status');
|
||||
counter.addEventListener('click', () => {
|
||||
const count = Number(counter.dataset.count || 0) + 1;
|
||||
counter.dataset.count = String(count);
|
||||
statusEl.textContent = `当前计数:${count}`;
|
||||
});
|
||||
```
|
||||
:::
|
||||
|
||||
## 结尾:先结构清晰,再上样式与交互
|
||||
|
||||
写网页像搭房子:先把房间(结构标签)安排好,再选家具颜色(CSS),最后加智能设备(JS)。
|
||||
|
||||
建议你先用这些常用标签做一个“个人名片页”,含标题、段落、头像图片、导航链接和一个简单表单。练熟后再加样式与交互。
|
||||
|
||||
**延伸阅读**:
|
||||
- HTML 规范与参考(MDN):https://developer.mozilla.org/en-US/docs/Web/HTML
|
||||
- 无障碍与语义化:https://developer.mozilla.org/en-US/docs/Glossary/Semantics
|
||||
@@ -15,30 +15,30 @@ permalink: /programming/web/basic-syntax/html-tags-attributes/
|
||||
|
||||
### 认识div标签
|
||||
|
||||
**什么是 <div>?**
|
||||
**什么是 `<div>`?**
|
||||
|
||||
<div> 是 "division"(分区)的缩写,可以理解为网页中的"容器"或"盒子"。
|
||||
`<div>` 是 "division"(分区)的缩写,可以理解为网页中的"容器"或"盒子"。
|
||||
|
||||
想象一下搬家时的纸箱:
|
||||
|
||||
* 网页 = 整个房间
|
||||
* <div> = 一个个纸箱
|
||||
* `<div>` = 一个个纸箱
|
||||
* 箱子里 = 可以放各种物品(文字、图片、按钮等)
|
||||
|
||||
### <div> 的基本特点
|
||||
### `<div>` 的基本特点
|
||||
|
||||
1. 块级元素
|
||||
<div> 是块级元素,这意味着:
|
||||
`<div>` 是块级元素,这意味着:
|
||||
|
||||
* 默认会占据整行的宽度
|
||||
* 前后会自动换行
|
||||
* 就像段落一样,每个<div>都会从新的一行开始
|
||||
* 就像段落一样,每个`<div>`都会从新的一行开始
|
||||
|
||||
**<div> 本身没有特定含义,它只是用来分组和布局。**
|
||||
**`<div>` 本身没有特定含义,它只是用来分组和布局。**
|
||||
|
||||
### 为什么要使用 <div>?
|
||||
### 为什么要使用 `<div>`?
|
||||
|
||||
没有<div>的情况:
|
||||
没有`<div>`的情况:
|
||||
```html title='index.html'
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
@@ -58,7 +58,7 @@ permalink: /programming/web/basic-syntax/html-tags-attributes/
|
||||
|
||||
所有元素都堆在一起,很难分别控制样式。
|
||||
|
||||
使用 <div> 的情况:
|
||||
使用 `<div>` 的情况:
|
||||
```html title='index.html'
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
@@ -265,11 +265,11 @@ p { max-width: 60ch; }
|
||||
|
||||
## 三、链接与图片(A/IMG)
|
||||
|
||||
### 什么是 <img> 标签
|
||||
### 什么是 `<img>` 标签
|
||||
|
||||
<img> 标签用于在网页中插入图片,它是自闭合标签(不需要结束标签)。
|
||||
`<img>` 标签用于在网页中插入图片,它是自闭合标签(不需要结束标签)。
|
||||
|
||||
### <img> 标签的基本属性
|
||||
### `<img>` 标签的基本属性
|
||||
|
||||
* src:指定图片的路径(必填)
|
||||
* alt:指定图片的替代文本(必填,用于图片加载失败时显示)
|
||||
@@ -293,13 +293,13 @@ HTML中的链接是一种用于在不同网页之间导航的元素。
|
||||
|
||||
链接允许用户在浏览网页时单击文本或图像来跳转到其他位置,从而实现网页之间的互联。
|
||||
|
||||
HTML 链接 通过 <a> 标签创建,通常用于将用户从一个页面导航到另一个页面、从一个部分跳转到页面中的另一个部分、下载文件、打开电子邮件应用程序或执行 JavaScript 函数等。
|
||||
HTML 链接 通过 `<a>` 标签创建,通常用于将用户从一个页面导航到另一个页面、从一个部分跳转到页面中的另一个部分、下载文件、打开电子邮件应用程序或执行 JavaScript 函数等。
|
||||
|
||||
超链接可以是一个字,一个词,或者一组词,也可以是一幅图像,可以点击这些内容来跳转到新的文档或者当前文档中的某个部分。
|
||||
|
||||
当把鼠标指针移动到网页中的某个链接上时,箭头会变为**一只小手**。
|
||||
|
||||
## <a> 标签的基本属性
|
||||
## `<a>` 标签的基本属性
|
||||
|
||||
* href:指定链接的目标 URL(必填)
|
||||
* target:指定链接在何处打开(可选)
|
||||
@@ -312,7 +312,7 @@ HTML 链接 通过 <a> 标签创建,通常用于将用户从一个页面导航
|
||||
```html title='index.html'
|
||||
<a href="https://www.example.com">链接文本</a>
|
||||
```
|
||||
- <a> 标签:定义了一个超链接(anchor)。它是 HTML 中用来创建可点击链接的主要标签。
|
||||
- `<a>` 标签:定义了一个超链接(anchor)。它是 HTML 中用来创建可点击链接的主要标签。
|
||||
- href 属性:指定目标 URL,当点击链接时,浏览器将导航到此 URL。
|
||||
|
||||
**这里还有一个target 属性**:
|
||||
|
||||
606
docs/notes/programming/web/basic-syntax/javascript-basics.md
Normal file
606
docs/notes/programming/web/basic-syntax/javascript-basics.md
Normal file
@@ -0,0 +1,606 @@
|
||||
---
|
||||
title: JavaScript 基础知识
|
||||
createTime: 2025/11/2 21:30:00
|
||||
permalink: /programming/web/basic-syntax/javascript-basics/
|
||||
---
|
||||
|
||||
## JavaScript 是什么?
|
||||
|
||||
JavaScript 是一种广泛用于网页开发的脚本语言,它使网页能够实现交互式功能。与 HTML(负责结构)和 CSS(负责样式)不同,JavaScript 专注于**行为**,可以让网页变得动态和响应式。
|
||||
|
||||
|
||||
## 第一个 JavaScript 程序
|
||||
|
||||
JavaScript 代码可以直接写在 HTML 文件中,通常放在 `<body>` 标签的底部,使用 `<script>` 标签包裹。
|
||||
|
||||
```html title="index.html"
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>我的第一个 JavaScript 程序</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>你好,世界!</h1>
|
||||
|
||||
<script>
|
||||
// 这是注释,不会被执行
|
||||
console.log('Hello, JavaScript!'); // 在控制台输出文本
|
||||
alert('欢迎学习 JavaScript!'); // 弹出提示框
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
**提示**:你可以在浏览器中按下 F12 打开开发者工具,然后切换到 "Console" 标签查看 `console.log()` 的输出。
|
||||
|
||||
`console.log()` 是 JavaScript 中最常用、最重要的调试工具,可以说是每个开发者的"最佳朋友"!
|
||||
|
||||
### 基本输出 ###
|
||||
|
||||
```javascript
|
||||
// 输出字符串
|
||||
console.log("Hello World!");
|
||||
|
||||
// 输出变量
|
||||
const name = "小明";
|
||||
console.log(name);
|
||||
|
||||
// 输出多个值
|
||||
const age = 18;
|
||||
const isStudent = true;
|
||||
console.log("学生信息:", name, age, isStudent);
|
||||
```
|
||||
|
||||
### 输出不同类型的数据 ###
|
||||
|
||||
```javascript
|
||||
// 各种数据类型
|
||||
console.log("字符串:", "Hello");
|
||||
console.log("数字:", 42);
|
||||
console.log("布尔值:", true);
|
||||
console.log("数组:", [1, 2, 3]);
|
||||
console.log("对象:", {name: "李华", age: 20});
|
||||
console.log("函数:", function() {});
|
||||
console.log("undefined:", undefined);
|
||||
console.log("null:", null);
|
||||
```
|
||||
|
||||
### 字符串插值 ###
|
||||
|
||||
```javascript
|
||||
const userName = "张三";
|
||||
const userAge = 25;
|
||||
const score = 95.5;
|
||||
|
||||
// 传统方式
|
||||
console.log("用户 " + userName + " 年龄 " + userAge + " 分数 " + score);
|
||||
|
||||
// 模板字符串(推荐)
|
||||
console.log(`用户 ${userName} 年龄 ${userAge} 分数 ${score}`);
|
||||
|
||||
// 带表达式的插值
|
||||
console.log(`${userName} 是 ${userAge >= 18 ? "成年人" : "未成年人"}`);
|
||||
```
|
||||
|
||||
### 格式化输出 ###
|
||||
|
||||
```javascript
|
||||
const product = {
|
||||
name: "笔记本电脑",
|
||||
price: 5999,
|
||||
brand: "Dell",
|
||||
inStock: true
|
||||
};
|
||||
|
||||
// %s - 字符串
|
||||
console.log("产品名称: %s", product.name);
|
||||
|
||||
// %d - 数字
|
||||
console.log("价格: %d 元", product.price);
|
||||
|
||||
// %f - 浮点数
|
||||
console.log("折扣价: %f", product.price * 0.9);
|
||||
|
||||
// %o - 对象
|
||||
console.log("完整产品信息: %o", product);
|
||||
|
||||
// %c - CSS样式
|
||||
console.log("%c重要信息!", "color: red; font-size: 20px; font-weight: bold;");
|
||||
```
|
||||
|
||||
## JavaScript 变量
|
||||
|
||||
变量是用来存储信息的容器。在 JavaScript 中,我们使用 `let`、`const` 或 `var` 关键字来声明变量。
|
||||
|
||||
### 变量声明方式
|
||||
|
||||
```javascript
|
||||
// 使用 let 声明可变变量
|
||||
let name = "小明";
|
||||
name = "小红"; // 可以修改
|
||||
|
||||
// 使用 const 声明常量(不可变)
|
||||
const PI = 3.14159;
|
||||
// PI = 3.14; // 错误!常量不能修改
|
||||
|
||||
// 使用 var 声明变量(旧方式,现在推荐使用 let 和 const)
|
||||
var age = 25;
|
||||
```
|
||||
|
||||
**注意**:
|
||||
- 使用 `let` 声明的变量可以重新赋值
|
||||
- 使用 `const` 声明的变量不能重新赋值(常量)
|
||||
- 尽量避免使用 `var`,因为它有一些奇怪的作用域规则
|
||||
|
||||
|
||||
## 数据类型
|
||||
|
||||
JavaScript 有几种基本数据类型:
|
||||
|
||||
### 1. 字符串(String)
|
||||
|
||||
用于表示文本,可以使用单引号或双引号。
|
||||
|
||||
```javascript
|
||||
const greeting = "你好";
|
||||
const name = 'JavaScript';
|
||||
const message = `${greeting}, ${name}!`; // 使用模板字符串(ES6 特性)
|
||||
console.log(message); // 输出:你好, JavaScript!
|
||||
```
|
||||
|
||||
### 2. 数字(Number)
|
||||
|
||||
用于表示数值。
|
||||
|
||||
```javascript
|
||||
const age = 25;
|
||||
const price = 99.99;
|
||||
const PI = 3.14159;
|
||||
```
|
||||
|
||||
### 3. 布尔值(Boolean)
|
||||
|
||||
用于表示真或假,只有两个值:`true` 和 `false`。
|
||||
|
||||
```javascript
|
||||
const isStudent = true;
|
||||
const hasGraduated = false;
|
||||
```
|
||||
|
||||
### 4. 数组(Array)
|
||||
|
||||
用于存储多个值的集合。
|
||||
|
||||
```javascript
|
||||
const fruits = ["苹果", "香蕉", "橙子"];
|
||||
console.log(fruits[0]); // 输出:苹果(数组索引从0开始)
|
||||
|
||||
// 添加元素
|
||||
fruits.push("葡萄");
|
||||
console.log(fruits); // 输出:["苹果", "香蕉", "橙子", "葡萄"]
|
||||
```
|
||||
|
||||
### 5. 对象(Object)
|
||||
|
||||
用于存储键值对集合。
|
||||
|
||||
```javascript
|
||||
const person = {
|
||||
name: "小明",
|
||||
age: 25,
|
||||
isStudent: true,
|
||||
greet: function() {
|
||||
console.log(`你好,我是${this.name}!`);
|
||||
}
|
||||
};
|
||||
|
||||
console.log(person.name); // 输出:小明
|
||||
person.greet(); // 输出:你好,我是小明!
|
||||
```
|
||||
|
||||
## 运算符
|
||||
|
||||
### 算术运算符
|
||||
|
||||
```javascript
|
||||
const a = 10;
|
||||
const b = 5;
|
||||
|
||||
console.log(a + b); // 15 加法
|
||||
console.log(a - b); // 5 减法
|
||||
console.log(a * b); // 50 乘法
|
||||
console.log(a / b); // 2 除法
|
||||
console.log(a % b); // 0 取余
|
||||
console.log(a ** b); // 100000 幂运算(ES6)
|
||||
```
|
||||
|
||||
### 赋值运算符
|
||||
|
||||
```javascript
|
||||
const x = 10;
|
||||
|
||||
x += 5; // 等同于 x = x + 5
|
||||
console.log(x); // 15
|
||||
|
||||
x -= 3; // 等同于 x = x - 3
|
||||
console.log(x); // 12
|
||||
```
|
||||
|
||||
### 比较运算符
|
||||
|
||||
```javascript
|
||||
const a = 10;
|
||||
const b = 5;
|
||||
|
||||
console.log(a > b); // true
|
||||
console.log(a < b); // false
|
||||
console.log(a >= b); // true
|
||||
console.log(a <= b); // false
|
||||
console.log(a === b); // false(严格相等,比较值和类型)
|
||||
console.log(a == b); // false(宽松相等,只比较值)
|
||||
console.log(a !== b); // true(严格不相等)
|
||||
```
|
||||
|
||||
## 条件语句
|
||||
|
||||
### if 语句
|
||||
|
||||
```javascript
|
||||
const age = 18;
|
||||
|
||||
if (age >= 18) {
|
||||
console.log("你已经成年了!");
|
||||
} else if (age >= 13) {
|
||||
console.log("你是青少年。");
|
||||
} else {
|
||||
console.log("你还是个孩子。");
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## 循环
|
||||
|
||||
### for 循环
|
||||
|
||||
```javascript
|
||||
// 打印1到5
|
||||
for (const i = 1; i <= 5; i++) {
|
||||
console.log(i);
|
||||
}
|
||||
|
||||
// 遍历数组
|
||||
const fruits = ["苹果", "香蕉", "橙子"];
|
||||
for (const i = 0; i < fruits.length; i++) {
|
||||
console.log(fruits[i]);
|
||||
}
|
||||
|
||||
// 使用 for...of 遍历(ES6)
|
||||
for (const fruit of fruits) {
|
||||
console.log(fruit);
|
||||
}
|
||||
```
|
||||
|
||||
### while 循环
|
||||
|
||||
```javascript
|
||||
const count = 1;
|
||||
while (count <= 5) {
|
||||
console.log(count);
|
||||
count++;
|
||||
}
|
||||
```
|
||||
|
||||
## 函数
|
||||
|
||||
函数是一段可重复使用的代码块,可以接受输入(参数),执行操作,并返回输出(返回值)。
|
||||
|
||||
### 函数声明
|
||||
|
||||
```javascript
|
||||
function greet(name) {
|
||||
return `你好,${name}!`;
|
||||
}
|
||||
|
||||
const message = greet("小明");
|
||||
console.log(message); // 输出:你好,小明!
|
||||
```
|
||||
|
||||
格式如下
|
||||
|
||||
```javascript
|
||||
function 函数名(参数1, 参数2, ...参数N) {
|
||||
// 函数体:要执行的代码
|
||||
return 返回值; // 可选
|
||||
}
|
||||
```
|
||||
|
||||
### 箭头函数(ES6)
|
||||
|
||||
```javascript
|
||||
const sum = (a, b) => {
|
||||
return a + b;
|
||||
};
|
||||
|
||||
// 简化写法(当只有一行返回语句时)
|
||||
const multiply = (a, b) => a * b;
|
||||
|
||||
console.log(sum(3, 4)); // 7
|
||||
console.log(multiply(3, 4)); // 12
|
||||
```
|
||||
|
||||
## DOM 操作
|
||||
|
||||
DOM(文档对象模型)是 HTML 和 XML 文档的编程接口。JavaScript 可以通过 DOM 来操作网页元素。
|
||||
|
||||
### 选择元素
|
||||
|
||||
```javascript
|
||||
// 通过 id 选择元素
|
||||
const title = document.getElementById("title");
|
||||
|
||||
// 通过 class 选择元素(返回元素集合)
|
||||
const items = document.getElementsByClassName("item");
|
||||
|
||||
// 通过标签名选择元素
|
||||
const paragraphs = document.getElementsByTagName("p");
|
||||
|
||||
// 通过 CSS 选择器选择元素(ES5+)
|
||||
const header = document.querySelector("header"); // 选择第一个匹配的元素
|
||||
const allLinks = document.querySelectorAll("a"); // 选择所有匹配的元素
|
||||
```
|
||||
|
||||
### 修改元素内容
|
||||
|
||||
```javascript
|
||||
// 修改文本内容
|
||||
const title = document.getElementById("title");
|
||||
title.textContent = "新标题";
|
||||
|
||||
// 修改 HTML 内容
|
||||
title.innerHTML = "<strong>加粗的新标题</strong>";
|
||||
```
|
||||
|
||||
### 修改元素样式
|
||||
|
||||
```javascript
|
||||
const element = document.getElementById("box");
|
||||
element.style.color = "red";
|
||||
element.style.fontSize = "20px";
|
||||
element.style.backgroundColor = "#f0f0f0";
|
||||
```
|
||||
|
||||
### 添加事件监听器
|
||||
|
||||
```javascript
|
||||
const button = document.getElementById("myButton");
|
||||
|
||||
button.addEventListener("click", function() {
|
||||
console.log("按钮被点击了!");
|
||||
alert("你好,欢迎使用!");
|
||||
});
|
||||
```
|
||||
|
||||
## 小案例:交互式计算器
|
||||
|
||||
下面是一个简单的交互式计算器示例,演示如何结合 HTML、CSS 和 JavaScript。
|
||||
|
||||
::: code-tabs
|
||||
@tab index.html
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>简易计算器</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="calculator">
|
||||
<h2>简易计算器</h2>
|
||||
<input type="number" id="num1" placeholder="输入第一个数字">
|
||||
<select id="operation">
|
||||
<option value="add">+</option>
|
||||
<option value="subtract">-</option>
|
||||
<option value="multiply">×</option>
|
||||
<option value="divide">÷</option>
|
||||
</select>
|
||||
<input type="number" id="num2" placeholder="输入第二个数字">
|
||||
<button id="calculate">计算</button>
|
||||
<div id="result">结果将显示在这里</div>
|
||||
</div>
|
||||
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
@tab style.css
|
||||
```css
|
||||
.calculator {
|
||||
max-width: 300px;
|
||||
margin: 2rem auto;
|
||||
padding: 1.5rem;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 8px;
|
||||
text-align: center;
|
||||
font-family: system-ui;
|
||||
}
|
||||
|
||||
input, select, button {
|
||||
margin: 0.5rem 0;
|
||||
padding: 0.5rem;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
button {
|
||||
background: #007bff;
|
||||
color: white;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background: #0056b3;
|
||||
}
|
||||
|
||||
#result {
|
||||
margin-top: 1rem;
|
||||
padding: 1rem;
|
||||
background: #f8f9fa;
|
||||
border-radius: 4px;
|
||||
}
|
||||
```
|
||||
@tab script.js
|
||||
```javascript
|
||||
// 获取DOM元素
|
||||
const num1Input = document.getElementById('num1');
|
||||
const num2Input = document.getElementById('num2');
|
||||
const operationSelect = document.getElementById('operation');
|
||||
const calculateButton = document.getElementById('calculate');
|
||||
const resultDiv = document.getElementById('result');
|
||||
|
||||
// 添加点击事件监听器
|
||||
calculateButton.addEventListener('click', function() {
|
||||
// 获取输入值
|
||||
const num1 = parseFloat(num1Input.value);
|
||||
const num2 = parseFloat(num2Input.value);
|
||||
const operation = operationSelect.value;
|
||||
const result;
|
||||
|
||||
// 检查输入是否有效
|
||||
if (isNaN(num1) || isNaN(num2)) {
|
||||
resultDiv.textContent = '请输入有效的数字!';
|
||||
return;
|
||||
}
|
||||
|
||||
// 执行计算
|
||||
switch (operation) {
|
||||
case 'add':
|
||||
result = num1 + num2;
|
||||
break;
|
||||
case 'subtract':
|
||||
result = num1 - num2;
|
||||
break;
|
||||
case 'multiply':
|
||||
result = num1 * num2;
|
||||
break;
|
||||
case 'divide':
|
||||
// 检查除数是否为0
|
||||
if (num2 === 0) {
|
||||
resultDiv.textContent = '除数不能为0!';
|
||||
return;
|
||||
}
|
||||
result = num1 / num2;
|
||||
break;
|
||||
}
|
||||
|
||||
// 显示结果
|
||||
resultDiv.textContent = `计算结果:${result}`;
|
||||
});
|
||||
```
|
||||
:::
|
||||
|
||||
## JavaScript 的异步编程
|
||||
|
||||
JavaScript 是单线程的,但它可以通过异步编程模型来处理耗时操作,如网络请求、定时器等。
|
||||
|
||||
### setTimeout 和 setInterval
|
||||
|
||||
```javascript
|
||||
// setTimeout - 延迟执行一次
|
||||
setTimeout(function() {
|
||||
console.log('2秒后执行');
|
||||
}, 2000);
|
||||
|
||||
// setInterval - 定期重复执行
|
||||
const count = 0;
|
||||
const timer = setInterval(function() {
|
||||
count++;
|
||||
console.log(`执行第 ${count} 次`);
|
||||
|
||||
if (count >= 5) {
|
||||
clearInterval(timer); // 清除定时器
|
||||
console.log('定时器已停止');
|
||||
}
|
||||
}, 1000);
|
||||
```
|
||||
|
||||
### Promise(ES6)
|
||||
|
||||
Promise 是异步编程的一种解决方案,用于处理异步操作。
|
||||
|
||||
```javascript
|
||||
// 创建一个Promise
|
||||
const fetchData = new Promise((resolve, reject) => {
|
||||
// 模拟网络请求
|
||||
setTimeout(() => {
|
||||
const success = true;
|
||||
if (success) {
|
||||
resolve('数据获取成功');
|
||||
} else {
|
||||
reject('数据获取失败');
|
||||
}
|
||||
}, 2000);
|
||||
});
|
||||
|
||||
// 使用Promise
|
||||
fetchData
|
||||
.then(data => {
|
||||
console.log(data);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error(error);
|
||||
});
|
||||
```
|
||||
|
||||
## 常见错误和调试技巧
|
||||
|
||||
### 常见错误
|
||||
|
||||
1. **语法错误**:代码不符合 JavaScript 语法规则
|
||||
2. **引用错误**:使用了未定义的变量或函数
|
||||
3. **类型错误**:对错误类型的值进行操作
|
||||
4. **范围错误**:数值超出有效范围
|
||||
|
||||
### 调试技巧
|
||||
|
||||
1. **使用 console.log()**:在控制台输出变量值或执行流程
|
||||
2. **使用断点**:在浏览器开发者工具中设置断点,逐步执行代码
|
||||
3. **检查错误信息**:仔细阅读错误提示,找出问题所在
|
||||
4. **检查变量类型**:使用 `typeof` 操作符检查变量类型
|
||||
|
||||
```javascript
|
||||
console.log(typeof "hello"); // "string"
|
||||
console.log(typeof 42); // "number"
|
||||
console.log(typeof true); // "boolean"
|
||||
console.log(typeof {}); // "object"
|
||||
console.log(typeof []); // "object"(数组也是对象的一种)
|
||||
```
|
||||
|
||||
## 实践练习
|
||||
|
||||
### 练习1:创建一个简单的待办事项列表
|
||||
|
||||
使用 HTML、CSS 和 JavaScript 创建一个待办事项列表,包含添加、删除和标记完成功能。
|
||||
|
||||
提示:
|
||||
- 使用数组存储待办事项
|
||||
- 使用 DOM 操作动态更新列表
|
||||
- 为按钮添加事件监听器
|
||||
|
||||
### 练习2:实现一个数字猜谜游戏
|
||||
|
||||
计算机随机生成一个1到100之间的数字,玩家通过输入框猜测,程序提示"猜大了"或"猜小了",直到猜对为止。
|
||||
|
||||
提示:
|
||||
- 使用 `Math.random()` 生成随机数
|
||||
- 使用条件语句判断猜测结果
|
||||
- 记录并显示猜测次数
|
||||
|
||||
## 总结
|
||||
|
||||
JavaScript 是现代 web 开发的核心技术之一,它可以让网页变得动态和交互。通过学习变量、数据类型、运算符、条件语句、循环、函数和 DOM 操作等基础知识,你已经迈出了学习 JavaScript 的第一步。
|
||||
|
||||
继续练习和探索,你会发现 JavaScript 的强大功能和灵活性!
|
||||
Reference in New Issue
Block a user