1<!doctype html> 2<!--[if lt IE 7]><html class="no-js lt-ie9 lt-ie8 lt-ie7" lang="en"> <![endif]--> 3<!--[if IE 7]><html class="no-js lt-ie9 lt-ie8" lang="en"> <![endif]--> 4<!--[if IE 8]><html class="no-js lt-ie9" lang="en"> <![endif]--> 5<!--[if IE 9 ]><html class="ie9 no-js"> <![endif]--> 6<!--[if (gt IE 9)|!(IE)]><!--> <html class="no-js"> <!--<![endif]--> 7<head> 8 9 <!-- Basic page needs ================================================== --> 10 <meta charset="utf-8"> 11 <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> 12 13 14 <link rel="icon" href="https://cdn.store-assets.com/s/1318958/f/17587815.jpg" /> 15 16 17 <!-- Title and description ================================================== --> 18 <title> 19 ç»å ¥ – LIJOE 20 </title> 21 22 23 24 <!-- Social meta ================================================== --> 25 26 27 <meta property="og:type" content="website"> 28 <meta property="og:title" content="ç»å ¥"> 29 <meta property="og:url" content="https://www.lijoe.tw/account/login"> 30 31 <meta property="og:image" content="https://cdn.store-assets.com/s/1318958/f/17587815.jpg"> 32 <meta property="og:image:secure_url" content="https://cdn.store-assets.com/s/1318958/f/17587815.jpg"> 33 34 35 36<meta property="og:description" content="æ°åæ ä¿é¤ â§ æ°é å°åçï¼äººéè¦ç¶é身å¿éçæ¢ç´¢ï¼éè¦æ´å¥½çèªå·±ãçµ¦ä½ ç´ç²¹ç天ç¶åæï¼æçºä½ çæ¸å±¬ï¼åµé ä½ çèªä¿¡ãæ¡ç¨é«ççç´çºç¶ï¼é¦åµå·¥æ³è£½ç¨ï¼æææº¶å ¥ç²¾è¯å ç´ ï¼éæ°´éæ¾ï¼æ·±å ¥èé¾ã"> 37<meta property="og:site_name" content="LIJOE "> 38 39 40 41 <meta name="twitter:card" content="summary"> 42 43 44 45 <meta name="twitter:site" content="@"> 46 47 48 49 50 51 <!-- Helpers ================================================== --> 52 <link rel="canonical" href="https://www.lijoe.tw/account/login"> 53 <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1"> 54 <meta name="theme-color" content="#384d44"> 55 56
56<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js" type="text/javascript" ></script>
56 57 58 <!-- Header hook for plugins ================================================== --> 59 60<!-- ScriptTags -->
61<script>window.__st={p: "customers",cid: null,cem: null,cph: null,cfn: null,cln: null,cge: null,cdb: null,ccc: null};</script>
61<script src='/assets/events.js'></script>
61<script>(function(){function asyncLoad(){var urls=['/assets/traffic.js?v=1','https://apps.easystore.co/facebook-login/script.js?shop=lijoe.easy.co'];for(var i=0;i<urls.length;i++){var s=document.createElement('script');s.type='text/javascript';s.async=true;s.src=urls[i];var x=document.getElementsByTagName('script')[0];x.parentNode.insertBefore(s, x);}}window.attachEvent ? window.attachEvent('onload', asyncLoad) : window.addEventListener('load', asyncLoad, false);})();</script>
61 62<!-- /ScriptTags --> 63 64 65 66
66<script src="https://store-themes.easystore.co/1318958/themes/310721/assets/global.js?t=1790562592" defer="defer"></script>
66 67 68 69 70
70<script src="/assets/shop_common.js" type="text/javascript" ></script>
70 71
71<script src="/assets/customer_area.js" type="text/javascript" ></script>
71 72 73
73<script> 74 (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ 75 (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), 76 m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) 77 })(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); 78 79 ga('create', '', 'auto','myTracker'); 80 ga('myTracker.send', 'pageview'); 81 82 </script>
82 83 84
84<script src="/assets/storefront.js?id=1d419de2011a5572c98b" type="text/javascript" ></script>
84 85 86 87 <!-- CSS ================================================== --> 88 <style> 89 @font-face { 90 font-family: 'Alata'; 91 font-style: normal; 92 font-weight: regular; 93 src: local('Alata regular'), local('Alata-regular'), url(https://fonts.gstatic.com/s/alata/v2/PbytFmztEwbIofe6xKcRQEOX.ttf) format('truetype'); 94 } 95 96 @font-face { 97 font-family: 'Alata'; 98 font-style: normal; 99 font-weight: regular; 100 src: local('Alata regular'), local('Alata-regular'), url(https://fonts.gstatic.com/s/alata/v2/PbytFmztEwbIofe6xKcRQEOX.ttf) format('truetype'); 101 } 102 103 :root { 104 --font-body-family: 'Alata', sans-serif; 105 --font-body-style: normal; 106 --font-body-weight: 400; 107 108 --font-heading-family: 'Alata', sans-serif; 109 --font-heading-style: normal; 110 --font-heading-weight: 700; 111 112 --color-heading-text: 56,77,68; 113 --color-base-text: 56,77,68; 114 --color-base-background-1: 239,246,231; 115 --color-base-background-2: 239,246,231; 116 117 --color-base-solid-button-labels: 239,246,231; 118 --color-base-outline-button-labels: 239,246,231; 119 120 --color-base-accent-1: 56,77,68; 121 --color-base-accent-2: 56,77,68; 122 --payment-terms-background-color: 239,246,231; 123 124 --gradient-base-background-1: 239,246,231; 125 --gradient-base-background-2: 239,246,231; 126 --gradient-base-accent-1: 56,77,68; 127 --gradient-base-accent-2: 56,77,68; 128 129 --page-width: 145rem; 130 } 131 132 *, 133 *::before, 134 *::after { 135 box-sizing: inherit; 136 } 137 138 html { 139 box-sizing: border-box; 140 font-size: 62.5%; 141 height: 100%; 142 } 143 144 body { 145 display: grid; 146 grid-template-rows: auto auto 1fr auto; 147 grid-template-columns: 100%; 148 min-height: 100%; 149 margin: 0; 150 font-size: 1.5rem; 151 letter-spacing: 0.06rem; 152 line-height: 1.8; 153 font-family: var(--font-body-family); 154 font-style: var(--font-body-style); 155 font-weight: var(--font-body-weight); 156 157 } 158 159 @media screen and (min-width: 750px) { 160 body { 161 font-size: 1.6rem; 162 } 163 } 164 </style> 165 166 <link href="https://store-themes.easystore.co/1318958/themes/310721/assets/base.css?t=1790562592" rel="stylesheet" type="text/css" media="screen" /> 167 168 169 170 171
171<script>document.documentElement.className = document.documentElement.className.replace('no-js', 'js');</script>
171 172
172<script type="application/ld+json"> 173 {"@context":"https://schema.org/","@graph":[{"@type":"WebSite","@id":"https://www.lijoe.tw#website","name":"LIJOE","url":"https://www.lijoe.tw","potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://www.lijoe.tw/search?q={search_term_string}"},"query-input":"required name=search_term_string"},"publisher":{"@id":"https://www.lijoe.tw#organization"}},{"@type":"Organization","@id":"https://www.lijoe.tw#organization","name":"LIJOE","url":"https://www.lijoe.tw","logo":{"@type":"ImageObject","url":"https://cdn.store-assets.com/s/1318958/f/17587815.jpg?width=350\u0026format=webp"}}]} 174 </script>
174 175</head> 176 177<body id="------" class="template-customers" > 178 179 180<!-- Snippet:global/body_start: Announcement Bar --> 181<link rel="stylesheet" href="https://apps.easystore.co/assets/css/annoucement-bar/slider.css?v1.01"> 182 183<input type="hidden" id="total_announcement_left" name="total_announcement_left" value="2"> 184<input type="hidden" id="locale" name="locale" value="zh_TW"> 185 186<slider-announcement-bar-app id="announcement-bar" name="announcement-bar" style=" 187 border: unset; 188 padding: 4px 0px; 189 margin: 0px; 190 z-index:2999; 191 background:rgb(56, 77, 68); 192 color:rgb(239, 246, 231); 193 position: -webkit-sticky; position: sticky; top: 0; 194"> 195 196 <div style=" 197 display: flex; 198 justify-content: space-between; 199 align-items: center; 200 padding: 0px 0px; 201 border-top: 0px; 202 border-bottom: 0px; 203 border-color: transparent; 204 "> 205 <div style="height: 24px;"> 206 <a id="previous-announcement-bar-button" class="announcement-bar-direction-button" type="button" name="previous" style="height: 24px;"> 207 <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-chevron-left" width="24" height="24" viewBox="0 0 24 24" stroke-width="1.5" stroke="white" fill="none" stroke-linecap="round" stroke-linejoin="round"> 208 <path stroke="none" d="M0 0h24v24H0z" fill="none" /> 209 <polyline points="15 6 9 12 15 18" /> 210 </svg> 211 </a> 212 </div> 213 214 <ul style="flex-grow: 2; margin: 0px;"> 215 <li id="announcement_bar_0" style=" 216 display: flex; 217 justify-content: center; 218 align-items: center; 219 flex-wrap: wrap; 220 margin: 0px; 221 width: 100%; 222 word-wrap: break-word; 223 "> 224 ãä¸ç§æ´»åãæ¥µæèå ç³»åä¸ä»¶ï¼ï¼æï¼å ©ä»¶ï¼ï¼æï¼æ´»åæéè³2026/10/31æ¢ï¼ 225 <a class="announcement-bar-button" href="https://www.lijoe.tw/collections/all" style="color: rgb(56, 77, 68); background: rgb(239, 246, 231);">æåæ¶è³¼</a> 226 <div id='announcementBar_countdown_0' class="announcementBar_timer style_3" style="color: rgb(56, 77, 68); background: rgb(239, 246, 231); display: none;"> 227 </div> 228 <input type="hidden" id="expired_at_0" name="expired_at_0" value="2026-10-31 23:55"> 229 </li> 230 <li id="announcement_bar_1" style=" 231 display: flex; 232 justify-content: center; 233 align-items: center; 234 flex-wrap: wrap; 235 margin: 0px; 236 width: 100%; 237 word-wrap: break-word; 238 "> 239 æ°ãåãä¸ãå¸ãï¼ãå ¨ãé¤¨ãæ¶ãè²»ãå ãéãè²»ãï¼ 240 <input type="hidden" id="expired_at_1" name="expired_at_1" value="2026-09-27 00:00"> 241 </li> 242 </ul> 243 244 <div style="display: flex;"> 245 <a id="next-announcement-bar-button" class="announcement-bar-direction-button" type="button" name="next" style="height: 24px;"> 246 <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-chevron-right" width="24" height="24" viewBox="0 0 24 24" stroke-width="1.5" stroke="white" fill="none" stroke-linecap="round" stroke-linejoin="round"> 247 <path stroke="none" d="M0 0h24v24H0z" fill="none" /> 248 <polyline points="9 6 15 12 9 18" /> 249 </svg> 250 </a> 251 </div> 252 </div> 253 254 255</slider-announcement-bar-app> 256
257<script> 258 $(function() { 259 var is_top_enabled = 1; 260 261 const loadScript = function(url, callback) { 262 const script = document.createElement("script"); 263 script.type = "text/javascript"; 264 // If the browser is Internet Explorer. 265 if (script.readyState) { 266 script.onreadystatechange = function() { 267 if (script.readyState == "loaded" || script.readyState == "complete") { 268 script.onreadystatechange = null; 269 callback(); 270 } 271 }; 272 // For any other browser. 273 } else { 274 script.onload = function() { 275 callback(); 276 }; 277 } 278 script.src = url; 279 document.getElementsByTagName("head")[0].appendChild(script); 280 }; 281 282 const announcementBarAppJS = function($) { 283 284 $('#announcement-close-button').on('click', function() { 285 $('#announcement-bar, #announcement-bar-top').hide(); 286 $('#easystore-section-header, .sticky-topbar').css('top', ''); 287 }); 288 } 289 290 if (typeof jQuery === 'undefined') { 291 loadScript('//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js', function() { 292 jQuery = jQuery.noConflict(true); 293 announcementBarAppJS(jQuery); 294 }); 295 } else { 296 announcementBarAppJS(jQuery); 297 } 298 299 300 301 if(is_top_enabled){ 302 // Prevent announcement bar block header 303 setTimeout(()=>{ 304 $('#easystore-section-header, .sticky-topbar').css('top', $('#announcement-bar').height()+'px'); 305 }, 2000); 306 } 307 }); 308 309 setInterval(function() { 310 const total_announcement = "2" 311 var total_announcement_left = $("#total_announcement_left").val(); 312 313 for (let i = 0; i <= total_announcement; i++) { 314 const startDate = new Date(); 315 const endDateStr = $("#expired_at_" + i).val(); 316 const endDate = endDateStr == undefined ? new Date() : new Date(endDateStr.replace(/-/g, "/")); 317 const seconds = (endDate.getTime() - startDate.getTime()) / 1000; 318 319 const days = parseInt(seconds / 86400); 320 const hours = parseInt((seconds % 86400) / 3600); 321 const mins = parseInt((seconds % 86400 % 3600) / 60); 322 const secs = parseInt((seconds % 86400 % 3600) % 60); 323 324 // use to translate countdown unit 325 // (translate based on the preferred language when save announcement bar setting) 326 String.prototype.translate = function() { 327 try { 328 if ($("#locale").val() == "zh_TW") { 329 if (this.toString() === 'day') { 330 return "天"; 331 } 332 if (this.toString() === 'hour') { 333 return "å°æ"; 334 } 335 if (this.toString() === 'min') { 336 return "åé"; 337 } 338 if (this.toString() === 'sec') { 339 return "ç§"; 340 } 341 } else { 342 if (this.toString() === 'day') { 343 if (days > 0) { 344 return "Days"; 345 } else { 346 return "Day"; 347 } 348 } else if (this.toString() === 'hour') { 349 if (hours > 0) { 350 return "Hours"; 351 } else { 352 return "Hour"; 353 } 354 } else if (this.toString() === 'min') { 355 if (mins > 0) { 356 return "Mins"; 357 } else { 358 return "Min"; 359 } 360 } else if (this.toString() === 'sec') { 361 if (secs > 0) { 362 return "Secs"; 363 } else { 364 return "Sec"; 365 } 366 } 367 } 368 } catch (error) { 369 console.log("Some errors heres", error); 370 } 371 }; 372 373 const announcementBar_countdown = document.getElementById("announcementBar_countdown_" + i); 374 if (announcementBar_countdown && seconds > 0) { 375 376 $(announcementBar_countdown).show() 377 announcementBar_countdown.innerHTML = ` 378 <div> 379 ${days} <small>${'day'.translate()}</small> 380 </div> 381 <div> 382 ${hours} <small>${'hour'.translate()}</small> 383 </div> 384 <div> 385 ${mins} <small>${'min'.translate()}</small> 386 </div> 387 <div> 388 ${secs} <small>${'sec'.translate()}</small> 389 </div> 390 `; 391 392 393 } else if (announcementBar_countdown && seconds <= 0) { 394 $("#announcement_bar_" + i).remove(); 395 total_announcement_left = total_announcement_left - 1; 396 $("#total_announcement_left").val(total_announcement_left); 397 } 398 } 399 400 showOrHide(total_announcement_left); 401 }, 1000); 402 403 404 function showOrHide(total_announcement_left) { 405 if (total_announcement_left <= 1) { 406 $("#previous-announcement-bar-button,#next-announcement-bar-button").hide(); 407 } else { 408 $("#previous-announcement-bar-button,#next-announcement-bar-button").show(); 409 } 410 411 if (total_announcement_left == 0) { 412 $("#announcement-close-button").hide(); 413 $("#announcement-bar").hide(); 414 $('#announcement-bar-top').hide(); 415 $('#easystore-section-header, .sticky-topbar').css('top', ''); 416 } 417 }; 418 419 let annoucementBarAutoMoveInterval = ''; 420 class AnnouncementBarAppSlider extends HTMLElement { 421 constructor() { 422 super(); 423 this.slider = this.querySelector('ul'); 424 this.sliderItems = this.querySelectorAll('li'); 425 this.prevButton = this.querySelector('a[name="previous"]'); 426 this.nextButton = this.querySelector('a[name="next"]'); 427 428 if (!this.slider || !this.nextButton) return; 429 430 const resizeObserver = new ResizeObserver(entries => this.initPages()); 431 resizeObserver.observe(this.slider); 432 433 this.slider.addEventListener('scroll', this.update.bind(this)); 434 this.prevButton.addEventListener('click', this.onButtonClick.bind(this)); 435 this.nextButton.addEventListener('click', this.onButtonClick.bind(this)); 436 437 438 } 439 440 initPages() { 441 const sliderItemsToShow = Array.from(this.sliderItems).filter(element => element.clientWidth > 0); 442 this.sliderLastItem = sliderItemsToShow[sliderItemsToShow.length - 1]; 443 if (sliderItemsToShow.length === 0) return; 444 this.slidesPerPage = Math.floor(this.slider.clientWidth / sliderItemsToShow[0].clientWidth); 445 this.totalPages = sliderItemsToShow.length - this.slidesPerPage + 1; 446 this.update(); 447 let self = this 448 var total_announcement_left = $("#total_announcement_left").val(); 449 annoucementBarAutoMoveInterval = setInterval(function() { 450 if (total_announcement_left > 1) { 451 self.moveSlide('next') 452 } 453 }, 5000) 454 } 455 456 update() { 457 this.currentPage = Math.round(this.slider.scrollLeft / this.sliderLastItem.clientWidth) + 1; 458 } 459 460 onButtonClick(event) { 461 event.preventDefault(); 462 let self = this; 463 self.moveSlide(event.currentTarget.name); 464 } 465 466 467 moveSlide(move_to) { 468 469 clearInterval(annoucementBarAutoMoveInterval); 470 let self = this; 471 annoucementBarAutoMoveInterval = setInterval(function() { 472 self.moveSlide('next'); 473 }, 5000) 474 475 if (move_to === 'previous' && this.currentPage === 1) { 476 this.slider.scrollTo({ 477 left: this.sliderLastItem.clientWidth * (this.totalPages - 1) 478 }); 479 } else if (move_to === 'next' && this.currentPage === this.totalPages) { 480 this.slider.scrollTo({ 481 left: 0 482 }); 483 } else { 484 const slideScrollPosition = move_to === 'next' ? this.slider.scrollLeft + this.sliderLastItem 485 .clientWidth : this.slider.scrollLeft - this.sliderLastItem.clientWidth; 486 this.slider.scrollTo({ 487 left: slideScrollPosition 488 }); 489 } 490 } 491 492 } 493 494 customElements.define('slider-announcement-bar-app', AnnouncementBarAppSlider); 495</script>
495 496 497<!-- /Snippet --> 498 499<!-- Snippet:global/body_start: Console Extension --> 500<div id='es_console' style='display: none;'>1318958</div> 501<!-- /Snippet --> 502 503 504 <style> 505 header { 506 --logo-width: 100px; 507 } 508 .header-wrapper, 509 .header-wrapper .list-menu--disclosure, 510 .header-wrapper .search-modal{ 511 background-color: #eff6e7; 512 } 513 .header-wrapper .search-modal .field__input{ 514 background-color: rgb(var(--color-background)); 515 } 516 .header-wrapper summary .icon-caret, 517 .header-wrapper .header__menu-item a, 518 .header-wrapper .list-menu__item, 519 .header-wrapper .link--text{ 520 color: #384d44; 521 } 522 .header__logo_secondary{ 523 display: none; 524 } 525 526 .search-modal__form{ 527 position: relative; 528 } 529 530 .dropdown { 531 display: none; 532 position: absolute; 533 top: 100%; 534 left: 0; 535 width: 100%; 536 padding: 5px 0; 537 background-color: #fff; 538 color:#000; 539 z-index: 1000; 540 border-bottom-left-radius: 15px; 541 border-bottom-right-radius: 15px; 542 border: 1px solid rgba(var(--color-foreground), 1); 543 border-top: none; 544 overflow-x: hidden; 545 overflow-y: auto; 546 max-height: 350px; 547 } 548 549 .dropdown-item { 550 padding: 0.4rem 2rem; 551 cursor: pointer; 552 line-height: 1.4; 553 overflow: hidden; 554 text-overflow: ellipsis; 555 white-space: nowrap; 556 } 557 558 .dropdown-item:hover{ 559 background-color: #f3f3f3; 560 } 561 562 .search__input.is-focus{ 563 border-radius: 15px; 564 border-bottom-left-radius: 0; 565 border-bottom-right-radius: 0; 566 border: 1px solid rgba(var(--color-foreground), 1); 567 border-bottom: none; 568 box-shadow: none; 569 } 570 571 .clear-all { 572 text-align: right; 573 padding: 0 2rem 0.2rem; 574 line-height: 1; 575 font-size: 70%; 576 margin-bottom: -2px; 577 } 578 579 .clear-all:hover{ 580 background-color: #fff; 581 } 582 583 .search-input-focus .easystore-section-header-hidden{ 584 transform: none; 585 } 586 .referral-notification { 587 position: absolute; 588 top: 100%; 589 right: 0; 590 background: white; 591 border: 1px solid #e0e0e0; 592 border-radius: 8px; 593 box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); 594 width: 280px; 595 z-index: 1000; 596 padding: 16px; 597 margin-top: 8px; 598 font-size: 14px; 599 line-height: 1.4; 600 } 601 602 .referral-notification::before { 603 content: ''; 604 position: absolute; 605 top: -8px; 606 right: 20px; 607 width: 0; 608 height: 0; 609 border-left: 8px solid transparent; 610 border-right: 8px solid transparent; 611 border-bottom: 8px solid white; 612 } 613 614 .referral-notification::after { 615 content: ''; 616 position: absolute; 617 top: -9px; 618 right: 20px; 619 width: 0; 620 height: 0; 621 border-left: 8px solid transparent; 622 border-right: 8px solid transparent; 623 border-bottom: 8px solid #e0e0e0; 624 } 625 626 .referral-notification h4 { 627 margin: 0 0 8px 0; 628 color: #2196F3; 629 font-size: 16px; 630 font-weight: 600; 631 } 632 633 .referral-notification p { 634 margin: 0 0 12px 0; 635 color: #666; 636 } 637 638 .referral-notification .referral-code { 639 background: #f5f5f5; 640 padding: 8px; 641 border-radius: 4px; 642 font-family: monospace; 643 font-size: 13px; 644 text-align: center; 645 margin: 8px 0; 646 border: 1px solid #ddd; 647 } 648 649 .referral-notification .close-btn { 650 position: absolute; 651 top: 8px; 652 right: 8px; 653 background: none; 654 border: none; 655 font-size: 18px; 656 color: #999; 657 cursor: pointer; 658 padding: 0; 659 width: 20px; 660 height: 20px; 661 line-height: 1; 662 } 663 664 .referral-notification .close-btn:hover { 665 color: #333; 666 } 667 668 .referral-notification .action-btn { 669 background: #2196F3; 670 color: white; 671 border: none; 672 padding: 8px 16px; 673 border-radius: 4px; 674 cursor: pointer; 675 font-size: 12px; 676 margin-right: 8px; 677 margin-top: 8px; 678 } 679 680 .referral-notification .action-btn:hover { 681 background: #1976D2; 682 } 683 684 .referral-notification .dismiss-btn { 685 background: transparent; 686 color: #666; 687 border: 1px solid #ddd; 688 padding: 8px 16px; 689 border-radius: 4px; 690 cursor: pointer; 691 font-size: 12px; 692 margin-top: 8px; 693 } 694 695 .referral-notification .dismiss-btn:hover { 696 background: #f5f5f5; 697 } 698 .referral-modal__dialog { 699 transform: translate(-50%, 0); 700 transition: transform var(--duration-default) ease, visibility 0s; 701 z-index: 10000; 702 position: fixed; 703 top: 20vh; 704 left: 50%; 705 width: 100%; 706 max-width: 350px; 707 box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); 708 border-radius: 12px; 709 background-color: #fff; 710 color: #000; 711 padding: 20px; 712 text-align: center; 713 } 714 715 .modal-overlay.referral-modal-overlay { 716 position: fixed; 717 top: 0; 718 left: 0; 719 width: 100%; 720 height: 100%; 721 background-color: rgba(0, 0, 0, 0.7); 722 z-index: 2001; 723 display: block; 724 opacity: 1; 725 transition: opacity var(--duration-default) ease, visibility 0s; 726 } 727</style> 728 729 730 <style> 731 .template-index .header__logo_secondary + .header__heading-logo, 732 .template-index .easystore-section-header-sticky .header__logo_secondary{ 733 display: none; 734 } 735 .template-index .header__logo_secondary, 736 .template-index .easystore-section-header-sticky .header__logo_secondary + .header__heading-logo{ 737 display: block; 738 } 739 .template-index .header-wrapper { 740 position: absolute; 741 width: 100%; 742 } 743 .template-index .header-wrapper { 744 background-color: transparent; 745 } 746 747 .template-index #easystore-section-header:not(.easystore-section-header-sticky) .header__icon .icon{ 748 color: #eff6e7; 749 } 750 .template-index .easystore-section-header-sticky .header-wrapper{ 751 background-color: #eff6e7; 752 } 753 @media screen and (min-width: 990px) {
754 .template-index div:not(.easystore-section-header-sticky) nav > .list-menu > li > a, 755 .template-index div:not(.easystore-section-header-sticky) nav > .list-menu > li > details-disclosure > details > summary *{ 756 color: #eff6e7; 757 } 758 } 759 </style> 760 761 762<link rel="preload" href="https://store-themes.easystore.co/1318958/themes/310721/assets/section-header.css?t=1790562592" as="style" onload="this.onload=null;this.rel='stylesheet'"> 763<link rel="preload" href="https://store-themes.easystore.co/1318958/themes/310721/assets/component-list-menu.css?t=1790562592" as="style" onload="this.onload=null;this.rel='stylesheet'"> 764<link rel="preload" href="https://store-themes.easystore.co/1318958/themes/310721/assets/component-menu-drawer.css?t=1790562592" as="style" onload="this.onload=null;this.rel='stylesheet'"> 765<link rel="preload" href="https://store-themes.easystore.co/1318958/themes/310721/assets/component-cart-notification.css?v1.1?t=1790562592" as="style" onload="this.onload=null;this.rel='stylesheet'"> 766
767<script src="https://store-themes.easystore.co/1318958/themes/310721/assets/cart-notification.js?t=1790562592" defer="defer"></script>
vendor: 1 bytes, line 767
767
768<script src="https://store-themes.easystore.co/1318958/themes/310721/assets/details-modal.js?t=1790562592" defer="defer"></script>
768 769 770<svg xmlns="http://www.w3.org/2000/svg" class="hidden"> 771 <symbol id="icon-search" viewbox="0 0 18 19" fill="none"> 772 <path fill-rule="evenodd" clip-rule="evenodd" d="M11.03 11.68A5.784 5.784 0 112.85 3.5a5.784 5.784 0 018.18 8.18zm.26 1.12a6.78 6.78 0 11.72-.7l5.4 5.4a.5.5 0 11-.71.7l-5.41-5.4z" fill="currentColor"/> 773 </symbol> 774 775 <symbol id="icon-close" class="icon icon-close" fill="none" viewBox="0 0 18 17"> 776 <path d="M.865 15.978a.5.5 0 00.707.707l7.433-7.431 7.579 7.282a.501.501 0 00.846-.37.5.5 0 00-.153-.351L9.712 8.546l7.417-7.416a.5.5 0 10-.707-.708L8.991 7.853 1.413.573a.5.5 0 10-.693.72l7.563 7.268-7.418 7.417z" fill="currentColor"> 777 </symbol> 778</svg> 779 780 781<div id="easystore-section-header"> 782 <sticky-header class="header-wrapper header-wrapper--border-bottom"> 783 <header class="header header--top-center page-width header--has-menu" itemscope itemtype="http://schema.org/Organization"> 784 <div class="header__left-icon header__icons large-up-hide"> 785 <header-drawer data-breakpoint="tablet"> 786 <details class="menu-drawer-container menu-opening"> 787 <summary class="header__icon header__icon--menu header__icon--summary link link--text focus-inset" aria-label="Menu" role="button" aria-expanded="true" aria-controls="menu-drawer"> 788 <span> 789 790 791 792 <svg class="icon icon-hamburger " data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600"><path d="M32.5,65h535a25,25,0,0,0,0-50H32.5a25,25,0,0,0,0,50Z" fill="currentColor"/><path d="M567.5,275H32.5a25,25,0,0,0,0,50h535a25,25,0,0,0,0-50Z" fill="currentColor"/><path d="M567.5,535H32.5a25,25,0,0,0,0,50h535a25,25,0,0,0,0-50Z" fill="currentColor"/></svg> 793 794 795 796 797 798 799 <svg class="icon icon-close " data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600"><path d="M335.36,300,581.87,53.48a25,25,0,0,0-35.35-35.35L300,264.64,53.48,18.13A25,25,0,0,0,18.13,53.48L264.64,300,18.13,546.52a25,25,0,0,0,35.35,35.35L300,335.36,546.52,581.87a25,25,0,0,0,35.35-35.35Z" fill="currentColor"/></svg> 800 801 802 803 </span> 804 </summary> 805 <div id="menu-drawer" class="menu-drawer motion-reduce" tabindex="-1"> 806 <div class="menu-drawer__inner-container"> 807 <div class="menu-drawer__navigation-container"> 808 <nav class="menu-drawer__navigation"> 809 <ul class="menu-drawer__menu list-menu" role="list"> 810 811 812 813 <li> 814 <a href="/collections/all" class="menu-drawer__menu-item list-menu__item link link--text focus-inset"> 815 æ°åä¸å¸ 816 </a> 817 </li> 818 819 820 821 822 <li> 823 <a href="/pages/åçæ äº" class="menu-drawer__menu-item list-menu__item link link--text focus-inset"> 824 åçæ äº 825 </a> 826 </li> 827 828 829 830 831 <li> 832 <a href="/pages/å·¥æ³è£½ç¨" class="menu-drawer__menu-item list-menu__item link link--text focus-inset"> 833 å·¥æ³è£½ç¨ 834 </a> 835 </li> 836 837 838 839 840 <li> 841 <a href="/pages/è³¼ç©é ç¥" class="menu-drawer__menu-item list-menu__item link link--text focus-inset"> 842 è³¼ç©é ç¥ 843 </a> 844 </li> 845 846 847 </ul> 848 </nav> 849 850 <div class="menu-drawer__utility-links"> 851 852 853 854 855 856 857 858 859 <a href="/account/login" class="menu-drawer__account link link--text focus-inset h5"> 860 861 862 863 <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" role="presentation" class="icon icon-account " fill="none" viewBox="0 0 18 19"> 864 <path fill-rule="evenodd" clip-rule="evenodd" d="M6 4.5a3 3 0 116 0 3 3 0 01-6 0zm3-4a4 4 0 100 8 4 4 0 000-8zm5.58 12.15c1.12.82 1.83 2.24 1.91 4.85H1.51c.08-2.6.79-4.03 1.9-4.85C4.66 11.75 6.5 11.5 9 11.5s4.35.26 5.58 1.15zM9 10.5c-2.5 0-4.65.24-6.17 1.35C1.27 12.98.5 14.93.5 18v.5h17V18c0-3.07-.77-5.02-2.33-6.15-1.52-1.
8641-3.67-1.35-6.17-1.35z" fill="currentColor"></path> 865 </svg> 866 867 868 869 870 ç»å ¥ 871 </a> 872 873 <a href="/account/register" class="menu-drawer__account link link--text focus-inset h5"> 874 875 876 877 878 <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" role="presentation" class="icon icon-plus " fill="none" viewBox="0 0 10 10"> 879 <path fill-rule="evenodd" clip-rule="evenodd" d="M1 4.51a.5.5 0 000 1h3.5l.01 3.5a.5.5 0 001-.01V5.5l3.5-.01a.5.5 0 00-.01-1H5.5L5.49.99a.5.5 0 00-1 .01v3.5l-3.5.01H1z" fill="currentColor"></path> 880 </svg> 881 882 883 884 註å帳è 885 </a> 886 887 888 889 </div> 890 </div> 891 </div> 892 </div> 893 </details> 894 </header-drawer> 895 <details-modal class="header__search"> 896 <details> 897 <summary class="header__icon header__icon--search header__icon--summary link link--text focus-inset modal__toggle" aria-haspopup="dialog" aria-label="æå°"> 898 <span> 899 <svg class="modal__toggle-open icon icon-search" aria-hidden="true" focusable="false" role="presentation"> 900 <use href="#icon-search"> 901 </svg> 902 <svg class="modal__toggle-close icon icon-close" aria-hidden="true" focusable="false" role="presentation"> 903 <use href="#icon-close"> 904 </svg> 905 </span> 906 </summary> 907 <div class="search-modal modal__content" role="dialog" aria-modal="true" aria-label="æå°"> 908 <div class="modal-overlay"></div> 909 <div class="search-modal__content" tabindex="-1"> 910 <form action="/search" method="get" role="search" class="search search-modal__form"> 911 <div class="field"> 912 <input class="search__input field__input" 913 id="Search-In-Modal" 914 type="search" 915 name="q" 916 value="" 917 placeholder="æå°" 918 autocomplete="off" 919 > 920 <label class="field__label" for="Search-In-Modal">æå°</label> 921 <div class="dropdown" id="searchDropdown"></div> 922 <input type="hidden" name="search_history" class="hidden_search_history"> 923 <input type="hidden" name="options[prefix]" value="last"> 924 <button class="search__button field__button" aria-label="æå°"> 925 <svg class="icon icon-search" aria-hidden="true" focusable="false" role="presentation"> 926 <use href="#icon-search"> 927 </svg> 928 </button> 929 </div> 930 </form> 931 <button type="button" class="search-modal__close-button modal__close-button link link--text focus-inset" aria-label="accessibility.close"> 932 <svg class="icon icon-close" aria-hidden="true" focusable="false" role="presentation"> 933 <use href="#icon-close"> 934 </svg> 935 </button> 936 </div> 937 </div> 938 </details> 939</details-modal> 940 </div> 941 942 943 <a href="/" class="header__heading-link link link--text focus-inset" itemprop="url"> 944 945 <img src="https://cdn.store-assets.com/s/1318958/f/17824376.png" class="header__heading-logo header__logo_secondary" alt="LIJOE " loading="lazy"> 946 947 <img src="https://cdn.store-assets.com/s/1318958/f/17824217.png" class="header__heading-logo" alt="LIJOE " loading="lazy" itemprop="logo"> 948 </a> 949 950 <nav class="header__inline-menu"> 951 <ul class="list-menu list-menu--inline" role="list"> 952 953 954 955 <li> 956 <a href="/collections/all" class="header__menu-item header__menu-item list-menu__item link link--text focus-inset"> 957 æ°åä¸å¸ 958 </a> 959 </li> 960 961 962 963 964 <li> 965 <a href="/pages/åçæ äº" class="header__menu-item header__menu-item list-menu__item link link--text focus-inset"> 966 åçæ äº 967 </a> 968 </li> 969 970 971 972 973 <li> 974 <a href="/pages/å·¥æ³è£½ç¨" class="header__menu-item header__menu-item list-menu__item link link--text focus-inset"> 975 å·¥æ³è£½ç¨ 976 </a> 977 </li> 978 979 980 981 982 <li> 983 <a href="/pages/è³¼ç©é ç¥" class="header__menu-item header__menu-item list-menu__item link link--text focus-inset"> 984 è³¼ç©é ç¥ 985 </a> 986 </li> 987 988 989 990 991 992 993 994 995 996 997 998 999 </ul> 1000 </nav> 1001 <div class="header__icons"> 1002 <div class="medium-hide small-hide"> 1003 <details-modal class="header__search"> 1004 <details> 1005 <summary class="header__icon header__icon--search header__icon--summary link link--text focus-inset modal__toggle" aria-haspopup="dialog" aria-label="æå°">
1006 <span> 1007 <svg class="modal__toggle-open icon icon-search" aria-hidden="true" focusable="false" role="presentation"> 1008 <use href="#icon-search"> 1009 </svg> 1010 <svg class="modal__toggle-close icon icon-close" aria-hidden="true" focusable="false" role="presentation"> 1011 <use href="#icon-close"> 1012 </svg> 1013 </span> 1014 </summary> 1015 <div class="search-modal modal__content" role="dialog" aria-modal="true" aria-label="æå°"> 1016 <div class="modal-overlay"></div> 1017 <div class="search-modal__content" tabindex="-1"> 1018 <form action="/search" method="get" role="search" class="search search-modal__form"> 1019 <div class="field"> 1020 <input class="search__input field__input" 1021 id="Search-In-Modal" 1022 type="search" 1023 name="q" 1024 value="" 1025 placeholder="æå°" 1026 autocomplete="off" 1027 > 1028 <label class="field__label" for="Search-In-Modal">æå°</label> 1029 <div class="dropdown" id="searchDropdown"></div> 1030 <input type="hidden" name="search_history" class="hidden_search_history"> 1031 <input type="hidden" name="options[prefix]" value="last"> 1032 <button class="search__button field__button" aria-label="æå°"> 1033 <svg class="icon icon-search" aria-hidden="true" focusable="false" role="presentation"> 1034 <use href="#icon-search"> 1035 </svg> 1036 </button> 1037 </div> 1038 </form> 1039 <button type="button" class="search-modal__close-button modal__close-button link link--text focus-inset" aria-label="accessibility.close"> 1040 <svg class="icon icon-close" aria-hidden="true" focusable="false" role="presentation"> 1041 <use href="#icon-close"> 1042 </svg> 1043 </button> 1044 </div> 1045 </div> 1046 </details> 1047</details-modal> 1048 </div> 1049 1050 1051 1052 <div class="header__icon header__icon--account link link--text focus-inset small-hide medium-hide" style="position: relative;"> 1053 <a href="/account/login" class="header__icon link link--text focus-inset p-2"> 1054 1055 1056 1057 <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" role="presentation" class="icon icon-account " fill="none" viewBox="0 0 18 19"> 1058 <path fill-rule="evenodd" clip-rule="evenodd" d="M6 4.5a3 3 0 116 0 3 3 0 01-6 0zm3-4a4 4 0 100 8 4 4 0 000-8zm5.58 12.15c1.12.82 1.83 2.24 1.91 4.85H1.51c.08-2.6.79-4.03 1.9-4.85C4.66 11.75 6.5 11.5 9 11.5s4.35.26 5.58 1.15zM9 10.5c-2.5 0-4.65.24-6.17 1.35C1.27 12.98.5 14.93.5 18v.5h17V18c0-3.07-.77-5.02-2.33-6.15-1.52-1.1-3.67-1.35-6.17-1.35z" fill="currentColor"></path> 1059 </svg> 1060 1061 1062 1063 </a> 1064 1065 <!-- Referral Notification Popup for Desktop --> 1066 <div id="referralNotification" class="referral-notification" style="display: none;"> 1067 <button class="close-btn" onclick="dismissReferralNotification()">×</button> 1068 <div style="text-align: center; margin-bottom: 16px;"> 1069 <div style="width: 100px; height: 100px; margin: 0 auto;"> 1070 <img src="https://resources.easystore.co/storefront/icons/channels/vector_referral_program.svg"> 1071 </div> 1072 </div> 1073 <p id="referralSignupMessage" style="text-align: center; font-size: 14px; color: #666; margin: 0 0 20px 0;"> 1074 æ¨ç好å鿍 åé¥éï¼ç«å³è¨»åé åã 1075 </p> 1076 <div style="text-align: center;"> 1077 <button class="btn" onclick="goToSignupPage()" style="width: 100%;"> 1078 註å 1079 </button> 1080 </div> 1081 </div> 1082 </div> 1083 1084 1085 1086 <a href="/cart" class="header__icon header__icon--cart link link--text focus-inset" id="cart-icon-bubble"> 1087 1088 1089 1090 <svg class="icon icon-cart-empty " aria-hidden="true" focusable="false" role="presentation" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40" fill="none"> 1091 <path d="m15.75 11.8h-3.16l-.77 11.6a5 5 0 0 0 4.99 5.34h7.38a5 5 0 0 0 4.99-5.33l-.78-11.61zm0 1h-2.22l-.71 10.67a4 4 0 0 0 3.99 4.27h7.38a4 4 0 0 0 4-4.27l-.72-10.67h-2.22v.63a4.75 4.75 0 1 1 -9.5 0zm8.5 0h-7.5v.63a3.7
10915 3.75 0 1 0 7.5 0z" fill="currentColor" fill-rule="evenodd"></path> 1092 </svg> 1093 1094 1095 1096 <div class="cart-count-bubble hidden"> 1097 <span aria-hidden="true" class="js-content-cart-count">0</span> 1098 </div> 1099 </a> 1100 1101 1102 1103 <!-- Referral Notification Modal for Mobile --> 1104 <details-modal class="referral-modal" id="referralMobileModal"> 1105 <details> 1106 <summary class="referral-modal__toggle" aria-haspopup="dialog" aria-label="Open referral modal" style="display: none;"> 1107 </summary> 1108 <div class="modal-overlay referral-modal-overlay"></div> 1109 <div class="referral-modal__dialog" role="dialog" aria-modal="true" aria-label="Referral notification"> 1110 <div class="referral-modal__content"> 1111 <button type="button" class="modal__close-button" aria-label="Close" onclick="closeMobileReferralModal()" style="position: absolute; top: 16px; right: 16px; background: none; border: none; font-size: 24px; cursor: pointer;"> 1112 × 1113 </button> 1114 1115 <div style="margin-bottom: 24px;"> 1116 <div style="width: 120px; height: 120px; margin: 0 auto 20px;"> 1117 <img src="https://resources.easystore.co/storefront/icons/channels/vector_referral_program.svg" style="width: 100%; height: 100%;"> 1118 </div> 1119 </div> 1120 1121 <p id="referralSignupMessageMobile" style="font-size: 16px; color: #333; margin: 0 0 30px 0; line-height: 1.5;"> 1122 æ¨ç好å鿍 åé¥éï¼ç«å³è¨»åé åã 1123 </p> 1124 1125 <button type="button" class="btn" onclick="goToSignupPageFromMobile()" style="width: 100%;"> 1126 註å 1127 </button> 1128 </div> 1129 </div> 1130 </details> 1131 </details-modal> 1132 1133 1134 </div> 1135 </header> 1136 </sticky-header> 1137 1138<cart-notification> 1139 <div class="cart-notification-wrapper page-width color-background-1"> 1140 <div id="cart-notification" class="cart-notification focus-inset" aria-modal="true" aria-label="å·²å å ¥è³¼ç©è»" role="dialog" tabindex="-1"> 1141 <div class="cart-notification__header"> 1142 <h2 class="cart-notification__heading caption-large"> 1143 1144 1145 <svg class="icon icon-checkmark color-foreground-text " aria-hidden="true" focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 9" fill="none"> 1146 <path fill-rule="evenodd" clip-rule="evenodd" d="M11.35.643a.5.5 0 01.006.707l-6.77 6.886a.5.5 0 01-.719-.006L.638 4.845a.5.5 0 11.724-.69l2.872 3.011 6.41-6.517a.5.5 0 01.707-.006h-.001z" fill="currentColor"></path> 1147 </svg> 1148 1149 1150 å·²å å ¥è³¼ç©è»</h2> 1151 <button type="button" class="cart-notification__close modal__close-button link link--text focus-inset" aria-label="accessibility.close"> 1152 1153 1154 1155 <svg class="icon icon-close " data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600"><path d="M335.36,300,581.87,53.48a25,25,0,0,0-35.35-35.35L300,264.64,53.48,18.13A25,25,0,0,0,18.13,53.48L264.64,300,18.13,546.52a25,25,0,0,0,35.35,35.35L300,335.36,546.52,581.87a25,25,0,0,0,35.35-35.35Z" fill="currentColor"/></svg> 1156 1157 1158 1159 </button> 1160 </div> 1161 <div id="cart-notification-product" class="cart-notification-product"></div> 1162 <div class="cart-notification__links"> 1163 <a href="/cart" id="cart-notification-button" class="button button--secondary button--full-width">æ¥çè³¼ç©è» (<span class="js-content-cart-count">0</span>)</a> 1164 <form action="/cart" method="post" id="cart-notification-form"> 1165 <input type="hidden" name="_token" value="u4QpX2koqlBocy10ItIAH1w3EC4wC46C7jxeR0Zx"> 1166 <input type="hidden" name="current_currency" value=""> 1167 <button class="button button--primary button--full-width" name="checkout" value="true">çµå¸³</button> 1168 </form> 1169 <a href="/collections/all" class="link button-label">ç¹¼çºè³¼ç©</a> 1170 </div> 1171 </div> 1172 </div> 1173</cart-notification> 1174<style> 1175 .cart-notification { 1176 display: none; 1177 } 1178</style>
1179<script> 1180document.getElementById('cart-notification-form').addEventListener('submit',(event)=>{ 1181 if(event.submitter) event.submitter.classList.add('loading'); 1182}) 1183 1184</script>
1184 1185 1186</div> 1187 1188
1189<script> 1190 1191 class StickyHeader extends HTMLElement { 1192 constructor() { 1193 super(); 1194 } 1195 1196 connectedCallback() { 1197 this.header = document.getElementById('easystore-section-header'); 1198 this.headerBounds = {}; 1199 this.currentScrollTop = 0; 1200 this.preventReveal = false; 1201 1202 this.onScrollHandler = this.onScroll.bind(this); 1203 this.hideHeaderOnScrollUp = () => this.preventReveal = true; 1204 1205 this.addEventListener('preventHeaderReveal', this.hideHeaderOnScrollUp); 1206 window.addEventListener('scroll', this.onScrollHandler, false); 1207 1208 this.createObserver(); 1209 } 1210 1211 disconnectedCallback() { 1212 this.removeEventListener('preventHeaderReveal', this.hideHeaderOnScrollUp); 1213 window.removeEventListener('scroll', this.onScrollHandler); 1214 } 1215 1216 createObserver() { 1217 let observer = new IntersectionObserver((entries, observer) => { 1218 this.headerBounds = entries[0].intersectionRect; 1219 observer.disconnect(); 1220 }); 1221 1222 observer.observe(this.header); 1223 } 1224 1225 onScroll() { 1226 const scrollTop = window.pageYOffset || document.documentElement.scrollTop; 1227 1228 if (scrollTop > this.currentScrollTop && scrollTop > this.headerBounds.bottom) { 1229 requestAnimationFrame(this.sticky.bind(this)); 1230 } else if (scrollTop < this.currentScrollTop && scrollTop > this.headerBounds.bottom) { 1231 if (!this.preventReveal) { 1232 requestAnimationFrame(this.reveal.bind(this)); 1233 } else { 1234 window.clearTimeout(this.isScrolling); 1235 1236 this.isScrolling = setTimeout(() => { 1237 this.preventReveal = false; 1238 }, 66); 1239 1240 requestAnimationFrame(this.sticky.bind(this)); 1241 } 1242 } else if (scrollTop <= this.headerBounds.top) { 1243 requestAnimationFrame(this.reset.bind(this)); 1244 } 1245 1246 1247 this.currentScrollTop = scrollTop; 1248 } 1249 1250 sticky() { 1251 this.header.classList.add('easystore-section-header-sticky'); 1252 this.closeMenuDisclosure(); 1253 this.closeSearchModal(); 1254 } 1255 1256 reveal() { 1257 this.header.classList.add('easystore-section-header-sticky'); 1258 } 1259 1260 reset() { 1261 this.header.classList.remove('easystore-section-header-sticky', 'animate'); 1262 } 1263 1264 closeMenuDisclosure() { 1265 this.disclosures = this.disclosures || this.header.querySelectorAll('details-disclosure'); 1266 this.disclosures.forEach(disclosure => disclosure.close()); 1267 } 1268 1269 closeSearchModal() { 1270 this.searchModal = this.searchModal || this.header.querySelector('details-modal'); 1271 this.searchModal.close(false); 1272 } 1273 } 1274 1275 customElements.define('sticky-header', StickyHeader); 1276 1277 1278 class DetailsDisclosure extends HTMLElement{ 1279 constructor() { 1280 super(); 1281 this.mainDetailsToggle = this.querySelector('details'); 1282 // this.mainDetailsToggle.addEventListener('focusout', this.onFocusOut.bind(this)); 1283 this.mainDetailsToggle.addEventListener('mouseover', this.open.bind(this)); 1284 this.mainDetailsToggle.addEventListener('mouseleave', this.close.bind(this)); 1285 } 1286 1287 onFocusOut() { 1288 setTimeout(() => { 1289 if (!this.contains(document.activeElement)) this.close(); 1290 }) 1291 } 1292 1293 open() { 1294 this.mainDetailsToggle.setAttribute('open',1) 1295 } 1296 1297 close() { 1298 this.mainDetailsToggle.removeAttribute('open') 1299 } 1300 } 1301 1302 customElements.define('details-disclosure', DetailsDisclosure); 1303 1304 function clearAll() { 1305 localStorage.removeItem('searchHistory'); 1306 1307 var customer = ""; 1308 if(customer) { 1309 // Your logic to clear all data or call an endpoint 1310 fetch('/account/search_histories', { 1311 method: 'DELETE', 1312 headers: { 1313 "Content-Type": "application/json", 1314 "X-Requested-With": "XMLHttpRequest" 1315 }, 1316 body: JSON.stringify({ 1317 _token: "u4QpX2koqlBocy10ItIAH1w3EC4wC46C7jxeR0Zx" 1318 }), 1319 }) 1320 .then(response => response.json()) 1321 } 1322 } 1323 // End - delete search history from local storage 1324 1325 // search history dropdown 1326 var searchInputs = document.querySelectorAll('.search__input'); 1327 1328 if(searchInputs.length > 0) { 1329
1330 searchInputs.forEach((searchInput)=> { 1331 1332 searchInput.addEventListener('focus', function() { 1333 var searchDropdown = searchInput.closest('form').querySelector('#searchDropdown'); 1334 searchDropdown.innerHTML = ''; // Clear existing items 1335 1336 // retrieve data from local storage 1337 var searchHistoryData = JSON.parse(localStorage.getItem('searchHistory')) || []; 1338 1339 // Convert JSON to string 1340 var search_history_json = JSON.stringify(searchHistoryData); 1341 1342 // Set the value of the hidden input 1343 searchInput.closest('form').querySelector(".hidden_search_history").value = search_history_json; 1344 1345 // create dropdown items 1346 var clearAllItem = document.createElement('div'); 1347 clearAllItem.className = 'dropdown-item clear-all'; 1348 clearAllItem.textContent = 'Clear'; 1349 clearAllItem.addEventListener('click', function() { 1350 clearAll(); 1351 searchDropdown.style.display = 'none'; 1352 searchInput.classList.remove('is-focus'); 1353 }); 1354 searchDropdown.appendChild(clearAllItem); 1355 1356 // create dropdown items 1357 searchHistoryData.forEach(function(item) { 1358 var dropdownItem = document.createElement('div'); 1359 dropdownItem.className = 'dropdown-item'; 1360 dropdownItem.textContent = item.term; 1361 dropdownItem.addEventListener('click', function() { 1362 searchInput.value = item.term; 1363 searchInput.closest('form').submit(); 1364 searchDropdown.style.display = 'none'; 1365 }); 1366 searchDropdown.appendChild(dropdownItem); 1367 }); 1368 1369 if(searchHistoryData.length > 0){ 1370 // display the dropdown 1371 searchInput.classList.add('is-focus'); 1372 document.body.classList.add('search-input-focus'); 1373 searchDropdown.style.display = 'block'; 1374 } 1375 }); 1376 1377 searchInput.addEventListener("focusout", (event) => { 1378 var searchDropdown = searchInput.closest('form').querySelector('#searchDropdown'); 1379 searchInput.classList.remove('is-focus'); 1380 searchDropdown.classList.add('transparent'); 1381 setTimeout(()=>{ 1382 searchDropdown.style.display = 'none'; 1383 searchDropdown.classList.remove('transparent'); 1384 document.body.classList.remove('search-input-focus'); 1385 }, 400); 1386 }); 1387 }) 1388 } 1389 // End - search history dropdown 1390 1391 // referral notification popup 1392 const referralMessageTemplate = 'æ¨ç好å鿍 __CURRENCY_CODE__ __CREDIT_AMOUNT__ åé¥éï¼ç«å³è¨»åé åã'; 1393 const shopCurrency = 'NT$'; 1394 1395 function getCookie(name) { 1396 const value = `; ${document.cookie}`; 1397 const parts = value.split(`; ${name}=`); 1398 if (parts.length === 2) return parts.pop().split(';').shift(); 1399 return null; 1400 } 1401 1402 function removeCookie(name) { 1403 document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`; 1404 } 1405 1406 function showReferralNotification() { 1407 const referralCode = getCookie('customer_referral_code'); 1408 1409 1410 const customerReferralCode = null; 1411 1412 1413 const activeReferralCode = referralCode || customerReferralCode; 1414 const referralData = JSON.parse(localStorage.getItem('referral_notification_data')) || {}; 1415 1416 if (referralData.timestamp && referralData.expirationDays) { 1417 const expirationTime = referralData.timestamp + (referralData.expirationDays * 24 * 60 * 60 * 1000); 1418 if (Date.now() > expirationTime) { 1419 localStorage.removeItem('referral_notification_data'); 1420 return; 1421 } 1422 } 1423 1424 if (referralData.dismissed) return; 1425 1426 if (activeReferralCode) { 1427 if (referralData.creditAmount) { 1428 displayReferralNotification(referralData.creditAmount); 1429 } else { 1430 fetchReferralCampaignData(activeReferralCode); 1431 } 1432 } 1433 } 1434 1435 function fetchReferralCampaignData(referralCode) { 1436 fetch(`/customer/referral_program/campaigns/${referralCode}`) 1437 .then(response => { 1438 if (!response.ok) { 1439 throw new Error('Network response was not ok'); 1440 } 1441 return response.json(); 1442 }) 1443 .then(data => { 1444 let refereeCreditAmount = null; 1445 if (data.data.campaign && data.data.campaign.referral_rules) { 1446 const refereeRule = data.data.campaign.referral_rules.find(rule => 1447 rule.target_type === 'referee' && 1448 rule.event_name === 'customer/create' && 1449 rule.entitlement && 1450 rule.entitlement.type === 'credit' 1451 ); 1452 1453 if (refereeRule) { 1454 refereeCreditAmount = refereeRule.entitlement.amount; 1455 } 1456 } 1457 1458 const referralData = JSON.parse(localStorage.getItem('referral_notification_data')) || {}; 1459 referralData.creditAmount = refereeCreditAmount; 1460 referralData.dismissed = referralData.dismissed || false; 1461 referralData.timestamp = Date.now(); 1462 referralData.expirationDays = 3; 1463 localStorage.setItem('referral_notification_data', JSON.stringify(referralData)); 1464 1465 displayReferralNotification(refereeCreditAmount); 1466 }) 1467 .catch(error => { 1468 removeCookie('customer_referral_code'); 1469 }); 1470 } 1471 1472 function displayReferralNotification(creditAmount = null) { 1473 const isMobile = innerWidth <= 749; 1474 1475 if (isMobile) { 1476 const mobileModal = document.querySelector('#referralMobileModal details'); 1477 const mobileMessageElement = document.getElementById('referralSignupMessageMobile'); 1478 1479 if (mobileModal && mobileMessageElement) { 1480 if (creditAmount) {
1481 const finalMessage = referralMessageTemplate 1482 .replace('__CREDIT_AMOUNT__', creditAmount) 1483 .replace('__CURRENCY_CODE__', shopCurrency); 1484 1485 mobileMessageElement.textContent = finalMessage; 1486 } 1487 1488 mobileModal.setAttribute('open', ''); 1489 } 1490 } else { 1491 const notification = document.getElementById('referralNotification'); 1492 1493 if (notification) { 1494 if (creditAmount) { 1495 const messageElement = document.getElementById('referralSignupMessage'); 1496 if (messageElement) { 1497 const finalMessage = referralMessageTemplate 1498 .replace('__CREDIT_AMOUNT__', creditAmount) 1499 .replace('__CURRENCY_CODE__', shopCurrency); 1500 1501 messageElement.textContent = finalMessage; 1502 } 1503 } 1504 1505 notification.style.display = 'block'; 1506 } 1507 } 1508 } 1509 1510 showReferralNotification(); 1511 1512 addEventListener('beforeunload', function() { 1513 const referralData = JSON.parse(localStorage.getItem('referral_notification_data')) || {}; 1514 1515 if (referralData.creditAmount !== undefined) { 1516 referralData.creditAmount = null; 1517 localStorage.setItem('referral_notification_data', JSON.stringify(referralData)); 1518 } 1519 }); 1520 1521 function closeReferralNotification() { 1522 const notification = document.getElementById('referralNotification'); 1523 if (notification) { 1524 notification.style.display = 'none'; 1525 } 1526 } 1527 1528 function dismissReferralNotification() { 1529 const referralData = JSON.parse(localStorage.getItem('referral_notification_data')) || {}; 1530 1531 referralData.dismissed = true; 1532 referralData.timestamp = referralData.timestamp || Date.now(); 1533 referralData.expirationDays = referralData.expirationDays || 3; 1534 1535 localStorage.setItem('referral_notification_data', JSON.stringify(referralData)); 1536 1537 closeReferralNotification(); 1538 } 1539 1540 function goToSignupPage() { 1541 location.href = '/account/register'; 1542 dismissReferralNotification(); 1543 } 1544 1545 function closeMobileReferralModal() { 1546 const mobileModal = document.querySelector('#referralMobileModal details'); 1547 if (mobileModal) { 1548 mobileModal.removeAttribute('open'); 1549 } 1550 1551 const referralData = JSON.parse(localStorage.getItem('referral_notification_data')) || {}; 1552 referralData.dismissed = true; 1553 referralData.timestamp = referralData.timestamp || Date.now(); 1554 referralData.expirationDays = referralData.expirationDays || 3; 1555 localStorage.setItem('referral_notification_data', JSON.stringify(referralData)); 1556 } 1557 1558 function goToSignupPageFromMobile() { 1559 location.href = '/account/register'; 1560 closeMobileReferralModal(); 1561 } 1562 // End - referral notification popup 1563</script>
1563 1564 1565 1566 <main id="MainContent" class="content-for-layout focus-none" role="main" tabindex="-1">
vendor: 83 bytes, lines 1566-1569
1566 1567 1568 1569<script src="https://www.recaptcha.net/recaptcha/enterprise.js?render=
15696LdMNdIqAAAAALegJp7y4weVcCIlnwmIN8TWseEF
vendor: 12 bytes, line 1569
1569"></script>
1570<link rel="preload" href="https://store-themes.easystore.co/1318958/themes/310721/assets/customer.css?t=1790562592" as="style" onload="this.onload=null;this.rel='stylesheet'"> 1571<style> 1572 main.main-content .field > label{ 1573 display: none; 1574 } 1575 .h3{ 1576 font-size: 18px; 1577 } 1578 .button--full-width{ 1579 width: 100%; 1580 } 1581 .tab-wrapper{ 1582 display: inline-flex; 1583 justify-content: center; 1584 align-items: center; 1585 margin: 10px auto 20px; 1586 background-color: #eaeaea; 1587 border-radius: 200px; 1588 padding: 5px; 1589 gap: 10px; 1590 } 1591 .tab-wrapper .tab-label { 1592 display: inline-block; 1593 min-width: 130px; 1594 padding: 8px 15px; 1595 border-radius: 100px; 1596 cursor: pointer; 1597 font-size: 17px; 1598 line-height: 1.1; 1599 user-select: none; 1600 margin: 0; 1601 color: #000; 1602 } 1603 #register-tos a { 1604 display: inline; 1605 } 1606 @media screen and (max-width: 400px){ 1607 .tab-wrapper .tab-label { 1608 min-width: 110px; 1609 } 1610 } 1611 .tab-wrapper input[type='radio']:checked + .tab-label { 1612 background-color: #fff; 1613 box-shadow: 2px 2px 25px -10px #333; 1614 } 1615 1616 @media screen and (min-width: 500px){ 1617 .large--five-twelfths{ 1618 min-width: 420px; 1619 } 1620 } 1621</style> 1622 1623 1624 1625 1626<div class="customer login section-width-control small-width large--five-twelfths text-center wrapper"> 1627 <div class="card"> 1628 <h1 id="login" tabindex="-1" class="mb-0"> 1629 æ¡è¿ 1630 </h1> 1631 <p class="h3 mt-0"> 1632 1633 註åæç»å ¥ä»¥ç¹¼çº 1634 1635 </p> 1636 <div> 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 <div class="tab-wrapper"> 1655 <div> 1656 <input type="radio" name="type" id="tab-register" class="hide hidden" checked> 1657 <label for="tab-register" class="tab-label"> 1658 註å帳è 1659 </label> 1660 </div> 1661 <div> 1662 <input type="radio" name="type" id="tab-login" class="hide hidden"> 1663 <label for="tab-login" class="tab-label"> 1664 ç»å ¥ 1665 </label> 1666 </div> 1667 </div> 1668 1669 1670 <form id="form-login" action="/account/auth" method="post" class="mt-2"> 1671 <input type="hidden" name="_token" value="u4QpX2koqlBocy10ItIAH1w3EC4wC46C7jxeR0Zx"> 1672 <input type="hidden" name="location_id" value=""> 1673 <input type="hidden" name="staff_id" value=""> 1674 <input type="hidden" id="recaptchaResponse" name="g-recaptcha-response"> 1675 1676 1677 <div id="error-content"></div> 1678 1679 <div class="field"> 1680 <input 1681 type="text" 1682 name="customer[email_or_phone]" 1683 id="CustomerDetail" 1684 autocorrect="off" 1685 autocapitalize="off" 1686 placeholder="é»åéµä»¶å°å" 1687 required 1688 > 1689 <label for="CustomerDetail"> 1690 é»åéµä»¶å°å 1691 </label> 1692 </div> 1693 1694 <button 1695 type="submit" 1696 form="form-login" 1697 class="btn button--full-width g-recaptcha"> 1698 ç¹¼çº 1699 </button> 1700 1701 <div class="button-snippet"> 1702 1703<!-- Snippet:login/button: Facebook Login --> 1704 <style> 1705 #fb-login-btn.btn{ 1706 background-color: #fff; 1707 color: #000; 1708 padding: 0; 1709 overflow: hidden; 1710 display: flex; 1711 justify-content: center; 1712 align-items: center; 1713 width: 100%; 1714 margin: 15px auto; 1715 font-size: 14px; 1716 border: 1px solid currentColor; 1717 box-shadow: none; 1718 } 1719 #fb-login-btn.btn:hover{ 1720 background-color: #fff; 1721 } 1722 #fb-login-btn.btn svg{ 1723 width: 45px; 1724 vertical-align: middle; 1725 padding: 5px; 1726 } 1727 #fb-login-btn.btn .fb-login-text{ 1728 padding: 13px 75px 13px 30px; 1729 display: inline-block; 1730 width: calc(100% - 52px); 1731 } 1732 @media screen and (max-width: 500px) { 1733 #fb-login-btn.btn .fb-login-text{ 1734 padding: 13px 25px 13px 8px; 1735 font-size: 13px; 1736 } 1737 } 1738 </style> 1739 <button id="fb-login-btn" type="button" class="btn" onclick="fb_login()" style="background-color: #fff; color: #000; font-weight: normal;"> 1740 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 700 700"><g><path d="M650,350C650,184.32,515.68,50,350,50S50,184.32,50,350c0,140.69,96.86,258.74,227.53,291.17V441.68H215.66V350h61.87V310.5c0-102.11,46.2-149.44,146.4-149.44,19,0,51.81,3.72,65.22,7.45V251.6c-7.08-.74-19.38-1.12-34.65-1.12-49.2,0-68.2,18.64-68.2,67.08V350h98.1l-16.8,91.68H386.35V647.8C534.88,629.86,650,503.38,650,350Z" fill="#0866ff"/><path d="M467.5,441.68,484.4,350h-98V317.6c0-48.44,19-67.08,68.19-67.08,15.28,0,27.6.37,34.66,1.12V168.51c-13.42-3.73-46.21-7.45-65.22-7.45-100.25,0-146.4,47.33-146.4,149.44V350H2
174015.66v91.68h61.87V641.17a301.61,301.61,0,0,0,108.82,6.63V441.68Z" fill="#fff"/></g></svg> 1741 <span class="fb-login-text">以 Facebook 帳èç¹¼çº</span> 1742 </button> 1743 1744
1744<script> 1745 function fb_login(){ 1746 location.href = 'https://apps.easystore.co/facebook-login/run?domain='+window.location.protocol+'//'+window.location.hostname+'&shop=lijoe.easy.co'; 1747 } 1748 </script>
1748 1749<!-- /Snippet --> 1750 1751 <style> 1752 #line-login-btn.btn{ 1753 background-color: #fff; 1754 color: #000; 1755 padding: 0; 1756 overflow: hidden; 1757 display: flex; 1758 justify-content: center; 1759 align-items: center; 1760 width: 100%; 1761 margin: 15px auto; 1762 font-size: 14px; 1763 border: 1px solid currentColor; 1764 box-shadow: none; 1765 } 1766 #line-login-btn.btn:hover{ 1767 background-color: #fff; 1768 } 1769 #line-login-btn.btn svg{ 1770 width: 45px; 1771 vertical-align: middle; 1772 padding: 5px; 1773 } 1774 #line-login-btn.btn .line-login-text{ 1775 padding: 13px 75px 13px 30px; 1776 display: inline-block; 1777 width: calc(100% - 52px); 1778 } 1779 @media screen and (max-width: 500px) { 1780 #line-login-btn.btn .line-login-text{ 1781 padding: 13px 25px 13px 8px; 1782 font-size: 13px; 1783 } 1784 } 1785 </style> 1786 <button type="button" onclick="location.href='/account/oauth/line'" id="line-login-btn" class="btn" style="color: #000; font-weight: normal; margin-bottom: 10px;"> 1787 <svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30"> 1788 <path d="M27.91,12a8.73,8.73,0,0,0-.53-2,9.84,9.84,0,0,0-2.2-3.31A12.91,12.91,0,0,0,20.85,4a14.67,14.67,0,0,0-4-1A17.13,17.13,0,0,0,15,2.83c-.27,0-.55,0-.82,0l-.82.06a15.07,15.07,0,0,0-1.62.24,14.77,14.77,0,0,0-3,1A12.64,12.64,0,0,0,4.81,6.78a9.82,9.82,0,0,0-2.29,3.55A8.38,8.38,0,0,0,2,13a9.45,9.45,0,0,0,.1,1.5A8.52,8.52,0,0,0,2.88,17a10.52,10.52,0,0,0,3.23,3.84A13.68,13.68,0,0,0,10.5,23a14.8,14.8,0,0,0,2.36.5,2.31,2.31,0,0,1,.69.16,1,1,0,0,1,.58.72,2,2,0,0,1,0,.74c-.05.34-.12.67-.17,1a2.55,2.55,0,0,0,0,.55c0,.38.22.53.59.45a4.21,4.21,0,0,0,.63-.2A11.83,11.83,0,0,0,16.92,26a47.13,47.13,0,0,0,5.68-4c.67-.55,1.31-1.14,2-1.71a10.26,10.26,0,0,0,1.64-1.78,9.31,9.31,0,0,0,1.2-2.16,8.3,8.3,0,0,0,.59-3A9.5,9.5,0,0,0,27.91,12ZM10.26,16.52l-.18,0H7.49a.67.67,0,0,1-.67-.67v-5a.67.67,0,0,1,.66-.66.68.68,0,0,1,.71.7v4.26H10a.66.66,0,0,1,.6.31A.69.69,0,0,1,10.26,16.52Zm2.43-.58a.63.63,0,0,1-.63.6.65.65,0,0,1-.69-.46.89.89,0,0,1,0-.28V11a1.1,1.1,0,0,1,0-.26.68.68,0,0,1,.61-.48.64.64,0,0,1,.61.29.92.92,0,0,1,.11.29.72.72,0,0,1,0,.21v4.77A1,1,0,0,1,12.69,15.94Zm6.14,0a.64.64,0,0,1-.5.63.7.7,0,0,1-.76-.27C16.79,15.17,16,14.1,15.22,13c0,0-.06-.11-.16-.14v3a.6.6,0,0,1-.1.39.64.64,0,0,1-.52.3.79.79,0,0,1-.45-.11.66.66,0,0,1-.29-.52v-5a.67.67,0,0,1,.1-.39.7.7,0,0,1,1.14,0c.46.64.93,1.26,1.4,1.89l1,1.33.09.11c.06-.05,0-.1,0-.15V10.89a.65.65,0,0,1,.5-.65.67.67,0,0,1,.87.64v3.67C18.83,15,18.82,15.45,18.83,15.89Zm4.39.62a.93.93,0,0,1-.29,0H20.47a.76.76,0,0,1-.41-.1.62.62,0,0,1-.31-.51,1.09,1.09,0,0,1,0-.18c0-1.59,0-3.19,0-4.78a.88.88,0,0,1,0-.28.66.66,0,0,1,.63-.49H23a.63.63,0,0,1,.6.43.68.68,0,0,1-.16.76.58.58,0,0,1-.39.17H21.14a5.87,5.87,0,0,0,0,1.11h.17c.56,0,1.13,0,1.69,0a.64.64,0,0,1,.65.52.66.66,0,0,1-.66.84H21.14a6.56,6.56,0,0,0,0,1.09l.19,0h1.61a1,1,0,0,1,.24,0,.67.67,0,0,1,.5.63A.63.63,0,0,1,23.22,16.51Z" fill="#02C755"/> 1789 </svg> 1790 <span class="line-login-text">LINE ç»å ¥</span> 1791 </button> 1792 <!-- <p style="font-size: 12px; color: grey;">æåä½¿ç¨æ¨çLINEé»åéµä»¶åµå»ºå®¢æ¶å¸³æ¶</p> --> 1793 1794 </div> 1795 1796 1797 1798 <div id="register-tos"> 1799 䏿¦é»æè¨»åï¼å³è¡¨ç¤ºä½ åæLIJOE ç æåæ¢æ¬¾ã 1800 </div> 1801 1802 </form> 1803 </div> 1804 </div> 1805 1806</div> 1807 1808 1809
1810<script> 1811 const register_tab = document.querySelector('#tab-register'); 1812 const login_tab = document.querySelector('#tab-login'); 1813 const register_tos = document.querySelector('#register-tos'); 1814 const isRegistrationEnabled = "1"; 1815 1816 if (register_tab) { 1817 register_tab.addEventListener('click', function() { 1818 if (register_tos) { 1819 register_tos.style.display = 'block'; 1820 } 1821 }); 1822 } 1823 if (login_tab) { 1824 login_tab.addEventListener('click', function() { 1825 if (register_tos) { 1826 register_tos.style.display = 'none'; 1827 } 1828 }); 1829 } 1830 1831 const methodSwitchBtn = document.getElementById('phone-login-btn'); 1832 if (methodSwitchBtn) { 1833 methodSwitchBtn.onclick = function () { 1834 var type = (register_tab && register_tab.checked) ? 'register' : 'login'; 1835 window.location.href = '/account/login?method=phone&type=' + type; 1836 }; 1837 } 1838 1839 let lastPathSegment = window.location.pathname.split('/').filter(segment => segment.length > 0).pop(); 1840 1841 // Redirect to login if trying to access register when self registration is disabled 1842 if (!isRegistrationEnabled) { 1843 if (lastPathSegment === 'register') { 1844 window.location.href = '/account/login'; 1845 } else if (lastPathSegment === 'login' || lastPathSegment === 'auth') { 1846 if (register_tos) { 1847 register_tos.style.display = 'none'; 1848 } 1849 } 1850 } else { 1851 // Only proceed with tab logic if not redirecting 1852 if(lastPathSegment === 'login') { 1853 if (login_tab) { 1854 login_tab.checked = true; 1855 } 1856 if (register_tos) { 1857 register_tos.style.display = 'none'; 1858 } 1859 } else { 1860 if (register_tos) { 1861 register_tos.style.display = 'block'; 1862 } 1863 } 1864 } 1865 1866 const emailPattern = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/; 1867 const phonePattern = /^(?:\+?\d{1,3}[\s-]?)?(?:\d{1,14}[\s-]?){1,5}$/; 1868 1869 let form = document.querySelector('#form-login'), 1870 input = document.querySelector('#CustomerDetail'), 1871 error_content = document.querySelector('#error-content'); 1872 1873 1874 // One attempt at a time: the reCAPTCHA wait below is async, so without 1875 // this a double-click starts two continuations and posts the form twice. 1876 var submitting = false; 1877 1878 form.addEventListener('submit', async function (event) { 1879 // preventDefault FIRST: a re-entrant submit must still be cancelled, or the 1880 // browser performs a native post with no captcha token. 1881 event.preventDefault(); 1882 if (submitting) return; 1883 1884 let input_value = input.value 1885 error_content.innerHTML = ''; 1886 if (!input_value.match(emailPattern) && !input_value.match(phonePattern)) { 1887 error_content.innerHTML = `<div class="errors note">Invalid Email or Phone</div>`; 1888 return false; 1889 } 1890 1891 submitting = true; 1892 document.querySelector('#form-login .btn').classList.add('btn--loading','loading'); 1893 1894 // reCAPTCHA is unreachable from some regions (google.com is blocked in 1895 // mainland China). Fail open the same way checkout and forgot-password do: 1896 // submit without a token rather than leave the button spinning forever. 1897 try { 1898 if (window.grecaptcha && typeof window.grecaptcha.enterprise === 'object') { 1899 // The loader defines a stub {ready} synchronously and fetches the real 1900 // implementation asynchronously, so execute() may not exist yet. 1901 // ready() queues until it does; the timeout stops a bundle that never 1902 // arrives from hanging the button. 1903 await new Promise(function (resolve) { 1904 setTimeout(resolve, 3000); 1905 try { grecaptcha.enterprise.ready(resolve); } catch (e) { resolve(); } 1906 }); 1907 1908 const token = await grecaptcha.enterprise.execute('6LdMNdIqAAAAALegJp7y4weVcCIlnwmIN8TWseEF', { action: 'LOGIN' }); 1909 document.getElementById('recaptchaResponse').value = token; 1910 } 1911 } catch (e) { /* fail open */ } 1912 1913 document.getElementById('form-login').submit(); 1914 }); 1915 1916 1917</script>
1917 1918 1919 1920 </main> 1921 <style> 1922 .footer{ 1923 background-color: #eff6e7; 1924 color: #384d44; 1925 --color-foreground: 56,77,68; 1926 } 1927 .footer .link--text, 1928 .footer .list-menu__item--link, 1929 .footer .footer-block__details-content .list-menu__item--link{ 1930 color: #384d44; 1931 } 1932 .footer-block__heading{ 1933 color: #384d44; 1934 } 1935 .rounded{ 1936 border-radius: 10px; 1937 } 1938 .object-contain{ 1939 object-fit: contain; 1940 } 1941 .shopping-app-border{ 1942 border: 1px #ECECEC solid; 1943 margin-right: 3px; 1944 } 1945 .app-download-badge{ 1946 display: inline-block; 1947 margin-right: 3px; 1948 } 1949</style> 1950 1951<link rel="preload" href="https://store-themes.easystore.co/1318958/themes/310721/assets/section-footer.css?t=1790562592" as="style" onload="this.onload=null;this.rel='stylesheet'"> 1952 1953<footer class="footer color-background-1"> 1954 <div class="footer__content-top page-width"> 1955 <div class="grid grid--1-col grid--4-col-tablet "> 1956 1957 1958 1959 <div class="grid__item"> 1960 1961 <h2 class="footer-block__heading">Follow us</h2> 1962 <ul class="footer__list-social list-unstyled list-social footer-block__details-content" role="list"> 1963 1964 1965 <li class="list-social__item"> 1966 <a href="https://www.facebook.com/LIJOETAIWAN/" class="link link--text list-social__link"> 1967 1968 1969 1970 <svg aria-hidden="true" focusable="false" role="presentation" class="icon icon-facebook " 1971 viewBox="0 0 18 18"> 1972 <path fill="currentColor" 1973 d="M16.42.61c.27 0 .5.1.69.28.19.2.28.42.28.7v15.44c0 .27-.1.5-.28.69a.94.94 0 01-.7.28h-4.39v-6.7h2.25l.31-2.65h-2.56v-1.7c0-.4.1-.72.28-.93.18-.2.5-.32 1-.32h1.37V3.35c-.6-.06-1.27-.1-2.01-.1-1.01 0-1.83.3-2.45.9-.62.6-.93 1.44-.93 2.53v1.97H7.04v2.65h2.24V18H.98c-.28 0-.5-.1-.7-.28a.94.94 0 01-.28-.7V1.59c0-.27.1-.5.28-.69a.94.94 0 01.7-.28h15.44z"> 1974 </path> 1975 </svg> 1976 1977 1978 1979 </a> 1980 </li> 1981 1982 1983 <li class="list-social__item"> 1984 <a href="https://www.instagram.com/lijoe_taiwan/" class="link link--text list-social__link"> 1985 1986 1987 1988 <svg aria-hidden="true" focusable="false" role="presentation" class="icon icon-instagram " 1989 viewBox="0 0 18 18"> 1990 <path fill="currentColor" 1991 d="M8.77 1.58c2.34 0 2.62.01 3.54.05.86.04 1.32.18 1.63.3.41.17.7.35 1.01.66.3.3.5.6.65 1 .12.32.27.78.3 1.64.05.92.06 1.2.06 3.54s-.01 2.62-.05 3.54a4.79 4.79 0 01-.3 1.63c-.17.41-.35.7-.66 1.01-.3.3-.6.5-1.01.66-.31.12-.77.26-1.63.3-.92.04-1.2.05-3.54.05s-2.62 0-3.55-.05a4.79 4.79 0 01-1.62-.3c-.42-.16-.7-.35-1.01-.66-.31-.3-.5-.6-.66-1a4.87 4.87 0 01-.3-1.64c-.04-.92-.05-1.2-.05-3.54s0-2.62.05-3.54c.04-.86.18-1.32.3-1.63.16-.41.35-.7.66-1.01.3-.3.6-.5 1-.65.32-.12.78-.27 1.63-.3.93-.05 1.2-.06 3.55-.06zm0-1.58C6.39 0 6.09.01 5.15.05c-.93.04-1.57.2-2.13.4-.57.23-1.06.54-1.55 1.02C1 1.96.7 2.45.46 3.02c-.22.56-.37 1.2-.4 2.13C0 6.1 0 6.4 0 8.77s.01 2.68.05 3.61c.04.94.2 1.57.4 2.13.23.58.54 1.07 1.02 1.56.49.48.98.78 1.55 1.01.56.22 1.2.37 2.13.4.94.05 1.24.06 3.62.06 2.39 0 2.68-.01 3.62-.05.93-.04 1.57-.2 2.13-.41a4.27 4.27 0 001.55-1.01c.49-.49.79-.98 1.01-1.56.22-.55.37-1.19.41-2.13.04-.93.05-1.23.05-3.61 0-2.39 0-2.68-.05-3.62a6.47 6.47 0 00-.4-2.13 4.27 4.27 0 00-1.02-1.55A4.35 4.35 0 0014.52.46a6.43 6.43 0 00-2.13-.41A69 69 0 008.77 0z"> 1992 </path> 1993 <path fill="currentColor" 1994 d="M8.8 4a4.5 4.5 0 100 9 4.5 4.5 0 000-9zm0 7.43a2.92 2.92 0 110-5.85 2.92 2.92 0 010 5.85zM13.43 5a1.05 1.05 0 100-2.1 1.05 1.05 0 000 2.1z"> 1995 </path> 1996 </svg> 1997 1998 1999 2000 </a> 2001 </li> 2002 2003 2004 2005 2006 <li class="list-social__item"> 2007 <a href="https://lin.ee/5yLjhRc" class="link link--text list-social__link"> 2008 2009 2010 2011 <svg class="icon icon-line-footer " fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 750 750"><path d="M375,.5C168.17.5.5,168.17.5,375S168.17,749.5,375,749.5,749.5,581.83,749.5,375,581.83.5,375,.5ZM570.75,476.9
20111C518.48,537.06,401.6,610.33,375,621.53s-22.66-7.13-21.57-13.42c.63-3.76,3.55-21.33,3.55-21.33.83-6.36,1.66-16.23-.83-22.52-2.81-7-13.83-10.54-21.95-12.29C214.51,536.14,125.9,452.45,125.9,352.53,125.9,241,237.64,150.38,375,150.38s249.1,90.68,249.1,202.15h0C624.14,397.14,606.85,437.32,570.75,476.91Z"/><polygon points="324.38 298.65 324.38 298.65 324.38 298.65 324.38 298.65"/><path d="M324.38,298.65H306.91a4.86,4.86,0,0,0-4.86,4.85V412a4.86,4.86,0,0,0,4.86,4.85h17.47a4.86,4.86,0,0,0,4.85-4.85V303.5A4.86,4.86,0,0,0,324.38,298.65Z"/><path d="M444.67,298.65h-17.5a4.85,4.85,0,0,0-4.85,4.85V368l-49.73-67.17a4.57,4.57,0,0,0-.38-.49,2.76,2.76,0,0,0-.29-.3l-.09-.09a2.65,2.65,0,0,0-.26-.21l-.12-.1-.25-.18-.15-.08-.26-.14-.15-.08-.28-.12-.16,0-.28-.1-.18,0-.27-.06H351.08a4.85,4.85,0,0,0-4.85,4.84V412a4.85,4.85,0,0,0,4.85,4.85h17.48a4.85,4.85,0,0,0,4.85-4.85V347.54l49.81,67.26a5.15,5.15,0,0,0,1.22,1.2h.06l.29.18.14.07.24.12.23.1.15,0,.32.11H426a4.69,4.69,0,0,0,1.24.16h17.48a4.85,4.85,0,0,0,4.86-4.84h0V303.5A4.87,4.87,0,0,0,444.67,298.65Z"/><path d="M282.26,389.67h0l0,0H234.79V303.5a4.85,4.85,0,0,0-4.83-4.85H212.47a4.84,4.84,0,0,0-4.85,4.84h0V412a4.74,4.74,0,0,0,1.35,3.32.27.27,0,0,0,.07.08l.07.07a4.81,4.81,0,0,0,3.33,1.35h69.81a4.84,4.84,0,0,0,4.84-4.84h0V394.52A4.84,4.84,0,0,0,282.26,389.67Z"/><path d="M541.16,371.34a4.85,4.85,0,0,0,4.85-4.85h0V349a4.85,4.85,0,0,0-4.84-4.85H493.72V325.84l47.42,0A4.83,4.83,0,0,0,546,321V303.5a4.85,4.85,0,0,0-4.84-4.86H471.34A4.81,4.81,0,0,0,468,300l-.05.05-.08.09a4.82,4.82,0,0,0-1.34,3.33V412a4.77,4.77,0,0,0,1.35,3.33l.07.07.07.07a4.8,4.8,0,0,0,3.32,1.36h69.81A4.85,4.85,0,0,0,546,412h0V394.5a4.85,4.85,0,0,0-4.84-4.85H493.72V371.34Z"/></svg> 2012 2013 2014 2015 </a> 2016 </li> 2017 2018 2019 2020 <li class="list-social__item"> 2021 <a href="https://www.youtube.com/@LIJOE283" class="link link--text list-social__link"> 2022 2023 2024 2025 <svg aria-hidden="true" focusable="false" role="presentation" class="icon icon-youtube " 2026 viewBox="0 0 100 70"> 2027 <path 2028 d="M98 11c2 7.7 2 24 2 24s0 16.3-2 24a12.5 12.5 0 01-9 9c-7.7 2-39 2-39 2s-31.3 0-39-2a12.5 12.5 0 01-9-9c-2-7.7-2-24-2-24s0-16.3 2-24c1.2-4.4 4.6-7.8 9-9 7.7-2 39-2 39-2s31.3 0 39 2c4.4 1.2 7.8 4.6 9 9zM40 50l26-15-26-15v30z" 2029 fill="currentColor"> 2030 </path> 2031 </svg> 2032 2033 2034 2035 </a> 2036 </li> 2037 2038 2039 </ul> 2040 2041 </div> 2042 2043 2044 2045 <div class="grid__item"> 2046 2047 <h2 class="footer-block__heading">Service Hours</h2> 2048 <div class="footer-block__details-content"> 2049 <p>Monday - Friday / 09:00 - 18:00</p> 2050 </div> 2051 2052 </div> 2053 2054 2055 2056 <div class="grid__item"> 2057 2058 <h2 class="footer-block__heading">Payment methods</h2> 2059 <div class="footer-block__details-content footer__payment"> 2060 <ul class="list list-payment" role="list"> 2061 2062 <li class="list-payment__item"> 2063 2064 2065 2066 <svg class="icon icon--full-color " viewBox="0 0 38 24" xmlns="http://www.w3.org/2000/svg" role="img" 2067 width="38" height="24" aria-labelledby="pi-visa"> 2068 <path opacity=".07" 2069 d="M35 0H3C1.3 0 0 1.3 0 3v18c0 1.7 1.4 3 3 3h32c1.7 0 3-1.3 3-3V3c0-1.7-1.4-3-3-3z"></path> 2070 <path fill="#fff" d="M35 1c1.1 0 2 .9 2 2v18c0 1.1-.9 2-2 2H3c-1.1 0-2-.9-2-2V3c0-1.1.9-2 2-2h32"> 2071 </path> 2072 <path 2073 d="M28.3 10.1H28c-.4 1-.7 1.5-1 3h1.9c-.3-1.5-.3-2.2-.6-3zm2.9 5.9h-1.7c-.1 0-.1 0-.2-.1l-.2-.9-.1-.2h-2.4c-.1 0-.2 0-.2.2l-.3.9c0 .1-.1.1-.1.1h-2.1l.2-.5L27 8.7c0-.5.3-.7.8-.7h1.5c.1 0 .2 0 .2.2l1.4 6.5c.1.4.2.7.2 1.1.1.1.1.1.1.2zm-13.4-.3l.4-1.8c.1 0 .2.1.2.1.7.3 1.4.5 2.1.4.2 0 .5-.1.7-.2.5-.2.5-.7.1-1.1-.2-.2-.5-.3-.8-.5-.4-.2-.8-.4-1.1-.7-1.2-1-.8-2.4-.1-3.1.6-.4.9-.8 1.7-.8 1.2 0 2.5 0 3.1.2h.1c-.1.6-.2 1.1-.4 1.7-.5-.2-1-.4-1.5-.4-.3 0-.6 0-.9.1-.2 0-.3.1-.4.2-.2.2-.2.5 0 .7l.5.4c.4.2.8.4 1.1.6.5.3 1 .8 1.1 1.4.2.9-.1 1.7-.9 2.3-.5.4-.7.6-1.4.6-1.4 0-2.5.1-3.4-.2-.1.2-.1.2-.2.1zm-3.5.3c.1-.7.1-.7.2-1 .5-2.2 1-4.5 1.4-6.7.
20731-.2.1-.3.3-.3H18c-.2 1.2-.4 2.1-.7 3.2-.3 1.5-.6 3-1 4.5 0 .2-.1.2-.3.2M5 8.2c0-.1.2-.2.3-.2h3.4c.5 0 .9.3 1 .8l.9 4.4c0 .1 0 .1.1.2 0-.1.1-.1.1-.1l2.1-5.1c-.1-.1 0-.2.1-.2h2.1c0 .1 0 .1-.1.2l-3.1 7.3c-.1.2-.1.3-.2.4-.1.1-.3 0-.5 0H9.7c-.1 0-.2 0-.2-.2L7.9 9.5c-.2-.2-.5-.5-.9-.6-.6-.3-1.7-.5-1.9-.5L5 8.2z" 2074 fill="#142688"></path> 2075 </svg> 2076 2077 2078 2079 </li> 2080 2081 2082 <li class="list-payment__item"> 2083 2084 2085 2086 <svg class="icon icon--full-color " viewBox="0 0 38 24" xmlns="http://www.w3.org/2000/svg" role="img" 2087 width="38" height="24" aria-labelledby="pi-master"> 2088 <path opacity=".07" 2089 d="M35 0H3C1.3 0 0 1.3 0 3v18c0 1.7 1.4 3 3 3h32c1.7 0 3-1.3 3-3V3c0-1.7-1.4-3-3-3z"></path> 2090 <path fill="#fff" d="M35 1c1.1 0 2 .9 2 2v18c0 1.1-.9 2-2 2H3c-1.1 0-2-.9-2-2V3c0-1.1.9-2 2-2h32"> 2091 </path> 2092 <circle fill="#EB001B" cx="15" cy="12" r="7"></circle> 2093 <circle fill="#F79E1B" cx="23" cy="12" r="7"></circle> 2094 <path fill="#FF5F00" 2095 d="M22 12c0-2.4-1.2-4.5-3-5.7-1.8 1.3-3 3.4-3 5.7s1.2 4.5 3 5.7c1.8-1.2 3-3.3 3-5.7z"></path> 2096 </svg> 2097 2098 2099 2100 </li> 2101 2102 2103 2104 2105 2106 2107 2108 <li class="list-payment__item"> 2109 <img src="https://s3.dualstack.ap-southeast-1.amazonaws.com/eesb.public/images/payment/payments_ecpay.svg" alt="payment_ecpay" loading="lazy" width="85px"> 2110 </li> 2111 2112 2113 </div> 2114 <br> 2115 2116 </div> 2117 2118 </div> 2119 </div> 2120 <div class="footer__content-bottom"> 2121 <div class="footer__content-bottom-wrapper page-width"> 2122 <div class="footer__column footer__column--info"> 2123 2124 2125 2126 2127 2128 <div class="footer__copyright caption"> 2129 <div class="copyright__content">LIJOEï½éºæåéè¡ä»½æéå ¬å¸</div> 2130 </div> 2131 2132 <div class="footer__copyright caption"> 2133 2134 </div> 2135 2136 </div> 2137 </div> 2138 </div> 2139</footer> 2140 2141 2142 2143 2144 2145 2146
2146<script> 2147 EasyStore.Currencies.init([{"name":"New Taiwan Dollar","code":"TWD","rate":"1.0","format_prefix":"NT$","format_suffix":null,"format_decimals":0,"thousand_separator":",","is_primary":true}], 1) 2148</script>
2148 2149 2150 2151 2152
2152<script> 2153 let page_template = 'customers'; 2154 2155 if(document.querySelector('.currency-picker')) { 2156 EasyStore.Currencies.change(document.querySelector('.currency-picker').value) 2157 EasyStore.Currencies.convertAll() 2158 } 2159 2160 document.querySelectorAll('.currency-picker').forEach((el)=>{ 2161 el.addEventListener('change',(event)=>{ 2162 EasyStore.Currencies.change(event.target.value) 2163 2164 2165 if (page_template == 'cart') { 2166 const params = new URLSearchParams(window.location.search); 2167 params.set('delete_cache', 1); 2168 window.location.search = params; 2169 } else { 2170 window.location.reload(); 2171 } 2172 2173 return 2174 2175 2176 document.querySelectorAll('[name=currencies],[name=current_currency]').forEach((el)=>{ 2177 el.value = event.target.value 2178 }) 2179 2180 if(page_template == 'cart') location.reload(); 2181 }) 2182 }) 2183 </script>
2183 2184 2185 2186 2187 2188
2188<script> 2189 2190 window.variantStrings = { 2191 addToCart: `å å ¥è³¼ç©è»`, 2192 updateCart: `æ´æ°è³¼ç©è»`, 2193 soldOut: `<span style='font-size:14px;'>å®å®</span>`, 2194 unavailable: `æ«ç¡ä¾æ`, 2195 } 2196 2197 window.accessibilityStrings = { 2198 shareSuccess: `éæ¥å·²å¾©è£½å°åªè²¼æ¿`, 2199 } 2200 2201 window.promotionStrings = { 2202 title: `é©ç¨åªæ `, 2203 } 2204 2205 window.productSettings = { 2206 variantOptionsDisplay: `radio-img`, 2207 } 2208 </script>
2208 2209 2210 <link href="https://store-themes.easystore.co/1318958/themes/310721/assets/section-main-product.css?t=1790562592" rel="stylesheet" type="text/css" media="screen" /> 2211<link href="https://store-themes.easystore.co/1318958/themes/310721/assets/component-loading-overlay.css?t=1790562592" rel="stylesheet" type="text/css" media="screen" /> 2212<link href="https://store-themes.easystore.co/1318958/themes/310721/assets/product-quickview.css?t=1790562592" rel="stylesheet" type="text/css" media="screen" /> 2213 2214<product-quickview-modal> 2215 <div id="product-quickview-modal" class="product-quickview-modal-wrapper focus-inset" aria-modal="true" role="dialog" tabindex="-1"> 2216 <button type="button" class="product-quickview-modal__close modal__close-button link link--text focus-inset" aria-label="accessibility.close"> 2217 2218 2219 2220 <svg class="icon icon-close " data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600"><path d="M335.36,300,581.87,53.48a25,25,0,0,0-35.35-35.35L300,264.64,53.48,18.13A25,25,0,0,0,18.13,53.48L264.64,300,18.13,546.52a25,25,0,0,0,35.35,35.35L300,335.36,546.52,581.87a25,25,0,0,0,35.35-35.35Z" fill="currentColor"/></svg> 2221 2222 2223 2224 </button> 2225 2226 <div class="loading-overlay"> 2227 <div class="loading-overlay__spinner"> 2228 <svg aria-hidden="true" focusable="false" role="presentation" class="spinner" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg"> 2229 <circle class="path" fill="none" stroke-width="6" cx="33" cy="33" r="30"></circle> 2230 </svg> 2231 </div> 2232 </div> 2233 2234 <div class="product-quickview-modal__body" style="display: none;"></div> 2235 </div> 2236 <div class="product-quickview-modal-backdrop"></div> 2237</product-quickview-modal> 2238
2239<script src="https://store-themes.easystore.co/1318958/themes/310721/assets/product-form.js?t=1790562592" type="text/javascript" ></script>
vendor: 1 bytes, line 2239
2239
2240<script src="https://store-themes.easystore.co/1318958/themes/310721/assets/product-quickview.js?t=1790562592" type="text/javascript" ></script>
2240 2241
2241<script> 2242 2243 /* 2244 2245 ------ 2246 Events 2247 ------ 2248 2249 pages/viewed 2250 2251 customers/signup 2252 2253 customers/login 2254 2255 products/searched 2256 2257 collections/viewed 2258 2259 products/viewed 2260 2261 products/shared 2262 2263 wishlists/item_added 2264 2265 carts/items_added 2266 2267 carts/viewed 2268 2269 carts/item_removed 2270 2271 checkouts/initiated 2272 2273 checkouts/shipping_info_added 2274 2275 checkouts/payment_info_added 2276 2277 checkouts/completed 2278 2279 orders/placed 2280 2281 orders/purchased 2282 2283 payments/captured 2284 2285 payments/failed 2286 2287 */ 2288 2289 window.__latest_cart = window.__latest_cart || null; 2290 2291 const _selector = document.querySelector.bind(document), 2292 _selectorAll = document.querySelectorAll.bind(document) 2293 2294 document.addEventListener('DOMContentLoaded', (event) => { 2295 2296 const default_currency = getCookie("currency") 2297 const customer_id = window.__st.cid 2298 const template = window.__st.p 2299 2300 onPageView() 2301 2302 //-----------------------// 2303 // Configs // 2304 //-----------------------// 2305 2306 window.dataLayer = window.dataLayer || [] 2307 2308 Array.prototype.last = Array.prototype.last || function() { 2309 return this[this.length - 1] || null 2310 } 2311 2312 Array.prototype.first = Array.prototype.first || function() { 2313 return this[0] || null 2314 } 2315 2316 //----------------------// 2317 // Triggers // 2318 //----------------------// 2319 2320 const XHR = window.XMLHttpRequest 2321 2322 function xhr() { 2323 2324 const xhr = new XHR() 2325 2326 xhr.addEventListener("readystatechange", function() { 2327 2328 if(xhr.readyState != 4) return 2329 2330 try { 2331 2332 const response_url = xhr.responseURL 2333 2334 if (response_url.includes("cart/add")) { 2335 2336 window.__latest_cart = JSON.parse(xhr.response) 2337 2338 onCartItemsAdded() // ok 2339 2340 } 2341 2342 if (response_url.includes("cart/remove_item_quantity")) { 2343 2344 window.__latest_cart = JSON.parse(xhr.response) 2345 2346 onCartItemRemoved() // ok 2347 2348 } 2349 2350 if (response_url.includes("new_cart?retrieve=true")) { 2351 2352 result = JSON.parse(xhr.response) 2353 2354 if (result.cart) { 2355 window.__latest_cart = result.cart 2356 } 2357 2358 } 2359 2360 } catch(e) { 2361 2362 console.error(e) 2363 2364 } 2365 2366 }, false); 2367 2368 return xhr 2369 2370 } 2371 2372 window.XMLHttpRequest = xhr 2373 2374 switch(template) { 2375 2376 case 'cart': onCartView() // ok 2377 break 2378 case 'product': onProductView() // ok 2379 break 2380 case 'collection': onCollectionView() // ok 2381 break 2382 case 'blog': onBlogView() 2383 break 2384 case 'article': onArticleView() 2385 break 2386 case 'payment_completed': onOrderPlace() 2387 break 2388 case 'payment_fail': onPaymentFail() 2389 break 2390 2391 } 2392 2393 // _selector('form[action="/checkout/payments"]').addEventListener("submit", onPaymentInfoAdded(_selector('form[action="/checkout/payments"]'))) 2394 if (_selector('form[action="/checkout/detail"]')) _selector('form[action="/checkout/detail"]').addEventListener("submit", ()=>{onShippingInfoAdded(_selector('form[action="/checkout/detail"]'))}) // ok 2395 if (_selector('form[action="/checkout/shipping"]')) _selector('form[action="/checkout/shipping"]').addEventListener("submit", ()=>{onShippingInfoAdded(_selector('form[action="/checkout/shipping"]'))}) // ok 2396 if (_selector('form[action="/account/register"]')) _selector('form[action="/account/register"]').addEventListener("submit", onSignUp) // ok 2397 if (_selector('form[action="/account/login"]')) _selector('form[action="/account/login"]').addEventListener("submit", onLogin) // ok 2398 if (_selector('form[action="/search"]')) _selector('form[action="/search"]').addEventListener("submit", onProductSearch()) // ok 2399 if (_selector('#line-login-btn')) _selector('#line-login-btn').addEventListener('click', onLineLogin) // ok 2400 if (_selector('#PlaceOrder')) _selector('#PlaceOrder').addEventListener("click", ()=>{onCheckoutComplete(_selector('form[action="/checkout/payments"]'))}); // ok 2401 if (_selector('#add_wishlist')) _selector('#add_wishlist').addEventListener("click", onWishlistItemAdded) // ok 2402 if (_selectorAll('a[href="/account/logout"]')) _selectorAll('a[href="/account/logout"]').forEach(logoutButton => logoutButton.addEventListener("click", onLogout)) // ok 2403 if (_selector('.CartDrawerTrigger.cart-page-link')) _selector('.CartDrawerTrigger.cart-page-link').addEventListener("click", onCartView) // ok 2404 if (_selector('.CartDrawerTrigger.cart-page-link.mobile-cart-page-link')) _selector('.CartDrawerTrigger.cart-page-link.mobile-cart-page-link').addEventListener("click", onCartView) // ok 2405 if (_selectorAll('a[class^="share-"]')) _selectorAll('a[class^="share-"]').forEach(shareButton => shareButton.addEventListener("click", ()=>{onProductShare(shareButton)}) ) // ok 2406 if (_selectorAll('[name$="checkout"]')) _selectorAll('[name$="checkout"]').forEach(checkoutButton => checkoutButton.addEventListener("click", onCheckoutInitiate)) 2407 2408 // For append elements 2409 const bodyMutationObserver = new MutationObserver(() => { 2410 if (_selector('#form__spc #PlaceOrder')) _selector('#form__spc #PlaceOrder').addEventListener("click", onSinglePageCheckout) // ok 2411 if (_selectorAll('[name$="checkout"]')) _selectorAll('[name$="checkout"]').forEach(checkoutButton => checkoutButton.addEventListener("click", onCheckoutInitiate)) 2412 }); 2413 bodyMutationObserver.observe(_selector("body"), {subtree: true, childList: true}); 2414 2415 //------------------------------// 2416 // Event handlers // 2417 //------------------------------// 2418 2419 function onPageView() { 2420 2421 EasyStore.Event.dispatch('pages/viewed', { 2422 page: { 2423 type: template, 2424 title: document.title, 2425 description: _selector('meta[name=description]') ? _selector('meta[name=description]').getAttribute('content') : null, 2426 url: location.href, 2427 } 2428 }) 2429 2430 } 2431 2432 function onSignUp() { 2433 2434 const email_regex = new RegExp(/^[a-zA-Z0-9.!#$%&"*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/) 2435 const phone_regex = new RegExp(/^(\+?6?01)[0-46-9]-*[0-9]{7,8}$/) 2436 2437 const email_or_phone = _selector(`input[name="customer[email_or_phone]"]`).value.replace("+", "").replace(/\s+/, "") 2438 2439 let data = {} 2440 2441 if (email_regex.test(email_or_phone)) { 2442 data.method = 'email' 2443 data.email = email_or_phone 2444 } 2445 2446 if (phone_regex.test(email_or_phone)) { 2447 data.method = "phone" 2448 data.phone = email_or_phone 2449 } 2450 2451 if (!data.method) return 2452 2453 EasyStore.Event.dispatch('customers/signup', data) 2454 2455 } 2456 2457 function onLogin() { 2458 2459 const email_regex = new RegExp(/^[a-zA-Z0-9.!#$%&"*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/) 2460 const phone_regex = new RegExp(/^(\+?6?01)[0-46-9]-*[0-9]{7,8}$/) 2461 2462 const email_or_phone = _selector(`input[name="customer[email_or_phone]"]`).value.replace("+", "").replace(/\s+/, "") 2463 2464 let data = {} 2465 2466 if (email_regex.test(email_or_phone)) { 2467 data.method = 'email' 2468 data.email = email_or_phone 2469 } 2470 2471 if (phone_regex.test(email_or_phone)) { 2472 data.method = "phone" 2473 data.phone = email_or_phone 2474 } 2475 2476 if (!data.method) return 2477 2478 EasyStore.Event.dispatch('customers/login', data) 2479 2480 } 2481 2482 function onLineLogin() { 2483 2484 EasyStore.Event.dispatch('customers/login', { method: 'line' }) 2485 2486 } 2487 2488 function onLogout() { 2489 2490 EasyStore.Event.dispatch('customers/logout', { customer_id }) 2491 2492 } 2493 2494 function onBlogView() { 2495 2496 const blog = "" 2497 2498 EasyStore.Event.dispatch('blogs/viewed', { blog }) 2499 2500 } 2501 2502 function onArticleView() { 2503 2504 const article = "" 2505 2506 EasyStore.Event.dispatch('articles/viewed', { article }) 2507 2508 } 2509 2510 function onProductSearch() { 2511 2512 const query = _selector('input[name=q]').value 2513 2514 if (!query) return 2515 2516 EasyStore.Event.dispatch('products/searched', { query }) 2517 2518 } 2519 2520 function onCollectionView() { 2521 2522 const collection = "" 2523 2524 EasyStore.Event.dispatch('collections/viewed', { collection }) 2525 2526 } 2527 2528 function onProductView() { 2529 2530 const product = "" 2531 2532 EasyStore.Event.dispatch("products/viewed", { product }) 2533 2534 } 2535 2536 function onProductShare(el) { 2537 2538 const product = "" 2539 2540 const channel = el.getAttribute("class").split("-").last() 2541 2542 EasyStore.Event.dispatch('products/shared', { product, channel }) 2543 2544 } 2545 2546 function onWishlistItemAdded() { 2547 2548 let product = "" 2549 const quantity = _selector("#Quantity").value 2550 2551 EasyStore.Event.dispatch('wishlists/item_added', { product }) 2552 2553 } 2554 2555 async function onCartItemsAdded() { 2556 2557 const cart = await getCart() 2558 2559 if(cart && cart.items != undefined && cart.items.length > 0) { 2560 2561 EasyStore.Event.dispatch('carts/item_added', { cart }) 2562 2563 } 2564 2565 } 2566 2567 async function onCartView() { 2568 2569 const cart = await getCart() 2570 2571 EasyStore.Event.dispatch('carts/viewed', { cart }) 2572 2573 } 2574 2575 async function onCartItemRemoved() { 2576 2577 const cart = await getCart() 2578 2579 cart.items = [] 2580 2581 if(cart) { 2582 2583 EasyStore.Event.dispatch('carts/item_removed', { cart }) 2584 2585 } 2586 2587 } 2588 2589 async function onCheckoutInitiate() { 2590 2591 const cart = await getCart() 2592 2593 EasyStore.Event.dispatch('checkouts/initiated', { cart }) 2594 2595 } 2596 2597 async function onShippingInfoAdded(form) { 2598 let checkout = getCheckout() 2599 2600 let form_data = {} 2601 new FormData(form).forEach((value, key) => form_data[key] = value) 2602 2603 let shipping_tier = null 2604 2605 if (form_data.type && form_data.type.startsWith("r_pickup")) { 2606 shipping_tier = `Pickup - ${form_data.pick_location}` 2607 } 2608 2609 if (form_data.s_id) {
2610 shipping_tier = _selector(`input[id='`+form_data.s_id+`']`).getAttribute("data-shipping-name") 2611 } 2612 2613 if (!shipping_tier) return 2614 2615 EasyStore.Event.dispatch('checkouts/shipping_info_added', { checkout, shipping_tier }) 2616 2617 } 2618 2619 async function onPaymentInfoAdded(form) { 2620 2621 let checkout = getCheckout() 2622 2623 let payment_type = new FormData(form).get('payment_method') 2624 2625 EasyStore.Event.dispatch("checkouts/payment_info_added", { checkout, payment_type }) 2626 2627 } 2628 2629 async function onOrderPlace() { 2630 2631 let cart_token = getCookie("cart_js") 2632 let previous_cart_token = getCookie("previous_cart_ga4_js") 2633 2634 if (previous_cart_token && previous_cart_token == cart_token) { 2635 // Prevent duplicate purchase tracking 2636 return 2637 } 2638 2639 let order = getOrder() 2640 2641 EasyStore.Event.dispatch('orders/placed', { order }) 2642 2643 if(order.is_manual_payment) { 2644 2645 EasyStore.Event.dispatch('orders/purchased', { order }) 2646 2647 } 2648 2649 const last_transaction = order.transactions.last() 2650 2651 if (last_transaction.status) { 2652 2653 EasyStore.Event.dispatch('orders/purchased', { order }) 2654 EasyStore.Event.dispatch('payments/captured', { order }) 2655 2656 } 2657 2658 } 2659 2660 async function onPaymentFail() { 2661 2662 const order = getOrder() 2663 2664 EasyStore.Event.dispatch('payments/failed', { order }) 2665 2666 } 2667 2668 async function onCheckoutComplete(form) { 2669 2670 onPaymentInfoAdded(form) 2671 2672 const checkout = getCheckout() 2673 2674 EasyStore.Event.dispatch('checkouts/completed', { checkout }) 2675 2676 } 2677 2678 async function onSinglePageCheckout() { 2679 2680 // let checkout = $("[data-app-checkout]").data("app-checkout") 2681 2682 let checkout = getCheckout() 2683 2684 // const payment_type = _selector("#app_spc_payment_method").find(`[class*="label-content"]`).first().find("b").first().text() 2685 const payment_type = _selector("#app_spc_payment_method").getElementsByClassName('label-content')[0].getElementsByTagName('b')[0].innerHTML 2686 2687 const shipping_method = _selector("#delivery_method").value 2688 2689 let shipping_tier = null 2690 let app_spc_customer_info_label = _selector("#app_spc_customer_info").getElementsByClassName('label-content') 2691 if (shipping_method == "shipping") { 2692 shipping_tier = app_spc_customer_info_label[app_spc_customer_info_label.length - 1].getElementsByTagName('b')[0].innerHTML 2693 } 2694 2695 if (shipping_method == "pickup") { 2696 shipping_tier = app_spc_customer_info_label[0].innerHTML 2697 } 2698 2699 if (shipping_tier) { 2700 2701 EasyStore.Event.dispatch('checkouts/shipping_info_added', { 2702 checkout, 2703 shipping_tier, 2704 }) 2705 2706 } 2707 2708 if (payment_type) { 2709 2710 EasyStore.Event.dispatch('checkouts/payment_info_added', { 2711 checkout, 2712 payment_type, 2713 }) 2714 2715 } 2716 2717 EasyStore.Event.dispatch('checkouts/completed', { checkout }) 2718 2719 } 2720 2721 }) 2722 2723 2724 //-----------------------// 2725 // Functions // 2726 //-----------------------// 2727 2728 function getCookie(name) { 2729 2730 name += "=" 2731 2732 decodedCookie = decodeURIComponent(document.cookie) 2733 2734 ca = decodedCookie.split(";") 2735 2736 for(i = 0; i < ca.length; i++) { 2737 c = ca[i] 2738 while (c.charAt(0) == " ") { 2739 c = c.substring(1) 2740 } 2741 if (c.indexOf(name) == 0) { 2742 return c.substring(name.length, c.length) 2743 } 2744 } 2745 2746 return "" 2747 2748 } 2749 2750 const parsePrice = price => { 2751 if(typeof price === 'string') { 2752 return parseFloat(price.split(',').join('')) 2753 } 2754 2755 return price 2756 } 2757 2758 const requestCart = async (method, data) => { 2759 2760 let response = await fetch('/cart.json', {method: 'GET',headers: {'Content-Type': 'application/json'}}) 2761 result = await response.json() 2762 2763 return result.cart 2764 2765 } 2766 const getCart = async (latest = false) => { 2767 2768 let cart = window.__latest_cart 2769 2770 const cart_invalid = !cart || !cart.items || (cart.total_price > 0 && !cart.items.length) 2771 2772 if(latest || cart_invalid) { 2773 cart = await requestCart() 2774 } 2775 2776 cart.items = cart.items || [] 2777 2778 return mapCart(cart) 2779 2780 } 2781 2782 const getCheckout = async () => { 2783 mapCheckout(window.__latest_cart || await requestCart()) 2784 } 2785 2786 const getOrder = async () => { 2787 mapOrder(window.__latest_cart || await requestCart()) 2788 } 2789 2790 //-----------------------// 2791 // Mappers // 2792 //-----------------------// 2793 2794 const fallbackAttribute = (object, attribute) => { 2795 2796 if(!Array.isArray(attribute)) { 2797 attribute = [attribute] 2798 } 2799 2800 let final_value = null 2801 2802 do { 2803 2804 final_value = object[attribute.shift()] 2805 2806 } while(!final_value && attribute.length) 2807 2808 return final_value 2809 2810 } 2811 2812 const map = (object, mapper) => { 2813 2814 const newObject = {} 2815 2816 for(const key in mapper) { 2817 2818 // Handle different keys between new and old format
2819 newObject[key] = fallbackAttribute(object, mapper[key]) 2820 2821 // Cast price to float 2822 if(newObject[key] && ['price', 'amount', 'discount', 'discounts'].some(x => key.endsWith(x))) { 2823 newObject[key] = parsePrice(newObject[key]) 2824 } 2825 2826 if(newObject[key] === undefined) { 2827 delete newObject[key] 2828 } 2829 2830 } 2831 2832 return newObject 2833 2834 } 2835 2836 const mapCart = cart => { 2837 2838 const oldCart = cart 2839 2840 const mapper = { 2841 id: 'id', 2842 currency: 'currency', 2843 item_count: 'item_count', 2844 items: 'items', 2845 total_price: 'total_price', 2846 latest_items: 'latest_items' 2847 } 2848 2849 cart = map(cart, mapper) 2850 2851 const discounts = (oldCart.storewide_discounts || []).concat((oldCart.voucher_discounts || [])) 2852 2853 cart.discount_applications = discounts.map(discount => ({ 2854 title: discount.voucher_code || null, 2855 value: parsePrice(discount.amount), 2856 })) 2857 2858 cart.original_total_price = cart.items.length 2859 ? cart.items 2860 .map(item => item.original_price) 2861 .reduce((sum, price) => sum + price) 2862 : 0 2863 2864 cart.total_discount = cart.discount_applications.length 2865 ? cart.discount_applications 2866 .map(discount => parsePrice(discount.value)) 2867 .reduce((sum, value) => sum + value) 2868 : 0 2869 2870 cart.items = cart.items.map(item => mapLineItem(item)) 2871 2872 return cart 2873 2874 } 2875 2876 const mapCheckout = checkout => { 2877 2878 const mapper = { 2879 note: 'note', 2880 attributes: 'note_attributes', 2881 billing_address: 'billing_address', 2882 currency: 'currency', 2883 customer_id: 'customer_id', 2884 discounts_amount: 'total_discount', 2885 id: 'id', 2886 line_items: 'order_item', 2887 order_number: 'order_number', 2888 shipping_address: 'shipping_address', 2889 shipping_price: 'shipping_tax', 2890 shipping_method: 'shipping_method_name', 2891 tax_price: 'total_tax', 2892 } 2893 2894 checkout = map(checkout, mapper) 2895 2896 checkout.requires_shipping = checkout.line_items.some(item => item.shipping_required) 2897 2898 checkout.line_items = checkout.line_items.map(item => mapLineItem(item)) 2899 2900 return checkout 2901 2902 } 2903 2904 const mapOrder = order => { 2905 2906 const mapper = { 2907 attributes: 'note_attributes', 2908 billing_address: 'billing_address', 2909 cancelled: 'is_cancelled', 2910 cancelled_at: 'cancelled_at', 2911 created_at: 'created_at', 2912 customer_id: 'customer_id', 2913 // discount_applications: 'discount_applications', 2914 email: 'email', 2915 financial_status: 'financial_status', 2916 fulfillment_status: 'fulfillment_status', 2917 line_items: 'order_item', 2918 note: 'note', 2919 order_number: 'order_number', 2920 phone: 'phone', 2921 shipping_address: 'shipping_address', 2922 shipping_methods: 'shipping_methods', 2923 shipping_price: 'total_shipping', 2924 subtotal_price: 'subtotal_price', 2925 // tax_lines: 'tax_lines', 2926 tax_price: 'total_tax', 2927 total_discounts: 'total_discount', 2928 total_net_amount: 'total_amount_include_transaction', 2929 total_price: 'total_price', 2930 transactions: 'transaction_records', 2931 is_manual_payment: 'is_manual_payment', 2932 } 2933 2934 order.email = order.billing_address.email 2935 order.phone = order.billing_address.phone 2936 order.shipping_method = order.shipping_method_name 2937 2938 order = map(order, mapper) 2939 2940 order.line_items = order.line_items.map(item => mapLineItem(item)) 2941 order.transactions = order.transactions.map(transaction => mapTransaction(transaction)) 2942 2943 return order 2944 2945 } 2946 2947 const mapLineItem = line_item => { 2948 2949 const old_line_item = line_item 2950 2951 const mapper = { 2952 final_price: 'price', 2953 image: 'img_url', 2954 message: 'message', 2955 original_line_price: 'original_line_price', 2956 original_price: 'original_price', 2957 properties: 'properties', 2958 quantity: 'quantity', 2959 requires_shipping: 'shipping_required', 2960 sku: 'sku', 2961 taxable: 'taxable', 2962 title: 'product_name', 2963 product_name: 'product_name', 2964 url: 'url', 2965 product_id: 'product_id', 2966 variant_id: 'variant_id', 2967 id: ['id', 'i_id'], 2968 } 2969 2970 line_item = map(line_item, mapper) 2971 2972 line_item.product_id = line_item.product_id || (old_line_item.product && old_line_item.product.id) || null 2973 line_item.variant_id = line_item.variant_id || (old_line_item.variant && old_line_item.variant.id) || null 2974 line_item.image = line_item.image || (old_line_item.image && old_line_item.image.url) || null 2975 2976 return line_item 2977 2978 } 2979 2980 const mapTransaction = transaction => { 2981 2982 const mapper = { 2983 amount: 'amount', 2984 created_at: 'created_at', 2985 gateway: 'gateway_type', 2986 id: 'id', 2987 status: 'status', 2988 } 2989 2990 transaction = map(transaction, mapper) 2991 2992 return transaction 2993 2994 } 2995 2996 2997</script>
2997 2998 2999</body> 3000</html>
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.