forked from t11003/w5-git-pr-practice
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
113 lines (97 loc) · 3.69 KB
/
Copy pathindex.html
File metadata and controls
113 lines (97 loc) · 3.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
<!DOCTYPE html>
<html lang="zh-Hant">
<head>
<meta charset="UTF-8">
<title>W5 PR 練習 Chatbot</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<header>
<h1>🤖 PR 練習 Chatbot</h1>
<p class="subtitle">W5 Pull Request 練習</p>
<input id="search-input" type="text" placeholder="搜尋訊息..." oninput="searchMessages(this.value)">
</header>
<div id="chat-box">
<div class="message bot">
嗨!這週我們要學 Pull Request 🔀 試著修改我,然後開一個 PR 吧!
</div>
</div>
<div class="input-area">
<input id="user-input" type="text" placeholder="輸入訊息...">
<button onclick="sendMessage()">送出</button>
</div>
</div>
<script>
function sendMessage() {
const input = document.getElementById('user-input');
const chatBox = document.getElementById('chat-box');
const text = input.value.trim();
if (!text) return;
const userDiv = document.createElement('div');
userDiv.className = 'message user';
const timeUser = document.createElement('span');
timeUser.className = 'timestamp';
timeUser.textContent = new Date().toLocaleTimeString('zh-TW', {hour:'2-digit', minute:'2-digit'});
userDiv.textContent = text;
userDiv.appendChild(timeUser);
chatBox.appendChild(userDiv);
const botDiv = document.createElement('div');
botDiv.className = 'message bot';
const timeBot = document.createElement('span');
timeBot.className = 'timestamp';
timeBot.textContent = new Date().toLocaleTimeString('zh-TW', {hour:'2-digit', minute:'2-digit'});
botDiv.textContent = `你說了「${text}」!`;
botDiv.appendChild(timeBot);
chatBox.appendChild(botDiv);
input.value = '';
chatBox.scrollTop = chatBox.scrollHeight;
}
document.getElementById('user-input').addEventListener('keypress', function(e) {
if (e.key === 'Enter') sendMessage();
});
function searchMessages(keyword) {
const messages = document.querySelectorAll('#chat-box .message');
const trimmed = keyword.trim().toLowerCase();
// 先移除所有高亮,還原 text nodes
messages.forEach(msg => removeHighlight(msg));
messages.forEach(msg => {
// 取得純文字內容(排除 timestamp)
const textNodes = Array.from(msg.childNodes)
.filter(n => n.nodeType === Node.TEXT_NODE)
.map(n => n.textContent)
.join('');
const content = textNodes.toLowerCase();
if (!trimmed) {
msg.classList.remove('hidden');
} else if (content.includes(trimmed)) {
msg.classList.remove('hidden');
highlightText(msg, trimmed);
} else {
msg.classList.add('hidden');
}
});
}
function highlightText(element, keyword) {
Array.from(element.childNodes).forEach(node => {
if (node.nodeType === Node.TEXT_NODE) {
const text = node.textContent;
const escaped = keyword.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
const regex = new RegExp(`(${escaped})`, 'gi');
if (regex.test(text)) {
const wrapper = document.createElement('span');
wrapper.setAttribute('data-highlight-wrapper', 'true');
wrapper.innerHTML = text.replace(regex, '<mark class="search-highlight">$1</mark>');
node.replaceWith(wrapper);
}
}
});
}
function removeHighlight(element) {
element.querySelectorAll('[data-highlight-wrapper]').forEach(wrapper => {
wrapper.replaceWith(document.createTextNode(wrapper.textContent));
});
}
</script>
</body>
</html>