2 * Created by Xiaotao.Nie on 09/04/2018.
4 * IF you have any question please email onlythen@yeah.net
7 // Global functions and listeners
8 window.onresize = () => {
9 // when window resize , we show remove some class that me be added
11 if(window.document.documentElement.clientWidth > 680){
12 let aboutContent = document.getElementById('nav-content')
13 aboutContent.classList.remove('hide-block')
14 aboutContent.classList.remove('show-block');
23 // Nav switch function on mobile
24 /*****************************************************************************/
25 const navToggle = document.getElementById('site-nav-toggle');
26 navToggle.addEventListener('click', () => {
27 let aboutContent = document.getElementById('nav-content')
28 if (!aboutContent.classList.contains('show-block')) {
29 aboutContent.classList.add('show-block');
30 aboutContent.classList.remove('hide-block')
32 aboutContent.classList.add('hide-block')
33 aboutContent.classList.remove('show-block');
39 /*****************************************************************************/
41 const searchButton = document.getElementById('search')
42 const searchField = document.getElementById('search-field')
43 const searchInput = document.getElementById('search-input')
44 const searchResultContainer = document.getElementById('search-result-container')
45 const escSearch = document.getElementById('esc-search')
46 const beginSearch = document.getElementById('begin-search')
48 searchField.addEventListener('mousewheel',(e) => {
55 var caseSensitive = false
57 searchButton.addEventListener('click', () => {
61 escSearch.addEventListener('click',() => {
65 beginSearch.addEventListener('click',() => {
66 let keyword = searchInput.value;
68 searchFromKeyWord(keyword)
72 function toggleSeachField(){
73 if (!searchField.classList.contains('show-flex-fade')) {
80 function showSearchField() {
82 searchField.classList.add('show-flex-fade');
83 searchField.classList.remove('hide-flex-fade');
86 function hideSearchField(){
87 window.onkeydown = null;
88 searchField.classList.add('hide-flex-fade');
89 searchField.classList.remove('show-flex-fade');
92 function searchFromKeyWord(keyword = ""){
95 let sildeWindowSize = 100;
97 let handleKeyword = keyword
100 handleKeyword = keyword.toLowerCase()
102 if(!searchJson) return -1;
104 searchJson.forEach((item) => {
106 if(!item.title || !item.content) return 0; // break
108 let title = item.title
109 let content = item.content.trim().replace(/<[^>]+>/g,"").replace(/[`#\n]/g,"");
111 let lowerTitle = title,lowerContent = content;
114 lowerTitle = title.toLowerCase();
115 lowerContent = content.toLowerCase();
119 if(lowerTitle.indexOf(handleKeyword) !== -1 || lowerContent.indexOf(handleKeyword) !== -1){
121 resultItem.title = title.replace(keyword, "<span class='red'>" + keyword + '</span>');
122 resultItem.url = item.url;
124 resultItem.content = [];
128 while(lowerContent.indexOf(handleKeyword) !== -1){
129 let begin = lowerContent.indexOf(handleKeyword) - sildeWindowSize / 2 < 0 ? 0 : lowerContent.indexOf(handleKeyword) - sildeWindowSize / 2
130 let end = begin + sildeWindowSize;
131 let reg = caseSensitive ? new RegExp('('+keyword+')','g') : new RegExp('('+keyword+')','ig')
132 resultItem.content.push("..." + content.slice(lastend + begin, lastend + end).replace(reg, "<span class='red'>$1</span>") + "...")
133 lowerContent = lowerContent.slice(end, lowerContent.length)
136 // resultItem.title = title.replace(keyword, "<span class='red'>" + keyword + '</span>');
137 result.push(resultItem)
143 searchResultContainer.innerHTML = `
144 <div class="no-search-result">No Result</div>
149 let searchFragment = document.createElement('ul')
151 for(let item of result){
152 let searchItem = document.createElement('li');
153 let searchTitle = document.createElement('a');
154 searchTitle.href = item.url
155 searchTitle.innerHTML = item.title;
156 searchItem.appendChild(searchTitle)
157 if(item.content.length) {
158 let searchContentLiContainer = document.createElement('ul')
159 for (let citem of item.content) {
160 let searchContentFragment = document.createElement('li')
161 searchContentFragment.innerHTML = citem;
162 searchContentLiContainer.appendChild(searchContentFragment)
164 searchItem.appendChild(searchContentLiContainer)
166 searchFragment.appendChild(searchItem)
168 while(searchResultContainer.firstChild){
169 searchResultContainer.removeChild(searchResultContainer.firstChild)
171 searchResultContainer.appendChild(searchFragment)
178 window.onkeydown = (e) => {
179 if (e.which === 27) {
180 /** 这里编写当ESC按下时的处理逻辑! */
182 } else if(e.which === 13){
184 let keyword = searchInput.value;
186 searchFromKeyWord(keyword)
194 let search_path = window.hexo_search_path;
195 if (search_path.length === 0) {
196 search_path = "search.json";
197 } else if (/json$/i.test(search_path)) {
200 let path = window.hexo_root+ search_path;
203 dataType: isXml ? "xml" : "json",
205 success: function (res) {
206 searchJson = isXml ? $("entry", res).map(function() {
208 title: $("title", this).text(),
209 content: $("content",this).text(),
210 url: $("url" , this).text()
219 // directory function in post pages
220 /*****************************************************************************/
221 function getDistanceOfLeft(obj) {
225 left += obj.offsetLeft;
226 top += obj.offsetTop;
227 obj = obj.offsetParent;
235 var toc = document.getElementById('toc')
237 var tocToTop = getDistanceOfLeft(toc).top;
239 function reHeightToc(){
240 if(toc) { // resize toc height
241 toc.style.height = ( document.documentElement.clientHeight - 10 ) + 'px';
242 toc.style.overflowY = 'scroll';
251 var nameSet = new Set();
253 if(!toc || !toc.children || !toc.children[0]){
257 if (toc.children[0].nodeName === "OL") {
258 let ol = Array.from(toc.children[0].children)
260 function getArrayFromOl(ol) {
263 // let escape = function (item) {
264 // return item.replace(/<[^>]+>/g, "").replace(/^\s\s*/, '').replace(/\s\s*$/, '').replace(/[\. _]/g, '-')
267 ol.forEach((item) => {
268 if (item.children.length === 1) {
270 let value = item.children[0].getAttribute('href').replace(/^#/,"")
278 let concatArray = getArrayFromOl(Array.from(item.children[1].children))
279 nameSet.add(item.children[0].getAttribute('href').replace(/^#/,""))
281 value: [item.children[0].getAttribute('href').replace(/^#/,"")].concat(concatArray.reduce((p, n) => {
282 p = p.concat(n.value)
287 result = result.concat(concatArray)
293 result = getArrayFromOl(ol)
296 var nameArray = Array.from(nameSet)
298 function reLayout() {
299 let scrollToTop = document.documentElement.scrollTop || window.pageYOffset // Safari is special
301 // Fix bug that when resize window the toc layout may be wrong
302 toc = document.getElementById('toc')
303 toc.classList.remove('toc-fixed')
304 tocToTop = getDistanceOfLeft(toc).top;
306 if (tocToTop <= scrollToTop + 10) {
307 if (!toc.classList.contains('toc-fixed'))
308 toc.classList.add('toc-fixed')
310 if (toc.classList.contains('toc-fixed'))
311 toc.classList.remove('toc-fixed')
315 let minTopsValue = ""
317 for (let item of nameArray) {
318 let dom = document.getElementById(item) || document.getElementById(item.replace(/\s/g, ''))
320 let toTop = getDistanceOfLeft(dom).top - scrollToTop;
322 if (Math.abs(toTop) < minTop) {
323 minTop = Math.abs(toTop)
327 // console.log(minTopsValue, minTop)
331 for (let item of result) {
332 if (item.value.indexOf(minTopsValue) !== -1) {
333 item.dom.classList.add("active")
335 item.dom.classList.remove("active")
343 window.addEventListener('scroll', (e) => {