1;(async function (doc, win, layer, hotRankList, keyword) { 2 const buildSearchUrl = k => `/search/${encodeURIComponent(k)}/` 3 const isSearchPage = () => window.location.pathname.includes("search-page") 4 const HISTORY_KEY = "__GLOBAL_SEARCH_HISTORY__" 5 const escapeHTML = raw => 6 String(raw ?? "") 7 .replace(/&/g, "&") 8 .replace(/</g, "<") 9 .replace(/>/g, ">") 10 .replace(/"/g, """) 11 .replace(/'/g, "'") 12 13 const parseKeyword = (raw, domparser) => { 14 const keywordhtml = domparser.parseFromString(String(raw || "").trim(), "text/html") 15 return keywordhtml.body.textContent 16 } 17 18 const initSearchAdLazyLoad = () => { 19 const images = Array.from(doc.querySelectorAll(".horizontal-banner img[data-lazy-ad][data-src]")).filter( 20 img => img.dataset.src 21 ) 22 if (!images.length) return 23 24 const loadAd = img => { 25 const src = img.dataset.src 26 if (!src || img.dataset.loaded === "1") return 27 img.dataset.loaded = "1" 28 if (typeof win.loadImage === "function" && img.id) { 29 win.loadImage(src, img.id) 30 return 31 } 32 img.src = src 33 } 34 35 if (!("IntersectionObserver" in win)) { 36 images.forEach(loadAd) 37 return 38 } 39 40 const observer = new IntersectionObserver( 41 entries => { 42 entries.forEach(entry => { 43 if (!entry.isIntersecting) return 44 observer.unobserve(entry.target) 45 loadAd(entry.target) 46 }) 47 }, 48 { rootMargin: "200px 0px" } 49 ) 50 51 images.forEach(img => observer.observe(img)) 52 } 53 54 const addSearchHistory = keyword => { 55 if (!keyword) return 56 let history = [] 57 try { 58 history = JSON.parse(localStorage.getItem(HISTORY_KEY)) || [] 59 } catch (error) { 60 history = [] 61 } 62 history = [keyword, ...history.filter(item => item !== keyword)].slice(0, 8) 63 localStorage.setItem(HISTORY_KEY, JSON.stringify(history)) 64 if (win.$HistoryRecord && typeof win.$HistoryRecord.show === "function") { 65 win.$HistoryRecord.show(history) 66 } 67 } 68 69 const submitSearch = keyword => { 70 if (!keyword || keyword.length < 1) return 71 try { 72 addSearchHistory(keyword) 73 top.location.href = buildSearchUrl(keyword) 74 } catch (error) { 75 window.location.href = buildSearchUrl(keyword) 76 } 77 } 78 // å表(æç´¢ç»æ) 79 class SortList { 80 constructor(selector, url) { 81 const _this = this 82 this.$archive = () => $(selector) 83 this.keyword = keyword 84 this.url = url 85 this.sort = "" 86 this.page = 1 87 88 // åé 89 $(document).on("change", '.xqbj-search-sort input[name="searchsort"][type="radio"]', function () { 90 _this.sort = $(this).val() 91 _this.page = 1 92 _this.load() 93 }) 94 } 95 96 // å ¥å£æ¹æ³ 97 load() { 98 this.showLoading() 99 this.fetchData() 100 .done(html => { 101 this.renderList(html) 102 this.bindEvents() 103 }) 104 .fail(() => { 105 layer.msg("æ°æ®è¯·æ±å¤±è´¥") 106 }) 107 .always(() => { 108 this.goTop() 109 setTimeout(() => { 110 layer.closeAll("loading") 111 }, 500) 112 }) 113 } 114 115 // è¯·æ± 116 fetchData() { 117 const data = { 118 q: this.keyword, 119 sort: this.sort, 120 page: this.page 121 } 122 123 return $.ajax({ 124 url: this.url, 125 method: "GET", 126 data 127 }) 128 } 129 130 // 渲æ[å端å¤ç] 131 renderList(html) { 132 this.$archive().fadeOut("fast", () => { 133 // [å端å¤ç] 134 // this.$archive.replaceWith(this.listTemplate()).fadeIn(300); 135 this.$archive().replaceWith(html).fadeIn(300) 136 }) 137 } 138 139 // 模æ¿(å表 + å页)[å端å¤ç] 140 listTemplate = html => { 141 return ` 142 <div id="archive" role="main"> 143 <article itemscope itemtype="http://schema.org/BlogPosting" class=""> 144 <div class="display-none" itemscope itemprop="author" itemtype="http://schema.org/Person"> 145 <meta itemprop="name" content="çç"/> 146 <meta itemprop="url" content=""/> 147 </div> 148 <div class="display-none" itemscope itemprop="publisher" itemtype="http://schema.org/Organization"> 149 <meta itemprop="name" content="çç"/> 150 <div itemscope itemprop="logo" itemtype="http://schema.org/ImageObject"> 151 <meta itemprop="url" content="/usr/themes/Mirages/images/51cg.png?s=50&r=G&d="> 152 </div> 153 </div> 154 <meta itemprop="url mainEntityOfPage" content="https://51cg1.com/archives/207221/" /> 155 <meta itemprop="dateModified" content="2025-05-19T09:10:30+00:00"> 156 <a href="https://51cg1.com/archives/207221/" > 157 <div class="post-card" id="post-card-207221" > 158 <div class="blog-background"></div> 159 <script type="text/javascript"> 160 loadBannerDirect('https://pic.sqbcn.cn/upload_01/xiao/20250517/2025051717181423596.jpeg', '', document.querySelector('#post-card-207221'), '-1', document.querySelector('#post-card-207221').offsetWidth, document.querySelector('#post-card-207221').offsetHeight); 161 </script> 162 <div class="post-card-mask "> 163 <div class="post-card-container"> 164 <h2 class="post-card-title" itemprop="headline">æ¥æ¬AV女ä¼è·¯è¾¹æ©ç´ 人 å¶éä¸å½çç·ä¸é è½¦å æ¿ææä¹ çé äºåç©50䏿¥å æåå¥³ä¼ å½¢è±¡ç¬é´é«å¤§ï¼</h2> 165 <div class="post-card-info">
166 <span itemprop="author" itemscope itemtype="http://schema.org/Person">çç ⢠</span> <span itemprop="datePublished" content="2025-05-17T16:18:00+00:00">2025 å¹´ 05 æ 17 æ¥ â¢ </span> 167 <span>仿¥åç, çç娱ä¹</span> 168 </div> 169 </div> 170 </div> 171 </div> 172 </a> 173 </article> 174 <article itemscope itemtype="http://schema.org/BlogPosting" class=""> 175 <div class="display-none" itemscope itemprop="author" itemtype="http://schema.org/Person"> 176 <meta itemprop="name" content="ç表妹"/> 177 <meta itemprop="url" content=""/> 178 </div> 179 <div class="display-none" itemscope itemprop="publisher" itemtype="http://schema.org/Organization"> 180 <meta itemprop="name" content="ç表妹"/> 181 <div itemscope itemprop="logo" itemtype="http://schema.org/ImageObject"> 182 <meta itemprop="url" content="/usr/themes/Mirages/images/51cg.png?s=50&r=G&d="> 183 </div> 184 </div> 185 <meta itemprop="url mainEntityOfPage" content="https://51cg1.com/archives/206994/" /> 186 <meta itemprop="dateModified" content="2025-05-19T09:10:36+00:00"> 187 <a href="https://51cg1.com/archives/206994/" > 188 <div class="post-card" id="post-card-206994" > 189 <div class="blog-background"></div> 190 <script type="text/javascript"> 191 loadBannerDirect('https://pic.sqbcn.cn/upload_01/xiao/20250516/2025051621385232406.jpeg', '', document.querySelector('#post-card-206994'), '-1', document.querySelector('#post-card-206994').offsetWidth, document.querySelector('#post-card-206994').offsetHeight); 192 </script> 193 <div class="post-card-mask "> 194 <div class="post-card-container"> 195 <h2 class="post-card-title" itemprop="headline">å°æ¹¾æåç¦å©å§¬å¥³ç¥ 波衣 éå ·èªæ °å·æ°´ç§æåé è¿è·ç¦»å±ç¤ºç¾ä¹³å«©ç©´æ éé æ å¨åå¾é诱人ï¼</h2> 196 <div class="post-card-info"> 197 <span itemprop="author" itemscope itemtype="http://schema.org/Person">ç表妹 ⢠</span> <span itemprop="datePublished" content="2025-05-17T16:00:00+00:00">2025 å¹´ 05 æ 17 æ¥ â¢ </span> 198 <span>仿¥åç, ç½çº¢é»æ</span> 199 </div> 200 </div> 201 </div> 202 </div> 203 </a> 204 </article> 205 <article itemscope itemtype="http://schema.org/BlogPosting" class=""> 206 <div class="display-none" itemscope itemprop="author" itemtype="http://schema.org/Person"> 207 <meta itemprop="name" content="ç表妹"/> 208 <meta itemprop="url" content=""/> 209 </div> 210 <div class="display-none" itemscope itemprop="publisher" itemtype="http://schema.org/Organization"> 211 <meta itemprop="name" content="ç表妹"/> 212 <div itemscope itemprop="logo" itemtype="http://schema.org/ImageObject"> 213 <meta itemprop="url" content="/usr/themes/Mirages/images/51cg.png?s=50&r=G&d="> 214 </div> 215 </div> 216 <meta itemprop="url mainEntityOfPage" content="https://51cg1.com/archives/206989/" /> 217 <meta itemprop="dateModified" content="2025-05-19T09:10:44+00:00"> 218 <a href="https://51cg1.com/archives/206989/" > 219 <div class="post-card" id="post-card-206989" > 220 <div class="blog-background"></div> 221 <script type="text/javascript"> 222 loadBannerDirect('https://pic.sqbcn.cn/upload_01/xiao/20250516/2025051620282659908.jpeg', '', document.querySelector('#post-card-206989'), '-1', document.querySelector('#post-card-206989').offsetWidth, document.querySelector('#post-card-206989').offsetHeight); 223 </script> 224 <div class="post-card-mask "> 225 <div class="post-card-container"> 226 <h2 class="post-card-title" itemprop="headline">æååå·®å¥³ç¥ ç§æéå ·æç©´ç¹å ç²å«©èç©´æ·«æ°´æ³æ»¥ èæ¡è髿½®å·æ¶ ç»é¢æ©å°çï¼</h2> 227 <div class="post-card-info">
228 <span itemprop="author" itemscope itemtype="http://schema.org/Person">ç表妹 ⢠</span> <span itemprop="datePublished" content="2025-05-17T15:30:00+00:00">2025 å¹´ 05 æ 17 æ¥ â¢ </span> 229 <span>仿¥åç, éªç·éªå¥³</span> 230 </div> 231 </div> 232 </div> 233 </div> 234 </a> 235 </article> 236 <article itemscope itemtype="http://schema.org/BlogPosting" class=""> 237 <div class="display-none" itemscope itemprop="author" itemtype="http://schema.org/Person"> 238 <meta itemprop="name" content="çäºå¥"/> 239 <meta itemprop="url" content=""/> 240 </div> 241 <div class="display-none" itemscope itemprop="publisher" itemtype="http://schema.org/Organization"> 242 <meta itemprop="name" content="çäºå¥"/> 243 <div itemscope itemprop="logo" itemtype="http://schema.org/ImageObject"> 244 <meta itemprop="url" content="/usr/themes/Mirages/images/51cg.png?s=50&r=G&d="> 245 </div> 246 </div> 247 <meta itemprop="url mainEntityOfPage" content="https://51cg1.com/archives/207136/" /> 248 <meta itemprop="dateModified" content="2025-05-19T09:09:56+00:00"> 249 <a href="https://51cg1.com/archives/207136/" > 250 <div class="post-card" id="post-card-207136" > 251 <div class="blog-background"></div> 252 <script type="text/javascript"> 253 loadBannerDirect('https://pic.sqbcn.cn/upload_01/xiao/20250516/2025051621454710950.jpeg', '', document.querySelector('#post-card-207136'), '-1', document.querySelector('#post-card-207136').offsetWidth, document.querySelector('#post-card-207136').offsetHeight); 254 </script> 255 <div class="post-card-mask "> 256 <div class="post-card-container"> 257 <h2 class="post-card-title" itemprop="headline">æé³æ¨ç¹åå¹³å°åå·®æ¯ç é²è¸èªæ °è£¸èåé æå¥¶é²ç©´è¶ çº§æ·«éª æ§æèº«æä»¤äººè¡èå·å¼ ï¼</h2> 258 <div class="post-card-info"> 259 <span itemprop="author" itemscope itemtype="http://schema.org/Person">çäºå¥ ⢠</span> <span itemprop="datePublished" content="2025-05-17T15:21:00+00:00">2025 å¹´ 05 æ 17 æ¥ â¢ </span> 260 <span>仿¥åç, ç½çº¢é»æ</span> 261 </div> 262 </div> 263 </div> 264 </div> 265 </a> 266 </article> 267 268 <div class="page-nav page-nav-ajax"> 269 <div class="page-jump"> 270 <div id="pageForm" method="get"> 271 <span class="page-info"> 12/518 </span> 272 <input type="number" id="pageNum"> 273 <button id="submitBtn">跳转</button> 274 </div> 275 </div> 276 <ul class="page-navigator"> 277 <li class="prev"><a href="javascript:void(0);" data-page="11">ä¸ä¸é¡µ</a></li> 278 <li><span></span></li> 279 <li class="next"><a href="javascript:void(0);" data-page="13">ä¸ä¸é¡µ</a></li> 280 </ul> 281 </div> 282 </div> 283 ` 284 } 285 286 // äºä»¶ 287 bindEvents() { 288 const _this = this 289 $(doc) 290 .off("click.pageNav") 291 292 // ä¸ä¸é¡µ 293 .on("click.pageNav", ".page-nav-ajax .prev a", function (e) { 294 e.preventDefault() 295 _this.page = $(this)?.data("page") || 1 296 // console.log('prev clicked', $(this).data('page')); 297 _this.load() 298 }) 299 300 // ä¸ä¸é¡µ 301 .on("click.pageNav", ".page-nav-ajax .next a", function (e) { 302 e.preventDefault() 303 _this.page = $(this)?.data("page") || 1 304 _this.load() 305 }) 306 307 // 跳转æé® 308 .on("click.pageNav", ".page-nav-ajax #submitBtn", function (e) { 309 e.preventDefault() 310 const input = $(this).closest(".page-nav-ajax").find("input").val() 311 312 _this.page = 1 * input || 1 313 _this.load() 314 }) 315 } 316 317 // æ¾ç¤ºå è½½å¨ç» 318 showLoading() { 319 layer.load(0) 320 } 321 322 // æ¾ç¤ºå è½½å¨ç» 323 goTop() { 324 window.scrollTo({ 325 top: 0, 326 behavior: "smooth" 327 }) 328 } 329 } 330 331 // 导èª(头é¨å¯¼èª) 332 class NavSearch { 333 constructor(hoturl, url, throttleInterval, keyLength) { 334 const _this = this 335 this.hoturl = hoturl 336 this.url = url 337 this.throttleInterval = throttleInterval 338 this.keyLength = keyLength 339 this.domparser = new DOMParser() 340 341 // 模æ¿å®ä¹(åå²) 342 this.hotTemplate = (c = {}) => { 343 const source = Array.isArray(c) ? { hotArticles: c, hotTags: [] } : c || {} 344 const tagList = Array.isArray(source.hotTags) ? source.hotTags.slice(0, 10) : [] 345 const searchList = Array.isArray(source.hotSearches) 346 ? source.hotSearches 347 : Array.isArray(source.hotArticles) 348 ? source.hotArticles 349 : [] 350 const list = searchList.slice(0, 10) 351 const hasTags = tagList.length > 0 352 const hasData = list.length > 0 353 return ` 354 <div class="container-search-context"> 355 <div class="search-container"> 356 <div class="search-title">
357 <span>åå²è®°å½</span> 358 <div class="r-text on-history-clear"> 359 <i class="fa fa-trash-o icon"></i> 360 å é¤è®°å½ 361 </div> 362 </div> 363 <div class="container-search-tags"> 364 <div class="list history-record"> 365 <div class="no-data">ææ è®°å½</div> 366 </div> 367 </div> 368 369 <div class="search-title"> 370 <span>ç鍿 ç¾</span> 371 </div> 372 <div class="hot-tag-list"> 373 ${ 374 hasTags 375 ? tagList 376 .map(e => { 377 const name = escapeHTML(e.name || "") 378 const url = e.url || buildSearchUrl(e.name || "") 379 return `<a href="${url}" class="hot-tag-item">${name}</a>` 380 }) 381 .join("") 382 : `<div class="no-data">ææ æ°æ®</div>` 383 } 384 </div> 385 386 <div class="search-title search-border"> 387 <span>çé¨æç´¢</span> 388 </div> 389 <div class="container-search-hots"> 390 ${ 391 hasData 392 ? ` 393 <div class="rank-list"> 394 ${list 395 .map( 396 (e, index) => ` 397 <a href="${e.permalink}" class="rank-card"> 398 ${index <= 2 ? `<div class="xqbj-icon-rank-${index + 1} rank-card-icon"></div>` : `<div class="rank-card-icon rank-card-num">${index + 1}</div>`} 399 <div class="rank-card-title text-line-ellipsis-1">${escapeHTML(e.title)}</div> 400 <div class="rank-card-meta"> 401 <span class="view"><span class="view-num">${escapeHTML(e.hot_formatted)}</span><span class="view-suffix">ç度</span></span> 402 <span class="hot-badge">ç</span> 403 </div> 404 </a> 405 ` 406 ) 407 .join("")} 408 </div> 409 ` 410 : `<div class="no-data">ææ æ°æ®</div>` 411 } 412 </div> 413 </div> 414 </div> 415 ` 416 } 417 this.renderSuggestList = (keyword, listSearchContainer, data) => { 418 const safeKeyword = keyword.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") 419 const regex = new RegExp(safeKeyword, "g") 420 const list = { 421 list: data.map(e => ({ 422 title: e, 423 url: buildSearchUrl(e) 424 })) 425 } 426 427 list.list = list.list.map(item => ({ 428 ...item, 429 title: item.title.replace(regex, `<span class="keyword">${keyword}</span>`) 430 })) 431 432 const tpl = _this.seaTemplate(list) 433 $(listSearchContainer).html(tpl) 434 } 435 436 this.requestSuggest = (keyword, listSearchContainer, hotSearchContainer) => { 437 if (!keyword) { 438 $(listSearchContainer).removeClass("show").html("") 439 if (hotSearchContainer) { 440 $(hotSearchContainer).addClass("show") 441 } 442 return 443 } 444 445 _this 446 .fetchSearchData(keyword) 447 .done(d => { 448 _this.renderSuggestList(keyword, listSearchContainer, d) 449 }) 450 .fail(() => {}) 451 .always(() => { 452 $(listSearchContainer).addClass("show") 453 if (hotSearchContainer) { 454 $(hotSearchContainer).removeClass("show") 455 } 456 }) 457 } 458 459 this.seaTemplate = c => { 460 const list = Array.isArray(c?.list) ? c.list.slice(0, 20) : [] 461 if (list.length === 0) return "" 462 463 return ` 464 <div class="container-search-context"> 465 <div class="search-container"> 466 <div class="container-search-hots container-search-lists"> 467 <div class="rank-list"> 468 ${list 469 .map( 470 e => `
471 <a href="${e.url}" class="rank-card"> 472 <div class="xqbj-icon-search1"></div> 473 <div class="rank-card-title text-line-ellipsis-1">${e.title ?? ""}</div> 474 </a> 475 ` 476 ) 477 .join("")} 478 </div> 479 </div> 480 </div> 481 </div> 482 ` 483 } 484 485 // åå§(mobile) 486 $(doc).on("click", "form#search-form .search-form-input", function (e) { 487 top.location.href = "/search-page.html" 488 }) 489 490 $(doc).on("click", "form#search-form #search_btn", function (e) { 491 e.preventDefault() 492 top.location.href = "/search-page.html" 493 }) 494 495 // è¾å ¥(mobile) 496 $(doc).on( 497 "input", 498 "#input-mobile-control-key", 499 _this.debounce(function () { 500 const searchRoot = $(this).closest(".search-page-mobile-search, .nav-search-container") 501 const listSearchContainer = searchRoot.find(".container-list-search").get(0) 502 const hotSearchContainer = isSearchPage() 503 ? $(".search-page__panel .container-hot-search").get(0) 504 : searchRoot.find(".container-hot-search").get(0) 505 const keyword = parseKeyword($(this).val(), _this.domparser) 506 507 _this.requestSuggest(keyword, listSearchContainer, hotSearchContainer) 508 }, _this.throttleInterval) 509 ) 510 511 // æç´¢(mobile) 512 $(doc).on("click", ".input-mobile-search-btn", function () { 513 const keyword = parseKeyword( 514 $(this).closest(".search-page-mobile-header").find("#input-mobile-control-key").val(), 515 _this.domparser 516 ) 517 submitSearch(keyword) 518 }) 519 520 // xf0714 æç´¢-é®ç(mobile) start 521 $("#input-mobile-control-key").on("keydown", function (event) { 522 if (event.key === "Enter") { 523 event.preventDefault() 524 submitSearch(parseKeyword($(this).val(), _this.domparser)) 525 } 526 }) 527 // xf0714 æç´¢-é®ç(mobile) end 528 529 // æ¡é¢ç«¯å¯¼èªæç´¢ -> 跳转äºçº§é¡µé¢ 530 $(doc).on("click", "#navbar .nav-search-container", function (e) { 531 e.preventDefault() 532 e.stopPropagation() 533 if (isSearchPage()) { 534 $("#input-page-control-key").trigger("focus") 535 return 536 } 537 top.location.href = "/search-page.html" 538 }) 539 540 // æç´¢é¡µ PC è¾å ¥èæ³ 541 $(doc).on( 542 "input", 543 "#input-page-control-key", 544 _this.debounce(function () { 545 const keyword = parseKeyword($(this).val(), _this.domparser) 546 const listSearchContainer = $(".search-page__suggest .container-list-search").get(0) 547 const hotSearchContainer = $(".search-page__panel .container-hot-search").get(0) 548 _this.requestSuggest(keyword, listSearchContainer, hotSearchContainer) 549 }, _this.throttleInterval) 550 ) 551 552 $(doc).on("click", ".input-page-search-btn", function () { 553 submitSearch(parseKeyword($("#input-page-control-key").val(), _this.domparser)) 554 }) 555 556 $(doc).on("keydown", "#input-page-control-key", function (e) { 557 if (e.key === "Enter") { 558 e.preventDefault() 559 submitSearch(parseKeyword($(this).val(), _this.domparser)) 560 } 561 }) 562 563 // è¿å 564 $(doc).on("click", ".backbtn", function () { 565 const currentUrl = window.location.href 566 567 if (currentUrl.includes("search-page")) { 568 top.location.href = "/" 569 } else if ( 570 window.location.protocol === "file:" || 571 (!document.referrer && document.referrer.startsWith("file://")) 572 ) { 573 top.location.href = `/` 574 } else if (!document.referrer) { 575 top.location.href = `/` 576 } else { 577 const fallbackUrl = "/" 578 const firstUrl = sessionStorage.getItem("firstNonSearchUrl") 579 if (firstUrl) { 580 top.location.href = firstUrl 581 } else { 582 top.location.href = fallbackUrl 583 } 584 } 585 }) 586 587 // æç´¢å岿¶é(mobile and desktop) 588 $(doc).on( 589 "click", 590 ".container-search-tags a, .hot-tag-list a, .container-search-lists a, .xqbj-search-tags-list a, .xqbj-search-none a", 591 function (event) {
592 const keywordhtml = _this.domparser.parseFromString( 593 $(event.target) 594 ?.text() 595 ?.replace(/(^\s*)|(\s*$)/g, ""), 596 "text/html" 597 ) 598 const keyword = keywordhtml.body.textContent 599 try { 600 $HistoryRecord.add(keyword) 601 } catch (error) { 602 // console.log("åå²ä¿¡æ¯æ¶é失败", error); 603 } 604 } 605 ) 606 607 // 608 // this.init() 609 } 610 611 // åå§å 612 init() { 613 const _this = this 614 const renderHot = data => { 615 const tpl = _this.hotTemplate(data) 616 617 $(".search-page__panel .container-hot-search").html(tpl).addClass("show") 618 619 const navHotSearchContainer = $("#navbar .nav-search-container .container-hot-search").get(0) 620 if (navHotSearchContainer && !isSearchPage()) { 621 $(navHotSearchContainer).html(tpl).addClass("show") 622 } 623 624 win?.$HistoryRecord && win?.$HistoryRecord.init() 625 } 626 627 const loadHot = () => { 628 _this 629 .fetchHotData() 630 .done(res => { 631 const data = res?.data || {} 632 const hotTags = Array.isArray(data.hotTags) ? data.hotTags : [] 633 const hotArticles = Array.isArray(data.hotSearches) 634 ? data.hotSearches 635 : Array.isArray(data.hotArticles) 636 ? data.hotArticles 637 : [] 638 // æå»ºè æ£å¨å·¥ä½ä¸ææ stale æ¶ï¼ä¿ç SSR çæ¦ï¼ä¸ç¨ç©ºé级è¦çã 639 if (hotTags.length === 0 && hotArticles.length === 0) return 640 renderHot({ 641 hotTags, 642 hotSearches: hotArticles, 643 hotArticles: hotArticles.length > 0 ? hotArticles : hotRankList 644 }) 645 }) 646 .fail(() => { 647 if (!isSearchPage()) { 648 renderHot(hotRankList) 649 } 650 }) 651 } 652 653 // çæ¦åªå¨æç´¢é¡µæé读å䏿¬¡ãå ¨ç«æ¯é¡µè¯·æ±/æ¯ 30s è½®è¯¢ä¼æ¾å¤§ç¼åè¿ææç¾¤ã 654 if (isSearchPage()) { 655 loadHot() 656 $(".search-page__panel .container-hot-search").addClass("show") 657 } 658 659 win?.$HistoryRecord && win?.$HistoryRecord.init() 660 661 if (isSearchPage()) { 662 setTimeout(() => { 663 if (window.innerWidth < 768) { 664 $("#input-mobile-control-key").trigger("focus") 665 } else { 666 $("#input-page-control-key").trigger("focus") 667 } 668 }, 100) 669 } 670 } 671 // æç´¢è¯·æ± 672 fetchSearchData(keyword) { 673 const _this = this 674 if (keyword.length <= _this.keyLength) throw new Error("å ³é®è¯é¿åº¦å¿ 须大äº2") 675 676 const data = { 677 q: encodeURIComponent(keyword) 678 } 679 680 return $.ajax({ 681 url: `${this.url}`, 682 method: "GET", 683 data 684 }) 685 } 686 687 // çé¨è¯·æ± 688 fetchHotData() { 689 const _this = this 690 return $.ajax({ 691 url: _this.hoturl, 692 method: "GET" 693 }) 694 } 695 696 // èæµ 697 debounce(func, delay) { 698 let timer = null 699 return function (...args) { 700 if (timer) clearTimeout(timer) 701 timer = setTimeout(() => { 702 func.apply(this, args) 703 timer = null 704 }, delay) 705 } 706 } 707 } 708 709 // åå²(æç´¢åå²) 710 class HistoryRecord { 711 constructor() { 712 this.key = HISTORY_KEY // localStorage ç key 713 this.max = 8 // æå¤ä¿å 20 æ¡è®°å½ 714 this.listcontainer = "div.history-record" // å表容å¨å ç´ 715 this.init() // åå§å è½½è®°å½ 716 } 717 getHistory() { 718 try { 719 const history = JSON.parse(localStorage.getItem(this.key)) || [] 720 return Array.isArray(history) ? history : [] 721 } catch (error) { 722 return [] 723 } 724 } 725 726 // å è½½ 727 init() { 728 const _this = this 729 this.show(this.getHistory()) 730 731 // äºä»¶ 732 _this.event() 733 } 734 735 // äºä»¶ 736 event() { 737 const _this = this 738 $(doc).on("click", ".on-history-clear", function () { 739 _this.clear() 740 }) 741 742 $(doc).on("click", ".on-history-delete", function (e) { 743 e.preventDefault()
744 const keyword = $(this).closest("a").text() 745 _this.del(keyword) 746 }) 747 748 // ç¹å»æ¯ä¸ªåå²é¡¹ å é¤èªèº« å¹¶æ´æ°æ¬å°åå¨çæ°æ® 749 $(doc).on("click", ".history-record-item .history-close", function (e) { 750 e.preventDefault() 751 const $item = $(this).closest(".history-record-item") 752 const keyword = $item.find("a span").text() 753 _this.del(keyword) 754 }) 755 } 756 757 // æ¾ç¤º(æä½) 758 show(historys) { 759 const $container = $(this.listcontainer) 760 $container && 761 $container.each((index, c) => { 762 let tpl = '<div class="no-data">ææ è®°å½</div>' 763 if (historys?.length > 0) { 764 tpl = historys 765 .map( 766 item => `<div class='history-record-item'> 767 <a href="${buildSearchUrl(item)}"><span class="text-line-ellipsis-1">${item}</span></a> 768 <img src='/usr/themes/Mirages/images/history-close.png' class='history-close' alt='close'/> 769 </div>` 770 ) 771 .join("") 772 } 773 c.innerHTML = tpl 774 }) 775 } 776 777 // æ·»å 778 add(keyword) { 779 if (!keyword) return 780 781 let history = this.getHistory() 782 783 // å»é + æ·»å å°å¼å¤´ + éå¶æ°é 784 history = [keyword, ...history.filter(item => item !== keyword)].slice(0, this.max) 785 786 localStorage.setItem(this.key, JSON.stringify(history)) 787 this.show(history) 788 } 789 790 // å é¤ 791 del(keyword) { 792 if (!keyword) return 793 794 let history = this.getHistory() 795 796 // å é¤ 797 history = history.filter(k => k !== keyword) 798 799 localStorage.setItem(this.key, JSON.stringify(history)) 800 this.show(history) 801 } 802 803 // æ¸ ç©º 804 clear() { 805 localStorage.removeItem(this.key) 806 this.show([]) 807 } 808 } 809 810 // åå§å 811 document.addEventListener( 812 "DOMContentLoaded", 813 function () { 814 const landingKey = "firstNonSearchUrl" 815 816 if (!isSearchPage()) { 817 sessionStorage.setItem(landingKey, window.location.href) 818 } 819 820 doc.addEventListener( 821 "click", 822 function (event) { 823 const button = event.target.closest(".input-page-search-btn, .input-mobile-search-btn") 824 if (!button) return 825 event.preventDefault() 826 event.stopImmediatePropagation() 827 const inputId = button.classList.contains("input-mobile-search-btn") 828 ? "input-mobile-control-key" 829 : "input-page-control-key" 830 const input = doc.getElementById(inputId) 831 submitSearch(parseKeyword(input ? input.value : "", new DOMParser())) 832 }, 833 true 834 ) 835 836 doc.addEventListener( 837 "keydown", 838 function (event) { 839 if (event.key !== "Enter") return 840 if ( 841 event.target && 842 (event.target.id === "input-page-control-key" || event.target.id === "input-mobile-control-key") 843 ) { 844 event.preventDefault() 845 event.stopImmediatePropagation() 846 submitSearch(parseKeyword(event.target.value, new DOMParser())) 847 } 848 }, 849 true 850 ) 851 852 win["$NavSearch"] = new NavSearch(
853 "/search-page-data.php", 854 "/action/suggest", 855 500, 856 0 // æç´¢æ¥å£ 857 ) 858 win["$SortList"] = new SortList("div#archive", "/action/search_by") 859 win["$HistoryRecord"] = new HistoryRecord() 860 win["$NavSearch"].init() 861 initSearchAdLazyLoad() 862 }, 863 false 864 ) 865})(document, window, window.layer || { load: function () {} }, window.hotRankList || [], window.keyword || "")
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.