JavaScript練習語法及建議總結(jié)大全
更新時間:2025年07月03日 10:15:40 作者:逍遙自在唯我獨
JavaScript 是一個程序語言,語法規(guī)則定義了語言結(jié)構(gòu),這篇文章主要介紹了JavaScript練習語法及建議總結(jié)的相關(guān)資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
基礎(chǔ)文件
- index.html:主入口頁面,它鏈接了所有示例頁面(如DOM操作、事件處理等)和對應(yīng)的JS文件。
- om.html :展示DOM操作的各種方法
- event.html :展示事件處理的各種類型
- animation.html :展示JavaScript動畫效果
- ajax.html :展示AJAX請求和數(shù)據(jù)處理
- js: 存放js文件
- todo.js - 實現(xiàn)待辦事項列表功能,包括添加、刪除和標記任務(wù)完成
- counter.js - 實現(xiàn)計數(shù)器功能,支持增減、重置、本地存儲和動畫效果
- color.js - 實現(xiàn)顏色選擇器,支持實時預(yù)覽、本地存儲和隨機顏色生成
- form.js - 實現(xiàn)表單驗證功能,包括用戶名、郵箱和密碼的實時驗證
這些JS文件通過“ script ”標簽被引入到HTML頁面中,為頁面添加交互功能。每個文件都專注于實現(xiàn)特定的功能模塊,遵循了模塊化的開發(fā)原則。
綜合練習:在線筆記本
project.html :一個完整的在線筆記本應(yīng)用,整合了所有JavaScript知識點
- 功能包括:
- 筆記的增刪改查
- 標簽管理和篩選
- 搜索功能
- 本地存儲
- 動畫效果
- 事件處理
- 模態(tài)框操作
練習建議 :
- 先從基礎(chǔ)開始,依次練習:
- 主頁面(index.html)
- DOM操作(dom.html)
- 事件處理(event.html)
- 動畫效果(animation.html)
- AJAX請求(ajax.html)
- 最后練習綜合項目(project.html),理解如何將各個知識點結(jié)合使用
index.html
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>JavaScript綜合練習項目</title> <style> /* 基礎(chǔ)樣式 */ * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: Arial, sans-serif; line-height: 1.6; padding: 20px; background-color: #f0f2f5; } .container { max-width: 1200px; margin: 0 auto; } nav { background-color: #fff; padding: 1rem; border-radius: 8px; margin-bottom: 20px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); } nav ul { list-style: none; display: flex; gap: 20px; } nav a { text-decoration: none; color: #333; padding: 5px 10px; border-radius: 4px; transition: background-color 0.3s; } nav a:hover { background-color: #e6e6e6; } .section { background-color: #fff; padding: 20px; border-radius: 8px; margin-bottom: 20px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); } h1, h2 { margin-bottom: 1rem; color: #333; } button { padding: 8px 16px; background-color: #1890ff; color: white; border: none; border-radius: 4px; cursor: pointer; transition: background-color 0.3s; } button:hover { background-color: #40a9ff; } input, textarea { padding: 8px; border: 1px solid #d9d9d9; border-radius: 4px; width: 100%; margin-bottom: 10px; } .todo-list { list-style: none; } .todo-item { display: flex; align-items: center; padding: 10px; background-color: #fafafa; margin-bottom: 5px; border-radius: 4px; } .todo-item input[type="checkbox"] { width: auto; margin-right: 10px; } .completed { text-decoration: line-through; color: #999; } </style> </head> <body> <div class="container"> <h1>JavaScript綜合練習項目</h1> <nav> <ul> <li><a href="index.html" rel="external nofollow" >首頁</a></li> <li><a href="dom.html" rel="external nofollow" >DOM操作</a></li> <li><a href="event.html" rel="external nofollow" >事件處理</a></li> <li><a href="ajax.html" rel="external nofollow" >AJAX請求</a></li> <li><a href="animation.html" rel="external nofollow" >動畫效果</a></li> </ul> </nav> <!-- 待辦事項列表部分 --> <section class="section" id="todo-section"> <h2>待辦事項列表</h2> <div> <input type="text" id="todo-input" placeholder="輸入新的待辦事項"> <button id="add-todo">添加</button> </div> <ul class="todo-list" id="todo-list"> <!-- 待辦事項將通過JavaScript動態(tài)添加 --> </ul> </section> <!-- 計數(shù)器部分 --> <section class="section" id="counter-section"> <h2>計數(shù)器</h2> <div> <button id="decrease">-</button> <span id="count">0</span> <button id="increase">+</button> <button id="reset">重置</button> </div> </section> <!-- 顏色選擇器部分 --> <section class="section" id="color-section"> <h2>顏色選擇器</h2> <div> <input type="color" id="color-picker"> <div id="color-display" style="width: 100px; height: 100px; margin-top: 10px; border: 1px solid #ccc;"></div> </div> </section> <!-- 表單驗證部分 --> <section class="section" id="form-section"> <h2>表單驗證</h2> <form id="validation-form"> <div> <input type="text" id="username" placeholder="用戶名(3-10個字符)"> <span id="username-error" style="color: red;"></span> </div> <div> <input type="email" id="email" placeholder="郵箱地址"> <span id="email-error" style="color: red;"></span> </div> <div> <input type="password" id="password" placeholder="密碼(至少6個字符)"> <span id="password-error" style="color: red;"></span> </div> <button type="submit">提交</button> </form> </section> </div> <!-- 引入JavaScript文件 --> <script src="js/todo.js"></script> <script src="js/counter.js"></script> <script src="js/color.js"></script> <script src="js/form.js"></script> </body> </html>
1.dom.html
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>DOM操作示例</title> <style> /* 基礎(chǔ)樣式 */ * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: Arial, sans-serif; line-height: 1.6; padding: 20px; background-color: #f0f2f5; } .container { max-width: 1200px; margin: 0 auto; } .section { background-color: #fff; padding: 20px; border-radius: 8px; margin-bottom: 20px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); } button { padding: 8px 16px; background-color: #1890ff; color: white; border: none; border-radius: 4px; cursor: pointer; margin: 5px; transition: background-color 0.3s; } button:hover { background-color: #40a9ff; } .demo-box { border: 1px solid #d9d9d9; padding: 10px; margin: 10px 0; border-radius: 4px; } .highlight { background-color: #fff7e6; border-color: #ffd591; } .list-item { padding: 8px; margin: 4px 0; background-color: #f5f5f5; border-radius: 4px; display: flex; justify-content: space-between; align-items: center; } .success { color: #52c41a; } .error { color: #f5222d; } </style> </head> <body> <div class="container"> <h1>DOM操作示例</h1> <nav> <button onclick="location.href='index.html'">返回首頁</button> </nav> <!-- 元素選擇和修改 --> <section class="section"> <h2>元素選擇和修改</h2> <div class="demo-box" id="select-demo"> <p id="target-text">這是目標文本</p> <p class="sample-class">使用類選擇器選擇的文本</p> <p data-type="special">使用屬性選擇器選擇的文本</p> </div> <div> <button onclick="changeText()">修改文本</button> <button onclick="changeStyle()">修改樣式</button> <button onclick="changeAttribute()">修改屬性</button> </div> </section> <!-- 元素創(chuàng)建和添加 --> <section class="section"> <h2>元素創(chuàng)建和添加</h2> <div class="demo-box" id="create-demo"> <div id="element-container"></div> </div> <div> <button onclick="createElement()">創(chuàng)建元素</button> <button onclick="cloneElement()">克隆元素</button> <button onclick="insertElement()">插入元素</button> </div> </section> <!-- 元素刪除和替換 --> <section class="section"> <h2>元素刪除和替換</h2> <div class="demo-box" id="modify-demo"> <ul id="item-list"> <li class="list-item">項目 1</li> <li class="list-item">項目 2</li> <li class="list-item">項目 3</li> </ul> </div> <div> <button onclick="removeElement()">刪除元素</button> <button onclick="replaceElement()">替換元素</button> <button onclick="resetList()">重置列表</button> </div> </section> <!-- 事件處理 --> <section class="section"> <h2>事件處理</h2> <div class="demo-box" id="event-demo"> <div id="event-target" style="padding: 20px; background-color: #f5f5f5; text-align: center;"> 在此區(qū)域內(nèi)移動鼠標或點擊 </div> <p id="event-info"></p> </div> </section> </div> <script> // 元素選擇和修改 function changeText() { // 通過ID選擇元素并修改文本 const element = document.getElementById('target-text'); element.textContent = '文本已被修改!' + new Date().toLocaleTimeString(); } function changeStyle() { // 通過類名選擇元素并修改樣式 const elements = document.getElementsByClassName('sample-class'); for (let element of elements) { element.classList.toggle('highlight'); } } function changeAttribute() { // 通過屬性選擇器選擇元素并修改屬性 const element = document.querySelector('[data-type="special"]'); const currentType = element.getAttribute('data-type'); element.setAttribute('data-type', currentType === 'special' ? 'normal' : 'special'); element.textContent = `當前屬性值:${element.getAttribute('data-type')}`; } // 元素創(chuàng)建和添加 let elementCount = 0; function createElement() { elementCount++; // 創(chuàng)建新元素 const newElement = document.createElement('div'); newElement.className = 'list-item'; newElement.textContent = `新元素 ${elementCount}`; // 添加到容器 document.getElementById('element-container').appendChild(newElement); } function cloneElement() { const container = document.getElementById('element-container'); if (container.children.length > 0) { // 克隆最后一個元素 const lastElement = container.lastElementChild; const clone = lastElement.cloneNode(true); clone.textContent += ' (克隆)'; container.appendChild(clone); } } function insertElement() { const container = document.getElementById('element-container'); // 創(chuàng)建新元素 const newElement = document.createElement('div'); newElement.className = 'list-item'; newElement.textContent = '插入的元素'; // 在第一個子元素之前插入 if (container.firstChild) { container.insertBefore(newElement, container.firstChild); } else { container.appendChild(newElement); } } // 元素刪除和替換 function removeElement() { const list = document.getElementById('item-list'); if (list.children.length > 0) { list.removeChild(list.lastElementChild); } } function replaceElement() { const list = document.getElementById('item-list'); if (list.children.length > 0) { // 創(chuàng)建新元素 const newElement = document.createElement('li'); newElement.className = 'list-item'; newElement.textContent = '替換的項目 ' + new Date().toLocaleTimeString(); // 替換第一個元素 list.replaceChild(newElement, list.firstElementChild); } } function resetList() { document.getElementById('item-list').innerHTML = ` <li class="list-item">項目 1</li> <li class="list-item">項目 2</li> <li class="list-item">項目 3</li> `; } // 事件處理 document.addEventListener('DOMContentLoaded', function() { const eventTarget = document.getElementById('event-target'); const eventInfo = document.getElementById('event-info'); // 鼠標移動事件 eventTarget.addEventListener('mousemove', function(e) { const rect = eventTarget.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; eventInfo.textContent = `鼠標位置 - X: ${Math.round(x)}px, Y: ${Math.round(y)}px`; }); // 點擊事件 eventTarget.addEventListener('click', function(e) { eventTarget.style.backgroundColor = '#' + Math.floor(Math.random()*16777215).toString(16); }); // 鼠標進入事件 eventTarget.addEventListener('mouseenter', function() { eventTarget.style.transform = 'scale(1.02)'; }); // 鼠標離開事件 eventTarget.addEventListener('mouseleave', function() { eventTarget.style.transform = 'scale(1)'; }); }); </script> </body> </html>
2.event.html
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>事件處理示例</title> <style> /* 基礎(chǔ)樣式 */ * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: Arial, sans-serif; line-height: 1.6; padding: 20px; background-color: #f0f2f5; } .container { max-width: 1200px; margin: 0 auto; } .section { background-color: #fff; padding: 20px; border-radius: 8px; margin-bottom: 20px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); } .demo-box { border: 1px solid #d9d9d9; padding: 15px; margin: 10px 0; border-radius: 4px; background-color: #fafafa; } .event-log { height: 100px; overflow-y: auto; padding: 10px; background-color: #f5f5f5; border-radius: 4px; margin-top: 10px; font-family: monospace; } .interactive-area { width: 200px; height: 200px; background-color: #e6f7ff; display: flex; align-items: center; justify-content: center; cursor: pointer; transition: all 0.3s; user-select: none; } .key-display { font-size: 2em; text-align: center; padding: 20px; background-color: #f0f0f0; border-radius: 4px; margin: 10px 0; } button { padding: 8px 16px; background-color: #1890ff; color: white; border: none; border-radius: 4px; cursor: pointer; margin: 5px; transition: background-color 0.3s; } button:hover { background-color: #40a9ff; } input[type="text"] { padding: 8px; border: 1px solid #d9d9d9; border-radius: 4px; width: 200px; margin: 5px; } .drag-item { width: 100px; height: 100px; background-color: #91d5ff; display: flex; align-items: center; justify-content: center; cursor: move; margin: 10px; transition: transform 0.2s; } .drop-zone { width: 200px; height: 200px; border: 2px dashed #1890ff; display: flex; align-items: center; justify-content: center; margin: 10px; } .drop-zone.dragover { background-color: #e6f7ff; border-style: solid; } </style> </head> <body> <div class="container"> <h1>事件處理示例</h1> <nav> <button onclick="location.href='index.html'">返回首頁</button> </nav> <!-- 鼠標事件 --> <section class="section"> <h2>鼠標事件</h2> <div class="demo-box"> <div id="mouse-area" class="interactive-area">在此區(qū)域操作鼠標</div> <div id="mouse-log" class="event-log"></div> </div> </section> <!-- 鍵盤事件 --> <section class="section"> <h2>鍵盤事件</h2> <div class="demo-box"> <input type="text" id="key-input" placeholder="在此輸入文字"> <div id="key-display" class="key-display">按下任意鍵</div> <div id="key-log" class="event-log"></div> </div> </section> <!-- 表單事件 --> <section class="section"> <h2>表單事件</h2> <div class="demo-box"> <form id="demo-form"> <input type="text" id="form-input" placeholder="輸入文字"> <select id="form-select"> <option value="">請選擇</option> <option value="1">選項1</option> <option value="2">選項2</option> <option value="3">選項3</option> </select> <button type="submit">提交</button> </form> <div id="form-log" class="event-log"></div> </div> </section> <!-- 拖放事件 --> <section class="section"> <h2>拖放事件</h2> <div class="demo-box"> <div style="display: flex;"> <div id="drag-item" class="drag-item" draggable="true">拖動我</div> <div id="drop-zone" class="drop-zone">放置區(qū)域</div> </div> <div id="drag-log" class="event-log"></div> </div> </section> </div> <script> // 工具函數(shù):記錄事件到日志 function logEvent(logElement, message) { const log = document.createElement('div'); log.textContent = `${new Date().toLocaleTimeString()} - ${message}`; logElement.insertBefore(log, logElement.firstChild); // 限制日志條數(shù) if (logElement.children.length > 10) { logElement.removeChild(logElement.lastChild); } } // 鼠標事件處理 document.addEventListener('DOMContentLoaded', function() { const mouseArea = document.getElementById('mouse-area'); const mouseLog = document.getElementById('mouse-log'); // 鼠標進入 mouseArea.addEventListener('mouseenter', function(e) { mouseArea.style.backgroundColor = '#bae7ff'; logEvent(mouseLog, '鼠標進入?yún)^(qū)域'); }); // 鼠標移動 mouseArea.addEventListener('mousemove', function(e) { const rect = mouseArea.getBoundingClientRect(); const x = Math.round(e.clientX - rect.left); const y = Math.round(e.clientY - rect.top); mouseArea.textContent = `X: ${x}, Y: ${y}`; }); // 鼠標離開 mouseArea.addEventListener('mouseleave', function(e) { mouseArea.style.backgroundColor = '#e6f7ff'; mouseArea.textContent = '在此區(qū)域操作鼠標'; logEvent(mouseLog, '鼠標離開區(qū)域'); }); // 鼠標點擊 mouseArea.addEventListener('click', function(e) { mouseArea.style.transform = 'scale(0.95)'; setTimeout(() => mouseArea.style.transform = 'scale(1)', 200); logEvent(mouseLog, '鼠標點擊'); }); // 鼠標右鍵 mouseArea.addEventListener('contextmenu', function(e) { e.preventDefault(); logEvent(mouseLog, '鼠標右鍵點擊'); }); }); // 鍵盤事件處理 document.addEventListener('DOMContentLoaded', function() { const keyInput = document.getElementById('key-input'); const keyDisplay = document.getElementById('key-display'); const keyLog = document.getElementById('key-log'); // 鍵盤按下 keyInput.addEventListener('keydown', function(e) { keyDisplay.textContent = e.key; keyDisplay.style.backgroundColor = '#bae7ff'; logEvent(keyLog, `按下鍵: ${e.key}`); }); // 鍵盤釋放 keyInput.addEventListener('keyup', function(e) { keyDisplay.style.backgroundColor = '#f0f0f0'; logEvent(keyLog, `釋放鍵: ${e.key}`); }); // 輸入事件 keyInput.addEventListener('input', function(e) { logEvent(keyLog, `輸入內(nèi)容: ${e.target.value}`); }); }); // 表單事件處理 document.addEventListener('DOMContentLoaded', function() { const form = document.getElementById('demo-form'); const formInput = document.getElementById('form-input'); const formSelect = document.getElementById('form-select'); const formLog = document.getElementById('form-log'); // 表單提交 form.addEventListener('submit', function(e) { e.preventDefault(); logEvent(formLog, '表單提交'); }); // 輸入框焦點 formInput.addEventListener('focus', function(e) { this.style.borderColor = '#40a9ff'; logEvent(formLog, '輸入框獲得焦點'); }); formInput.addEventListener('blur', function(e) { this.style.borderColor = '#d9d9d9'; logEvent(formLog, '輸入框失去焦點'); }); // 選擇框變化 formSelect.addEventListener('change', function(e) { logEvent(formLog, `選擇值改變: ${e.target.value}`); }); }); // 拖放事件處理 document.addEventListener('DOMContentLoaded', function() { const dragItem = document.getElementById('drag-item'); const dropZone = document.getElementById('drop-zone'); const dragLog = document.getElementById('drag-log'); // 拖動開始 dragItem.addEventListener('dragstart', function(e) { this.style.opacity = '0.5'; logEvent(dragLog, '開始拖動'); }); // 拖動結(jié)束 dragItem.addEventListener('dragend', function(e) { this.style.opacity = '1'; logEvent(dragLog, '結(jié)束拖動'); }); // 拖動進入放置區(qū)域 dropZone.addEventListener('dragenter', function(e) { e.preventDefault(); this.classList.add('dragover'); logEvent(dragLog, '進入放置區(qū)域'); }); // 拖動在放置區(qū)域上方 dropZone.addEventListener('dragover', function(e) { e.preventDefault(); }); // 離開放置區(qū)域 dropZone.addEventListener('dragleave', function(e) { this.classList.remove('dragover'); logEvent(dragLog, '離開放置區(qū)域'); }); // 在放置區(qū)域釋放 dropZone.addEventListener('drop', function(e) { e.preventDefault(); this.classList.remove('dragover'); this.appendChild(dragItem); logEvent(dragLog, '成功放置'); }); }); </script> </body> </html>
3.animation.html
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>動畫效果示例</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: Arial, sans-serif; line-height: 1.6; padding: 20px; background-color: #f0f2f5; } .container { max-width: 1200px; margin: 0 auto; } .section { background-color: #fff; padding: 20px; border-radius: 8px; margin-bottom: 20px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); } .demo-box { border: 1px solid #d9d9d9; padding: 15px; margin: 10px 0; border-radius: 4px; background-color: #fafafa; min-height: 200px; position: relative; } button { padding: 8px 16px; background-color: #1890ff; color: white; border: none; border-radius: 4px; cursor: pointer; margin: 5px; transition: background-color 0.3s; } button:hover { background-color: #40a9ff; } .animation-box { width: 50px; height: 50px; background-color: #1890ff; position: absolute; left: 0; top: 50%; transform: translateY(-50%); } .bounce-box { width: 50px; height: 50px; background-color: #52c41a; border-radius: 50%; position: absolute; left: 50%; transform: translateX(-50%); top: 0; } .rotate-box { width: 100px; height: 100px; background-color: #722ed1; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); } .particle { width: 10px; height: 10px; background-color: #f5222d; border-radius: 50%; position: absolute; left: 50%; top: 50%; } .progress-bar { width: 100%; height: 20px; background-color: #f5f5f5; border-radius: 10px; overflow: hidden; margin: 10px 0; } .progress-fill { width: 0; height: 100%; background-color: #1890ff; transition: width 0.3s ease; } .controls { margin: 10px 0; } </style> </head> <body> <div class="container"> <h1>動畫效果示例</h1> <nav> <button onclick="location.href='index.html'">返回首頁</button> </nav> <!-- 基礎(chǔ)動畫 --> <section class="section"> <h2>基礎(chǔ)動畫</h2> <div class="demo-box"> <div class="controls"> <button onclick="startBasicAnimation()">開始動畫</button> <button onclick="pauseBasicAnimation()">暫停</button> <button onclick="resetBasicAnimation()">重置</button> </div> <div id="basic-animation" class="animation-box"></div> </div> </section> <!-- 彈跳動畫 --> <section class="section"> <h2>彈跳動畫</h2> <div class="demo-box"> <div class="controls"> <button onclick="startBounceAnimation()">開始彈跳</button> <button onclick="stopBounceAnimation()">停止</button> </div> <div id="bounce-animation" class="bounce-box"></div> </div> </section> <!-- 旋轉(zhuǎn)和縮放 --> <section class="section"> <h2>旋轉(zhuǎn)和縮放</h2> <div class="demo-box"> <div class="controls"> <button onclick="startRotateScale()">開始動畫</button> <button onclick="stopRotateScale()">停止</button> </div> <div id="rotate-scale" class="rotate-box"></div> </div> </section> <!-- 粒子效果 --> <section class="section"> <h2>粒子效果</h2> <div class="demo-box"> <div class="controls"> <button onclick="createParticles()">創(chuàng)建粒子</button> </div> <div id="particle-container"></div> </div> </section> <!-- 進度條動畫 --> <section class="section"> <h2>進度條動畫</h2> <div class="demo-box"> <div class="controls"> <button onclick="startProgress()">開始進度</button> <button onclick="resetProgress()">重置</button> </div> <div class="progress-bar"> <div id="progress" class="progress-fill"></div> </div> </div> </section> </div> <script> // 基礎(chǔ)動畫 let basicAnimationId = null; let basicAnimationPaused = false; let basicAnimationPosition = 0; let lastTimestamp = 0; function startBasicAnimation() { if (basicAnimationPaused) { basicAnimationPaused = false; lastTimestamp = performance.now(); requestAnimationFrame(animateBasic); return; } const box = document.getElementById('basic-animation'); const container = box.parentElement; const maxDistance = container.clientWidth - box.clientWidth; function animateBasic(timestamp) { if (basicAnimationPaused) return; if (!lastTimestamp) lastTimestamp = timestamp; const progress = timestamp - lastTimestamp; lastTimestamp = timestamp; basicAnimationPosition += progress * 0.2; if (basicAnimationPosition >= maxDistance) { basicAnimationPosition = 0; } box.style.left = `${basicAnimationPosition}px`; basicAnimationId = requestAnimationFrame(animateBasic); } basicAnimationId = requestAnimationFrame(animateBasic); } function pauseBasicAnimation() { basicAnimationPaused = true; } function resetBasicAnimation() { basicAnimationPaused = true; cancelAnimationFrame(basicAnimationId); basicAnimationPosition = 0; lastTimestamp = 0; const box = document.getElementById('basic-animation'); box.style.left = '0px'; } // 彈跳動畫 let bounceAnimationId = null; let bounceVelocity = 5; const gravity = 0.5; const bounce = -0.7; function startBounceAnimation() { const box = document.getElementById('bounce-animation'); const container = box.parentElement; let position = 0; function animate() { position += bounceVelocity; bounceVelocity += gravity; // 碰到底部 if (position + box.clientHeight > container.clientHeight) { position = container.clientHeight - box.clientHeight; bounceVelocity *= bounce; } box.style.top = `${position}px`; bounceAnimationId = requestAnimationFrame(animate); } bounceAnimationId = requestAnimationFrame(animate); } function stopBounceAnimation() { cancelAnimationFrame(bounceAnimationId); const box = document.getElementById('bounce-animation'); box.style.top = '0px'; bounceVelocity = 5; } // 旋轉(zhuǎn)和縮放 let rotateScaleId = null; let angle = 0; let scale = 1; let scaleGrowing = true; function startRotateScale() { const box = document.getElementById('rotate-scale'); function animate() { angle = (angle + 2) % 360; if (scaleGrowing) { scale += 0.01; if (scale >= 1.5) scaleGrowing = false; } else { scale -= 0.01; if (scale <= 0.5) scaleGrowing = true; } box.style.transform = `translate(-50%, -50%) rotate(${angle}deg) scale(${scale})`; rotateScaleId = requestAnimationFrame(animate); } rotateScaleId = requestAnimationFrame(animate); } function stopRotateScale() { cancelAnimationFrame(rotateScaleId); const box = document.getElementById('rotate-scale'); box.style.transform = 'translate(-50%, -50%)'; angle = 0; scale = 1; scaleGrowing = true; } // 粒子效果 function createParticles() { const container = document.getElementById('particle-container'); container.innerHTML = ''; const particleCount = 20; for (let i = 0; i < particleCount; i++) { const particle = document.createElement('div'); particle.className = 'particle'; container.appendChild(particle); const angle = (Math.PI * 2 * i) / particleCount; const velocity = 5; let x = 0; let y = 0; let vx = Math.cos(angle) * velocity; let vy = Math.sin(angle) * velocity; let opacity = 1; function animate() { x += vx; y += vy; vy += 0.1; // 重力 opacity -= 0.01; if (opacity <= 0) { particle.remove(); return; } particle.style.transform = `translate(${x}px, ${y}px)`; particle.style.opacity = opacity; requestAnimationFrame(animate); } requestAnimationFrame(animate); } } // 進度條動畫 let progressInterval = null; function startProgress() { const progress = document.getElementById('progress'); let width = 0; progressInterval = setInterval(() => { if (width >= 100) { clearInterval(progressInterval); return; } width += 1; progress.style.width = `${width}%`; }, 50); } function resetProgress() { clearInterval(progressInterval); const progress = document.getElementById('progress'); progress.style.width = '0%'; } </script> </body> </html>
4.ajax.html
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>AJAX請求示例</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: Arial, sans-serif; line-height: 1.6; padding: 20px; background-color: #f0f2f5; } .container { max-width: 1200px; margin: 0 auto; } .section { background-color: #fff; padding: 20px; border-radius: 8px; margin-bottom: 20px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); } .demo-box { border: 1px solid #d9d9d9; padding: 15px; margin: 10px 0; border-radius: 4px; background-color: #fafafa; } button { padding: 8px 16px; background-color: #1890ff; color: white; border: none; border-radius: 4px; cursor: pointer; margin: 5px; transition: background-color 0.3s; } button:hover { background-color: #40a9ff; } button:disabled { background-color: #d9d9d9; cursor: not-allowed; } .result { margin-top: 10px; padding: 10px; background-color: #f5f5f5; border-radius: 4px; font-family: monospace; white-space: pre-wrap; max-height: 200px; overflow-y: auto; } .error { color: #f5222d; } .success { color: #52c41a; } .loading { display: inline-block; width: 20px; height: 20px; border: 3px solid #f3f3f3; border-top: 3px solid #1890ff; border-radius: 50%; animation: spin 1s linear infinite; margin-left: 10px; vertical-align: middle; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } input[type="text"], textarea { padding: 8px; border: 1px solid #d9d9d9; border-radius: 4px; width: 100%; margin: 5px 0; } .status { margin-top: 10px; font-style: italic; } </style> </head> <body> <div class="container"> <h1>AJAX請求示例</h1> <nav> <button onclick="location.href='index.html'">返回首頁</button> </nav> <!-- XMLHttpRequest GET請求 --> <section class="section"> <h2>XMLHttpRequest GET請求</h2> <div class="demo-box"> <button onclick="makeXHRGet()">發(fā)送GET請求</button> <div id="xhr-get-result" class="result"></div> </div> </section> <!-- Fetch API GET請求 --> <section class="section"> <h2>Fetch API GET請求</h2> <div class="demo-box"> <button onclick="makeFetchGet()">發(fā)送GET請求</button> <div id="fetch-get-result" class="result"></div> </div> </section> <!-- POST請求 --> <section class="section"> <h2>POST請求</h2> <div class="demo-box"> <textarea id="post-data" rows="4" placeholder="輸入要發(fā)送的JSON數(shù)據(jù)">{ "name": "張三", "age": 25, "message": "Hello, World!" }</textarea> <button onclick="makePost()">發(fā)送POST請求</button> <div id="post-result" class="result"></div> </div> </section> <!-- 文件上傳 --> <section class="section"> <h2>文件上傳</h2> <div class="demo-box"> <input type="file" id="file-input"> <button onclick="uploadFile()">上傳文件</button> <div id="upload-progress" class="status"></div> <div id="upload-result" class="result"></div> </div> </section> <!-- 并發(fā)請求 --> <section class="section"> <h2>并發(fā)請求</h2> <div class="demo-box"> <button onclick="makeConcurrentRequests()">發(fā)送并發(fā)請求</button> <div id="concurrent-result" class="result"></div> </div> </section> </div> <script> // 模擬API端點 const API_ENDPOINT = 'https://jsonplaceholder.typicode.com'; // 工具函數(shù):格式化響應(yīng)數(shù)據(jù) function formatResponse(data) { return typeof data === 'object' ? JSON.stringify(data, null, 2) : data; } // 工具函數(shù):顯示結(jié)果 function showResult(elementId, data, isError = false) { const element = document.getElementById(elementId); element.textContent = formatResponse(data); element.className = `result ${isError ? 'error' : 'success'}`; } // 工具函數(shù):顯示加載狀態(tài) function showLoading(elementId, isLoading) { const element = document.getElementById(elementId); const loadingSpinner = element.parentElement.querySelector('.loading'); if (isLoading) { if (!loadingSpinner) { const spinner = document.createElement('div'); spinner.className = 'loading'; element.parentElement.insertBefore(spinner, element); } } else { if (loadingSpinner) { loadingSpinner.remove(); } } } // XMLHttpRequest GET請求 function makeXHRGet() { const resultId = 'xhr-get-result'; showLoading(resultId, true); const xhr = new XMLHttpRequest(); xhr.open('GET', `${API_ENDPOINT}/posts/1`, true); xhr.onreadystatechange = function() { if (xhr.readyState === 4) { showLoading(resultId, false); if (xhr.status === 200) { showResult(resultId, JSON.parse(xhr.responseText)); } else { showResult(resultId, `請求失敗: ${xhr.status} ${xhr.statusText}`, true); } } }; xhr.onerror = function() { showLoading(resultId, false); showResult(resultId, '網(wǎng)絡(luò)錯誤', true); }; xhr.send(); } // Fetch API GET請求 async function makeFetchGet() { const resultId = 'fetch-get-result'; showLoading(resultId, true); try { const response = await fetch(`${API_ENDPOINT}/posts/1`); if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`); const data = await response.json(); showResult(resultId, data); } catch (error) { showResult(resultId, `請求失敗: ${error.message}`, true); } finally { showLoading(resultId, false); } } // POST請求 async function makePost() { const resultId = 'post-result'; showLoading(resultId, true); try { const postData = JSON.parse(document.getElementById('post-data').value); const response = await fetch(`${API_ENDPOINT}/posts`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(postData) }); if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`); const data = await response.json(); showResult(resultId, data); } catch (error) { showResult(resultId, `請求失敗: ${error.message}`, true); } finally { showLoading(resultId, false); } } // 文件上傳 function uploadFile() { const resultId = 'upload-result'; const progressElement = document.getElementById('upload-progress'); const fileInput = document.getElementById('file-input'); const file = fileInput.files[0]; if (!file) { showResult(resultId, '請選擇文件', true); return; } showLoading(resultId, true); const formData = new FormData(); formData.append('file', file); const xhr = new XMLHttpRequest(); xhr.open('POST', `${API_ENDPOINT}/posts`, true); xhr.upload.onprogress = function(e) { if (e.lengthComputable) { const percentComplete = Math.round((e.loaded / e.total) * 100); progressElement.textContent = `上傳進度: ${percentComplete}%`; } }; xhr.onload = function() { showLoading(resultId, false); if (xhr.status === 200) { showResult(resultId, '文件上傳成功'); } else { showResult(resultId, `上傳失敗: ${xhr.status} ${xhr.statusText}`, true); } }; xhr.onerror = function() { showLoading(resultId, false); showResult(resultId, '網(wǎng)絡(luò)錯誤', true); }; xhr.send(formData); } // 并發(fā)請求 async function makeConcurrentRequests() { const resultId = 'concurrent-result'; showLoading(resultId, true); try { const requests = [ fetch(`${API_ENDPOINT}/posts/1`).then(r => r.json()), fetch(`${API_ENDPOINT}/posts/2`).then(r => r.json()), fetch(`${API_ENDPOINT}/posts/3`).then(r => r.json()) ]; const results = await Promise.all(requests); showResult(resultId, results); } catch (error) { showResult(resultId, `請求失敗: ${error.message}`, true); } finally { showLoading(resultId, false); } } // 自定義AJAX函數(shù)封裝 function ajax(options) { return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); xhr.open(options.method || 'GET', options.url, true); if (options.headers) { Object.keys(options.headers).forEach(key => { xhr.setRequestHeader(key, options.headers[key]); }); } xhr.onreadystatechange = function() { if (xhr.readyState === 4) { if (xhr.status >= 200 && xhr.status < 300) { resolve({ data: JSON.parse(xhr.responseText), status: xhr.status, statusText: xhr.statusText }); } else { reject(new Error(`請求失敗: ${xhr.status} ${xhr.statusText}`)); } } }; xhr.onerror = () => reject(new Error('網(wǎng)絡(luò)錯誤')); xhr.send(options.data); }); } </script> </body> </html>
5. color.js
// color.js - 顏色選擇器功能實現(xiàn) // 等待DOM完全加載后執(zhí)行 document.addEventListener('DOMContentLoaded', function() { // 獲取DOM元素 const colorPicker = document.getElementById('color-picker'); // 顏色選擇輸入框 const colorDisplay = document.getElementById('color-display'); // 顏色顯示區(qū)域 // 從localStorage加載保存的顏色 function loadColor() { // 嘗試從localStorage獲取保存的顏色值 const savedColor = localStorage.getItem('selectedColor'); if (savedColor) { // 如果有保存的顏色,更新選擇器和顯示區(qū)域 colorPicker.value = savedColor; updateColorDisplay(savedColor); } } // 保存顏色到localStorage function saveColor(color) { localStorage.setItem('selectedColor', color); } // 更新顏色顯示 function updateColorDisplay(color) { // 更新顯示區(qū)域的背景顏色 colorDisplay.style.backgroundColor = color; // 計算顏色的亮度 const rgb = hexToRgb(color); const brightness = calculateBrightness(rgb); // 根據(jù)背景色的亮度設(shè)置文本顏色 colorDisplay.style.color = brightness > 128 ? '#000' : '#fff'; // 顯示顏色值 colorDisplay.textContent = color.toUpperCase(); // 添加過渡動畫 addTransitionEffect(); } // 將十六進制顏色轉(zhuǎn)換為RGB function hexToRgb(hex) { // 移除#號(如果有) hex = hex.replace('#', ''); // 將十六進制轉(zhuǎn)換為RGB值 const r = parseInt(hex.substring(0, 2), 16); const g = parseInt(hex.substring(2, 4), 16); const b = parseInt(hex.substring(4, 6), 16); return { r, g, b }; } // 計算顏色的亮度 function calculateBrightness({ r, g, b }) { // 使用相對亮度公式:(0.299*R + 0.587*G + 0.114*B) return (0.299 * r + 0.587 * g + 0.114 * b); } // 添加過渡效果 function addTransitionEffect() { // 添加過渡類 colorDisplay.classList.add('color-transition'); // 移除過渡類 setTimeout(() => { colorDisplay.classList.remove('color-transition'); }, 300); } // 生成隨機顏色 function generateRandomColor() { // 生成隨機的RGB值 const r = Math.floor(Math.random() * 256); const g = Math.floor(Math.random() * 256); const b = Math.floor(Math.random() * 256); // 轉(zhuǎn)換為十六進制 const hex = '#' + [ r.toString(16).padStart(2, '0'), g.toString(16).padStart(2, '0'), b.toString(16).padStart(2, '0') ].join(''); return hex; } // 添加雙擊事件來生成隨機顏色 colorDisplay.addEventListener('dblclick', function() { const randomColor = generateRandomColor(); colorPicker.value = randomColor; updateColorDisplay(randomColor); saveColor(randomColor); }); // 添加顏色選擇事件監(jiān)聽器 colorPicker.addEventListener('input', function(e) { // 獲取選擇的顏色 const selectedColor = e.target.value; // 更新顯示并保存 updateColorDisplay(selectedColor); saveColor(selectedColor); }); // 添加動畫樣式 const style = document.createElement('style'); style.textContent = ` #color-display { display: flex; align-items: center; justify-content: center; font-family: monospace; transition: background-color 0.3s ease; cursor: pointer; } .color-transition { animation: colorPulse 0.3s ease; } @keyframes colorPulse { 0% { transform: scale(1); } 50% { transform: scale(1.05); } 100% { transform: scale(1); } } `; document.head.appendChild(style); // 添加提示信息 colorDisplay.title = '雙擊生成隨機顏色'; // 頁面加載時加載保存的顏色 loadColor(); });
6. counter.js
// counter.js - 計數(shù)器功能實現(xiàn) // 等待DOM完全加載后執(zhí)行 document.addEventListener('DOMContentLoaded', function() { // 獲取DOM元素 const decreaseBtn = document.getElementById('decrease'); // 減少按鈕 const increaseBtn = document.getElementById('increase'); // 增加按鈕 const resetBtn = document.getElementById('reset'); // 重置按鈕 const countSpan = document.getElementById('count'); // 顯示計數(shù)的span元素 // 計數(shù)變量 let count = 0; // 從localStorage加載保存的計數(shù) function loadCount() { // 嘗試從localStorage獲取保存的計數(shù)值 const savedCount = localStorage.getItem('count'); if (savedCount !== null) { // 如果有保存的值,更新count和顯示 count = parseInt(savedCount); updateDisplay(); } } // 保存計數(shù)到localStorage function saveCount() { localStorage.setItem('count', count.toString()); } // 更新顯示 function updateDisplay() { // 更新顯示的數(shù)字 countSpan.textContent = count; // 根據(jù)數(shù)值設(shè)置顏色 if (count > 0) { countSpan.style.color = 'green'; } else if (count < 0) { countSpan.style.color = 'red'; } else { countSpan.style.color = 'black'; } } // 減少計數(shù) function decrease() { // 計數(shù)減1 count--; // 保存并更新顯示 saveCount(); updateDisplay(); // 添加動畫效果 addAnimation('decrease'); } // 增加計數(shù) function increase() { // 計數(shù)加1 count++; // 保存并更新顯示 saveCount(); updateDisplay(); // 添加動畫效果 addAnimation('increase'); } // 重置計數(shù) function reset() { // 重置為0 count = 0; // 保存并更新顯示 saveCount(); updateDisplay(); // 添加動畫效果 addAnimation('reset'); } // 添加動畫效果 function addAnimation(type) { // 移除之前的動畫類 countSpan.classList.remove('animate-increase', 'animate-decrease', 'animate-reset'); // 添加新的動畫類 countSpan.classList.add(`animate-${type}`); // 動畫結(jié)束后移除類 setTimeout(() => { countSpan.classList.remove(`animate-${type}`); }, 500); } // 添加事件監(jiān)聽器 decreaseBtn.addEventListener('click', decrease); increaseBtn.addEventListener('click', increase); resetBtn.addEventListener('click', reset); // 添加鍵盤事件支持 document.addEventListener('keydown', function(e) { // 根據(jù)按鍵執(zhí)行相應(yīng)操作 switch(e.key) { case 'ArrowDown': case '-': decrease(); break; case 'ArrowUp': case '+': increase(); break; case 'r': case 'R': reset(); break; } }); // 添加動畫樣式 const style = document.createElement('style'); style.textContent = ` @keyframes increase { 0% { transform: scale(1); } 50% { transform: scale(1.2); } 100% { transform: scale(1); } } @keyframes decrease { 0% { transform: scale(1); } 50% { transform: scale(0.8); } 100% { transform: scale(1); } } @keyframes reset { 0% { transform: rotate(0); } 100% { transform: rotate(360deg); } } .animate-increase { animation: increase 0.5s ease; } .animate-decrease { animation: decrease 0.5s ease; } .animate-reset { animation: reset 0.5s ease; } `; document.head.appendChild(style); // 頁面加載時加載保存的計數(shù) loadCount(); });
7. todo.js
// todo.js - 待辦事項列表功能實現(xiàn) // 等待DOM完全加載后執(zhí)行 document.addEventListener('DOMContentLoaded', function() { // 獲取DOM元素 const todoInput = document.getElementById('todo-input'); // 輸入框 const addButton = document.getElementById('add-todo'); // 添加按鈕 const todoList = document.getElementById('todo-list'); // 待辦事項列表 // 存儲待辦事項的數(shù)組 let todos = []; // 從localStorage加載保存的待辦事項 function loadTodos() { // 嘗試從localStorage獲取數(shù)據(jù) const savedTodos = localStorage.getItem('todos'); if (savedTodos) { // 如果有數(shù)據(jù),解析JSON字符串并更新todos數(shù)組 todos = JSON.parse(savedTodos); // 渲染待辦事項列表 renderTodos(); } } // 保存待辦事項到localStorage function saveTodos() { // 將todos數(shù)組轉(zhuǎn)換為JSON字符串并保存 localStorage.setItem('todos', JSON.stringify(todos)); } // 渲染待辦事項列表 function renderTodos() { // 清空列表 todoList.innerHTML = ''; // 遍歷todos數(shù)組,創(chuàng)建并添加列表項 todos.forEach((todo, index) => { // 創(chuàng)建列表項 const li = document.createElement('li'); li.className = 'todo-item'; // 創(chuàng)建復選框 const checkbox = document.createElement('input'); checkbox.type = 'checkbox'; checkbox.checked = todo.completed; // 添加復選框改變事件 checkbox.addEventListener('change', () => toggleTodo(index)); // 創(chuàng)建文本span const span = document.createElement('span'); span.textContent = todo.text; // 如果待辦事項已完成,添加completed類 if (todo.completed) { span.classList.add('completed'); } // 創(chuàng)建刪除按鈕 const deleteButton = document.createElement('button'); deleteButton.textContent = '刪除'; deleteButton.style.marginLeft = 'auto'; // 添加刪除按鈕點擊事件 deleteButton.addEventListener('click', () => deleteTodo(index)); // 將元素添加到列表項 li.appendChild(checkbox); li.appendChild(span); li.appendChild(deleteButton); // 將列表項添加到列表 todoList.appendChild(li); }); } // 添加新的待辦事項 function addTodo() { // 獲取輸入的文本并去除首尾空格 const text = todoInput.value.trim(); // 如果文本不為空 if (text) { // 創(chuàng)建新的待辦事項對象 const todo = { text: text, completed: false }; // 添加到數(shù)組 todos.push(todo); // 清空輸入框 todoInput.value = ''; // 保存并重新渲染 saveTodos(); renderTodos(); } } // 刪除待辦事項 function deleteTodo(index) { // 從數(shù)組中刪除指定索引的項 todos.splice(index, 1); // 保存并重新渲染 saveTodos(); renderTodos(); } // 切換待辦事項的完成狀態(tài) function toggleTodo(index) { // 切換指定索引項的completed狀態(tài) todos[index].completed = !todos[index].completed; // 保存并重新渲染 saveTodos(); renderTodos(); } // 添加事件監(jiān)聽器 // 點擊添加按鈕時添加待辦事項 addButton.addEventListener('click', addTodo); // 在輸入框中按回車鍵時添加待辦事項 todoInput.addEventListener('keypress', function(e) { // 如果按下的是回車鍵(keyCode 13) if (e.keyCode === 13) { addTodo(); } }); // 頁面加載時加載保存的待辦事項 loadTodos(); });
8. form.js
// form.js - 表單驗證功能實現(xiàn) // 等待DOM完全加載后執(zhí)行 document.addEventListener('DOMContentLoaded', function() { // 獲取DOM元素 const form = document.getElementById('validation-form'); // 表單 const username = document.getElementById('username'); // 用戶名輸入框 const email = document.getElementById('email'); // 郵箱輸入框 const password = document.getElementById('password'); // 密碼輸入框 const usernameError = document.getElementById('username-error'); // 用戶名錯誤提示 const emailError = document.getElementById('email-error'); // 郵箱錯誤提示 const passwordError = document.getElementById('password-error'); // 密碼錯誤提示 // 驗證規(guī)則對象 const validationRules = { // 用戶名驗證規(guī)則 username: { test: (value) => { return value.length >= 3 && value.length <= 10; }, message: '用戶名長度必須在3-10個字符之間' }, // 郵箱驗證規(guī)則 email: { test: (value) => { // 使用正則表達式驗證郵箱格式 const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return emailRegex.test(value); }, message: '請輸入有效的郵箱地址' }, // 密碼驗證規(guī)則 password: { test: (value) => { // 密碼至少6個字符,包含至少一個數(shù)字和一個字母 const passwordRegex = /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{6,}$/; return passwordRegex.test(value); }, message: '密碼至少6個字符,必須包含數(shù)字和字母' } }; // 驗證單個字段 function validateField(field, errorElement) { // 獲取字段值并去除首尾空格 const value = field.value.trim(); // 獲取字段名 const fieldName = field.id; // 獲取對應(yīng)的驗證規(guī)則 const rule = validationRules[fieldName]; // 如果輸入為空 if (!value) { showError(errorElement, '此字段不能為空'); return false; } // 使用驗證規(guī)則測試值 if (!rule.test(value)) { showError(errorElement, rule.message); return false; } // 驗證通過,清除錯誤提示 clearError(errorElement); return true; } // 顯示錯誤信息 function showError(element, message) { element.textContent = message; element.style.display = 'block'; // 添加抖動動畫 element.classList.add('error-shake'); setTimeout(() => { element.classList.remove('error-shake'); }, 500); } // 清除錯誤信息 function clearError(element) { element.textContent = ''; element.style.display = 'none'; } // 添加實時驗證 username.addEventListener('input', () => validateField(username, usernameError)); email.addEventListener('input', () => validateField(email, emailError)); password.addEventListener('input', () => validateField(password, passwordError)); // 添加表單提交事件處理 form.addEventListener('submit', function(e) { // 阻止表單默認提交行為 e.preventDefault(); // 驗證所有字段 const isUsernameValid = validateField(username, usernameError); const isEmailValid = validateField(email, emailError); const isPasswordValid = validateField(password, passwordError); // 如果所有字段都驗證通過 if (isUsernameValid && isEmailValid && isPasswordValid) { // 創(chuàng)建成功提示 showSuccessMessage(); // 重置表單 form.reset(); // 清除所有錯誤提示 clearError(usernameError); clearError(emailError); clearError(passwordError); } }); // 顯示成功消息 function showSuccessMessage() { // 創(chuàng)建成功消息元素 const successMessage = document.createElement('div'); successMessage.textContent = '表單提交成功!'; successMessage.style.cssText = ` position: fixed; top: 20px; right: 20px; background-color: #4caf50; color: white; padding: 15px 25px; border-radius: 4px; animation: slideIn 0.5s ease; `; // 添加到頁面 document.body.appendChild(successMessage); // 3秒后移除消息 setTimeout(() => { successMessage.style.animation = 'slideOut 0.5s ease'; setTimeout(() => { document.body.removeChild(successMessage); }, 500); }, 3000); } // 添加動畫樣式 const style = document.createElement('style'); style.textContent = ` @keyframes slideIn { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } } @keyframes slideOut { from { transform: translateX(0); opacity: 1; } to { transform: translateX(100%); opacity: 0; } } @keyframes shake { 0%, 100% { transform: translateX(0); } 25% { transform: translateX(-10px); } 75% { transform: translateX(10px); } } .error-shake { animation: shake 0.5s ease; color: #f44336; } #username-error, #email-error, #password-error { font-size: 0.8em; margin-top: -8px; margin-bottom: 10px; display: none; } `; document.head.appendChild(style); });
綜合練習
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>在線筆記本 - JavaScript綜合練習</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: Arial, sans-serif; line-height: 1.6; padding: 20px; background-color: #f0f2f5; } .container { max-width: 1200px; margin: 0 auto; } .header { background-color: #fff; padding: 20px; border-radius: 8px; margin-bottom: 20px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); display: flex; justify-content: space-between; align-items: center; } .notes-container { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 20px; margin-top: 20px; } .note { background-color: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); transition: transform 0.3s ease; position: relative; } .note:hover { transform: translateY(-5px); } .note-title { font-size: 1.2em; margin-bottom: 10px; color: #1890ff; } .note-content { margin-bottom: 15px; color: #333; } .note-footer { display: flex; justify-content: space-between; align-items: center; color: #999; font-size: 0.9em; } .note-actions { display: flex; gap: 10px; } button { padding: 8px 16px; background-color: #1890ff; color: white; border: none; border-radius: 4px; cursor: pointer; transition: background-color 0.3s; } button:hover { background-color: #40a9ff; } button.delete { background-color: #ff4d4f; } button.delete:hover { background-color: #ff7875; } .modal { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.5); justify-content: center; align-items: center; z-index: 1000; } .modal-content { background-color: #fff; padding: 20px; border-radius: 8px; width: 90%; max-width: 500px; position: relative; animation: slideIn 0.3s ease; } @keyframes slideIn { from { transform: translateY(-100px); opacity: 0; } to { transform: translateY(0); opacity: 1; } } .modal-close { position: absolute; top: 10px; right: 10px; font-size: 24px; cursor: pointer; color: #999; } input[type="text"], textarea { width: 100%; padding: 8px; margin: 10px 0; border: 1px solid #d9d9d9; border-radius: 4px; } textarea { height: 150px; resize: vertical; } .search-box { display: flex; gap: 10px; margin-bottom: 20px; } .search-box input { flex: 1; } .loading { display: none; width: 20px; height: 20px; border: 3px solid #f3f3f3; border-top: 3px solid #1890ff; border-radius: 50%; animation: spin 1s linear infinite; margin: 20px auto; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } .toast { position: fixed; bottom: 20px; right: 20px; padding: 10px 20px; background-color: #52c41a; color: white; border-radius: 4px; display: none; animation: fadeIn 0.3s ease; } @keyframes fadeIn { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } .error { background-color: #ff4d4f; } .tags { display: flex; flex-wrap: wrap; gap: 5px; margin: 10px 0; } .tag { padding: 2px 8px; background-color: #e6f7ff; border-radius: 12px; font-size: 0.9em; color: #1890ff; cursor: pointer; transition: background-color 0.3s; } .tag:hover { background-color: #bae7ff; } </style> </head> <body> <div class="container"> <nav> <button onclick="location.href='index.html'">返回首頁</button> </nav> <div class="header"> <h1>在線筆記本</h1> <button id="add-note-btn">添加筆記</button> </div> <div class="search-box"> <input type="text" id="search-input" placeholder="搜索筆記..."> <button id="search-btn">搜索</button> </div> <div class="tags" id="tags-container"></div> <div class="loading" id="loading"></div> <div class="notes-container" id="notes-container"></div> </div> <!-- 添加/編輯筆記的模態(tài)框 --> <div class="modal" id="note-modal"> <div class="modal-content"> <span class="modal-close">×</span> <h2 id="modal-title">添加筆記</h2> <input type="text" id="note-title-input" placeholder="筆記標題"> <textarea id="note-content-input" placeholder="筆記內(nèi)容"></textarea> <input type="text" id="note-tags-input" placeholder="標簽(用逗號分隔)"> <button id="save-note-btn">保存</button> </div> </div> <div class="toast" id="toast"></div> <script> // 狀態(tài)管理 const state = { notes: [], tags: new Set(), currentNoteId: null, filterTag: null }; // DOM元素 const elements = { notesContainer: document.getElementById('notes-container'), modal: document.getElementById('note-modal'), modalClose: document.querySelector('.modal-close'), modalTitle: document.getElementById('modal-title'), addNoteBtn: document.getElementById('add-note-btn'), saveNoteBtn: document.getElementById('save-note-btn'), titleInput: document.getElementById('note-title-input'), contentInput: document.getElementById('note-content-input'), tagsInput: document.getElementById('note-tags-input'), searchInput: document.getElementById('search-input'), searchBtn: document.getElementById('search-btn'), loading: document.getElementById('loading'), toast: document.getElementById('toast'), tagsContainer: document.getElementById('tags-container') }; // 工具函數(shù) const utils = { // 生成唯一ID generateId: () => Date.now().toString(36) + Math.random().toString(36).substr(2), // 格式化日期 formatDate: (date) => new Date(date).toLocaleString(), // 顯示加載動畫 showLoading: () => elements.loading.style.display = 'block', // 隱藏加載動畫 hideLoading: () => elements.loading.style.display = 'none', // 顯示提示消息 showToast: (message, isError = false) => { elements.toast.textContent = message; elements.toast.style.display = 'block'; elements.toast.className = `toast ${isError ? 'error' : ''}`; setTimeout(() => elements.toast.style.display = 'none', 3000); }, // 防抖函數(shù) debounce: (func, wait) => { let timeout; return function executedFunction(...args) { const later = () => { clearTimeout(timeout); func(...args); }; clearTimeout(timeout); timeout = setTimeout(later, wait); }; } }; // 筆記相關(guān)操作 const noteOperations = { // 添加筆記 addNote: (note) => { state.notes.unshift(note); note.tags.forEach(tag => state.tags.add(tag)); localStorage.setItem('notes', JSON.stringify(state.notes)); renderNotes(); renderTags(); }, // 編輯筆記 editNote: (id, updates) => { const index = state.notes.findIndex(note => note.id === id); if (index !== -1) { state.notes[index] = { ...state.notes[index], ...updates }; localStorage.setItem('notes', JSON.stringify(state.notes)); renderNotes(); renderTags(); } }, // 刪除筆記 deleteNote: (id) => { state.notes = state.notes.filter(note => note.id !== id); localStorage.setItem('notes', JSON.stringify(state.notes)); renderNotes(); renderTags(); }, // 搜索筆記 searchNotes: (query) => { const searchTerm = query.toLowerCase(); return state.notes.filter(note => { const matchesSearch = note.title.toLowerCase().includes(searchTerm) || note.content.toLowerCase().includes(searchTerm); const matchesTag = !state.filterTag || note.tags.includes(state.filterTag); return matchesSearch && matchesTag; }); } }; // 渲染函數(shù) function renderNotes(notes = state.notes) { elements.notesContainer.innerHTML = ''; notes.forEach(note => { const noteElement = document.createElement('div'); noteElement.className = 'note'; noteElement.innerHTML = ` <h3 class="note-title">${note.title}</h3> <div class="note-content">${note.content}</div> <div class="tags"> ${note.tags.map(tag => `<span class="tag">${tag}</span>`).join('')} </div> <div class="note-footer"> <span>${utils.formatDate(note.date)}</span> <div class="note-actions"> <button onclick="openEditNoteModal('${note.id}')">編輯</button> <button class="delete" onclick="deleteNoteWithConfirm('${note.id}')">刪除</button> </div> </div> `; elements.notesContainer.appendChild(noteElement); // 添加動畫效果 setTimeout(() => noteElement.style.opacity = '1', 10); }); } function renderTags() { elements.tagsContainer.innerHTML = ''; Array.from(state.tags).forEach(tag => { const tagElement = document.createElement('span'); tagElement.className = `tag ${state.filterTag === tag ? 'active' : ''}`; tagElement.textContent = tag; tagElement.onclick = () => filterByTag(tag); elements.tagsContainer.appendChild(tagElement); }); } // 模態(tài)框操作 function openAddNoteModal() { state.currentNoteId = null; elements.modalTitle.textContent = '添加筆記'; elements.titleInput.value = ''; elements.contentInput.value = ''; elements.tagsInput.value = ''; elements.modal.style.display = 'flex'; } function openEditNoteModal(id) { const note = state.notes.find(note => note.id === id); if (note) { state.currentNoteId = id; elements.modalTitle.textContent = '編輯筆記'; elements.titleInput.value = note.title; elements.contentInput.value = note.content; elements.tagsInput.value = note.tags.join(', '); elements.modal.style.display = 'flex'; } } function closeModal() { elements.modal.style.display = 'none'; } // 事件處理函數(shù) function saveNote() { const title = elements.titleInput.value.trim(); const content = elements.contentInput.value.trim(); const tags = elements.tagsInput.value .split(',').map(tag => tag.trim()) .filter(tag => tag.length > 0); if (!title || !content) { utils.showToast('標題和內(nèi)容不能為空', true); return; } const note = { title, content, tags, date: new Date().toISOString() }; if (state.currentNoteId) { noteOperations.editNote(state.currentNoteId, note); utils.showToast('筆記已更新'); } else { note.id = utils.generateId(); noteOperations.addNote(note); utils.showToast('筆記已添加'); } closeModal(); } function deleteNoteWithConfirm(id) { if (confirm('確定要刪除這個筆記嗎?')) { noteOperations.deleteNote(id); utils.showToast('筆記已刪除'); } } function filterByTag(tag) { state.filterTag = state.filterTag === tag ? null : tag; renderNotes(noteOperations.searchNotes(elements.searchInput.value)); renderTags(); } // 搜索功能 const handleSearch = utils.debounce(() => { const searchResults = noteOperations.searchNotes(elements.searchInput.value); renderNotes(searchResults); }, 300); // 初始化 function init() { // 加載保存的筆記 const savedNotes = localStorage.getItem('notes'); if (savedNotes) { state.notes = JSON.parse(savedNotes); state.notes.forEach(note => { note.tags.forEach(tag => state.tags.add(tag)); }); } // 渲染筆記和標簽 renderNotes(); renderTags(); // 事件監(jiān)聽 elements.addNoteBtn.onclick = openAddNoteModal; elements.modalClose.onclick = closeModal; elements.saveNoteBtn.onclick = saveNote; elements.searchInput.oninput = handleSearch; elements.searchBtn.onclick = handleSearch; // 點擊模態(tài)框外部關(guān)閉 window.onclick = (event) => { if (event.target === elements.modal) { closeModal(); } }; // 鍵盤事件 document.addEventListener('keydown', (e) => { if (e.key === 'Escape' && elements.modal.style.display === 'flex') { closeModal(); } }); } // 啟動應(yīng)用 init(); </script> </body> </html>
總結(jié)
到此這篇關(guān)于JavaScript練習語法及建議總結(jié)大全的文章就介紹到這了,更多相關(guān)JS練習語法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
您可能感興趣的文章:
相關(guān)文章
鼠標選擇動態(tài)改變網(wǎng)頁背景顏色的JS代碼
這篇文章主要介紹了鼠標選擇動態(tài)改變網(wǎng)頁背景顏色的JS代碼,有需要的朋友可以參考一下2013-12-12layui監(jiān)聽下拉選框選中值變化的方法(包含監(jiān)聽普通下拉選框)
今天小編大家分享一篇layui監(jiān)聽下拉選框選中值變化的方法(包含監(jiān)聽普通下拉選框),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09JS實現(xiàn)給json數(shù)組動態(tài)賦值的方法示例
這篇文章主要介紹了JS實現(xiàn)給json數(shù)組動態(tài)賦值的方法,結(jié)合實例形式分析了javascript針對json數(shù)組的遍歷、賦值等常用操作技巧,需要的朋友可以參考下2017-07-07