|
4 | 4 | <head>
|
5 | 5 | <meta charset="UTF-8">
|
6 | 6 | <meta name="viewport" content="width=device-width, initial-scale=1.0">
|
7 |
| - |
8 | 7 | <title>{{ title }}</title>
|
9 |
| - <meta name="description" content="{{ description }}" /> |
10 |
| - <meta name="keywords" content="{{ keywords }}" /> |
11 |
| - <meta name="generator" content="typikon" /> |
12 |
| - <meta name="template" content="typikon-theme" /> |
| 8 | + <meta name="description" content="{{ description }}"> |
| 9 | + <meta name="keywords" content="{{ keywords }}"> |
| 10 | + <meta name="generator" content="typikon"> |
| 11 | + <meta name="template" content="typikon-theme"> |
13 | 12 |
|
14 | 13 | {% for css_path in custom_css %}
|
15 | 14 | <link rel="stylesheet" href="{{ css_path | safe }}">
|
|
20 | 19 | <link rel="stylesheet" href="/assets/dark-theme.css" id="dark-theme" disabled>
|
21 | 20 |
|
22 | 21 | <link rel="icon" href="{{ icon | safe }}" type="image/png">
|
23 |
| - |
24 | 22 | </head>
|
25 | 23 |
|
26 | 24 | <body>
|
|
41 | 39 | </path>
|
42 | 40 | </svg>
|
43 | 41 | </span>
|
44 |
| - <input type="text" class="form-control" id="serach-text" placeholder="Full text serach..." |
| 42 | + <input type="text" class="form-control" id="search-text" placeholder="Full text search..." |
45 | 43 | aria-describedby="basic-addon1">
|
46 | 44 | </div>
|
47 | 45 | <ul class="list-unstyled ps-0" id="chapterList">
|
|
90 | 88 | {% endfor %}
|
91 | 89 |
|
92 | 90 | <script>
|
93 |
| - document.addEventListener('DOMContentLoaded', initTheme); |
94 |
| - window.onload = () => { |
95 |
| - themeChange(); |
96 |
| - fullTextSearch(); |
97 |
| - }; |
| 91 | + document.addEventListener('DOMContentLoaded', function () { |
| 92 | + initTheme(); |
| 93 | + initializeSearch(); |
| 94 | + }); |
98 | 95 |
|
99 |
| - function initTheme(event) { |
| 96 | + function initTheme() { |
100 | 97 | const darkThemeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
101 | 98 | const lightThemeLink = document.getElementById('light-theme');
|
102 | 99 | const darkThemeLink = document.getElementById('dark-theme');
|
103 | 100 |
|
104 |
| - changeTheme = (mediaQuery) => { |
| 101 | + const changeTheme = (mediaQuery) => { |
105 | 102 | if (mediaQuery.matches) {
|
106 |
| - // Dark mode |
107 | 103 | lightThemeLink.setAttribute('disabled', true);
|
108 | 104 | darkThemeLink.removeAttribute('disabled');
|
109 | 105 | } else {
|
110 |
| - // Light mode |
111 | 106 | darkThemeLink.setAttribute('disabled', true);
|
112 | 107 | lightThemeLink.removeAttribute('disabled');
|
113 | 108 | }
|
114 | 109 | };
|
115 | 110 |
|
116 |
| - // Initial check |
117 | 111 | changeTheme(darkThemeMediaQuery);
|
118 |
| - |
119 |
| - // Listen for changes in OS theme |
120 | 112 | darkThemeMediaQuery.addListener(changeTheme);
|
121 | 113 |
|
122 |
| - // Initial highlight.js |
123 | 114 | document.querySelectorAll('pre code').forEach((block) => {
|
124 | 115 | hljs.highlightElement(block);
|
125 | 116 | });
|
|
131 | 122 | paragraph.classList.add('md-p');
|
132 | 123 | });
|
133 | 124 | }
|
134 |
| - }; |
135 |
| - |
136 |
| - function fullTextSearch() { |
137 |
| - // Full text search data |
138 |
| - const data = [ |
139 |
| - { id: '1', title: '示例文档一', content: '这是示例文档一的内容。' }, |
140 |
| - { id: '2', title: '示例文档二', content: '这是示例文档二的内容。' } |
141 |
| - ]; |
142 |
| - |
143 |
| - // Fuse.js options |
144 |
| - const options = { |
145 |
| - keys: ['title', 'content'], |
146 |
| - includeScore: true, |
147 |
| - tokenize: true, |
148 |
| - threshold: 0.3, |
149 |
| - tokenSeparator: /[,|,|。]/ |
150 |
| - }; |
151 |
| - |
152 |
| - const fuse = new Fuse(data, options); |
153 |
| - const chapterList = document.getElementById('chapterList'); |
154 |
| - |
155 |
| - function performSearch() { |
156 |
| - const query = document.getElementById('serach-text').value.trim(); |
157 |
| - const results = fuse.search(query); |
158 |
| - |
159 |
| - chapterList.style.display = query !== '' ? 'none' : 'block'; |
160 |
| - |
161 |
| - results.forEach(result => { |
162 |
| - console.log(`${result.item.title} - ${result.item.content}`); |
163 |
| - }); |
164 |
| - }; |
165 |
| - |
166 |
| - const searchInput = document.getElementById("serach-text"); |
167 |
| - searchInput.addEventListener("input", performSearch); |
168 |
| - }; |
169 |
| - |
170 |
| - function themeChange() { |
171 |
| - const darkThemeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)'); |
172 |
| - const lightThemeLink = document.getElementById('light-theme'); |
173 |
| - const darkThemeLink = document.getElementById('dark-theme'); |
174 |
| - changeTheme = (mediaQuery) => { |
175 |
| - if (mediaQuery.matches) { |
176 |
| - // Dark mode |
177 |
| - lightThemeLink.setAttribute('disabled', true); |
178 |
| - darkThemeLink.removeAttribute('disabled'); |
179 |
| - } else { |
180 |
| - // Light mode |
181 |
| - darkThemeLink.setAttribute('disabled', true); |
182 |
| - lightThemeLink.removeAttribute('disabled'); |
183 |
| - } |
184 |
| - }; |
185 |
| - // Initial check |
186 |
| - changeTheme(darkThemeMediaQuery); |
187 |
| - // Listen for changes in OS theme |
188 |
| - darkThemeMediaQuery.addListener(changeTheme); |
189 |
| - }; |
| 125 | + } |
| 126 | + |
| 127 | + function initializeSearch() { |
| 128 | + fetch('/data.json') |
| 129 | + .then(response => response.json()) |
| 130 | + .then(data => { |
| 131 | + const options = { |
| 132 | + keys: ['title', "content"], |
| 133 | + includeScore: true, |
| 134 | + tokenize: true, |
| 135 | + threshold: 0.3, |
| 136 | + tokenSeparator: /[,|,|。]/ |
| 137 | + }; |
| 138 | + |
| 139 | + const fuse = new Fuse(data, options); |
| 140 | + const chapterList = document.getElementById('chapterList'); |
| 141 | + // 复制一份复原使用 |
| 142 | + let innerHTML = chapterList.innerHTML; |
| 143 | + function performSearch() { |
| 144 | + const query = document.getElementById('search-text').value.trim(); |
| 145 | + const results = fuse.search(query); |
| 146 | + |
| 147 | + // 设置显示菜单和搜索结果,如果没有搜索结果就显示菜单,有则反之 |
| 148 | + chapterList.innerHTML = results.length <= 0 ? chapterList.innerHTML = innerHTML : ''; |
| 149 | + |
| 150 | + // 遍历搜索结果并生成对应的 HTML |
| 151 | + results.forEach(result => { |
| 152 | + const sub_chapter = result.item; // 假设每个搜索结果是 sub_chapter 对象 |
| 153 | + |
| 154 | + // 构建章节和子章节的列表项 HTML |
| 155 | + const listItem = ` |
| 156 | + <li class="mb-1"> |
| 157 | + <div class="collapse show" id="collapse1"> |
| 158 | + <ul class="btn-toggle-nav list-unstyled fw-normal pb-1 small"> |
| 159 | + <li> |
| 160 | + <a href="${sub_chapter.url}" |
| 161 | + class="link-body-emphasis d-inline-flex text-decoration-none rounded"> |
| 162 | + ${sub_chapter.title} |
| 163 | + </a> |
| 164 | + </li> |
| 165 | + </ul> |
| 166 | + </div> |
| 167 | + </li> |
| 168 | + `; |
| 169 | + |
| 170 | + // 将拼接好的章节列表项添加到章节列表容器 |
| 171 | + chapterList.innerHTML += listItem; |
| 172 | + }); |
| 173 | + } |
| 174 | + |
| 175 | + const searchInput = document.getElementById('search-text'); |
| 176 | + searchInput.addEventListener('input', performSearch); |
| 177 | + }) |
| 178 | + .catch(error => console.error('Error fetching data:', error)); |
| 179 | + } |
190 | 180 | </script>
|
191 | 181 | </body>
|
192 | 182 |
|
|
0 commit comments