1 2<!DOCTYPE html> 3<html lang="ja"> 4<head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# article: http://ogp.me/ns/article#"> 5 <meta charset="utf-8"/> <meta name="viewport" content="width=device-width,initial-scale=1.0"> 6 <meta name="google-site-verification" content="AD6C_I-u_IpdT7-l1nRqU1mo-JcGVY2Q_JDPLrOsjI4"> 7 <link rel="shortcut icon" href="https://assets.tanp.jp/favicon.ico"> 8 <title>ã·ã§ããã³ã°ã«ã¼ã | TANPï¼ã¿ã³ãï¼</title> 9
9<script src="https://assets.tanp.jp/72a9040/js/laravel-mix/dist/pc/init.js"></script>
9 <meta name="description" content="æ¥æ¬æå¤§ç´ã®ã®ããå°éé販TANPï¼ã¿ã³ãï¼ãããªãã®ã®ããé¸ã³ãç·åçã«ãæä¼ããããã¾ããã25,000ç¹ä»¥ä¸ã®åæããããã¤ã³ãéå æå¤§5%ããæç峿¥çºéã å°éãã¤ã¤ã¼ãå³é¸ããã»ã³ã¹ã®ãããæ´è½ãªã®ããã«åºä¼ãã¾ããå å®ã®ãµãã¼ãã§é©åãªã®ãããç°¡åã«é¸ã¹ãã®ã§ãããã§ã®è³¼å ¥ãå®å¿ã§ãã"/> <link href="https://tanp.jp/carts" rel="canonical"> 10 <meta name="robots" content="noindex"> 11 <meta property="og:title" content="ã·ã§ããã³ã°ã«ã¼ã | TANPï¼ã¿ã³ãï¼"> 12 <meta property="og:type" content="article"> 13 <meta property="og:url" content="https://tanp.jp/carts"> 14 <meta property="og:image" 15 content="https://images.tanp.jp/gracia.tanp/ogp/tanp_ogp.jpg"> 16 <meta property="og:site_name" content="TANPï¼ã¿ã³ãï¼"> 17 <meta property="og:description" content="æ¥æ¬æå¤§ç´ã®ã®ããå°éé販TANPï¼ã¿ã³ãï¼ãããªãã®ã®ããé¸ã³ãç·åçã«ãæä¼ããããã¾ããã25,000ç¹ä»¥ä¸ã®åæããããã¤ã³ãéå æå¤§5%ããæç峿¥çºéã å°
17éãã¤ã¤ã¼ãå³é¸ããã»ã³ã¹ã®ãããæ´è½ãªã®ããã«åºä¼ãã¾ããå å®ã®ãµãã¼ãã§é©åãªã®ãããç°¡åã«é¸ã¹ãã®ã§ãããã§ã®è³¼å ¥ãå®å¿ã§ãã"> 18 <link rel="apple-touch-icon" href='https://assets.tanp.jp/favicon.ico'/> 19 <meta property="fb:app_id" content="130413917573250"> 20 <meta name="twitter:card" content="summary_large_image"> 21 22 <meta name="p:domain_verify" content="b66815b7fca76d124c9854d862c15848"/> 23 24 25 26
27<script> 28 window.dataLayer = window.dataLayer || [];
vendor: 366 bytes, lines 28-31
28 29 30 31 (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);})(window,document,'script','dataLayer','
31GTM-54ST37K
vendor: 13 bytes, lines 31-33
31'); 32 33
33</script>
33 34 35 <link rel="stylesheet" href="https://assets.tanp.jp/72a9040/css/dist/styles/pc-application.css"/> <link rel="stylesheet" href="https://assets.tanp.jp/72a9040/css/dist/styles/pages/common/carts/index.css"/><link rel="stylesheet" href="https://assets.tanp.jp/72a9040/css/dist/pages/favorite_toast/index.css"/> 36 <link rel="preload" href="https://assets.tanp.jp/font/NotoSansJP-Regular-Slim.woff2" as="font" type="font/woff2" crossorigin> 37 <link rel="preload" href="https://assets.tanp.jp/font/NotoSansJP-Bold-Slim.woff2" as="font" type="font/woff2" crossorigin> 38 <link rel="preload" href="https://assets.tanp.jp/font/FontAwesome-Slim.woff2" as="font" type="font/woff2" crossorigin> 39 40 41
41<script src="https://assets.tanp.jp/72a9040/js/dist/my_layout.js"></script>
41 42
42<script src="https://assets.tanp.jp/72a9040/js/laravel-mix/dist/pc/application.js" defer="defer"></script>
42 </head> 43 44<body> 45 46 47<template id='template-product-item'> 48 <a href="" class="container"> 49 <div class="image-container"> 50 <p class="rank"></p> 51 <div class="label-container"> 52 <p class="can-personalization">åå ¥ã対å¿</p> 53 <p class="is-new">New</p> 54 </div> 55 <img class="image"> 56 </div> 57 <div class="info-container"> 58 <p class="brand-title text"></p> 59 <p class="title text"></p> 60 <p class="product-group text"></p> 61 <div class="bottom-container"> 62 <div class="price-container"> 63 <p class="price text"></p> 64 </div> 65 <slot name="fav-button"></slot> 66 </div> 67 <p class="min-shipping-date"></p> 68 <p class="sold-out">SOLD OUT</p> 69 </div> 70 </a> 71 72 <style> 73 * { 74 box-sizing: border-box; 75 } 76 77 p { 78 margin: 0; 79 } 80 81 :host { 82 /* ããã©ã«ãã¯inline-blockããã®ã¾ã¾ã ã¨containerã®width:100%ãå¹ããªã */ 83 display: block; 84 } 85 86 .container { 87 display: block; 88 width: 100%; 89 transition: opacity 0.3s; 90 text-decoration: none; 91 } 92 93 .image-container { 94 position: relative; 95 width: 100%; 96 padding-top: 100%; 97 } 98 99 .rank { 100 position: absolute; 101 z-index: 1; 102 margin: 0; 103 left: 5px; 104 top: 5px; 105 font-size: 11px; 106 display: inline-block; 107 height: 22px; 108 line-height: 22px; 109 border-radius: 12px; 110 padding: 0 9px; 111 color: var(--color-base-bright); 112 background-color: var(--color-primary); 113 } 114 115 :host(:not([rank])) .rank { 116 display: none; 117 } 118 119 .label-container { 120 position: absolute; 121 z-index: 1; 122 left: 0; 123 bottom: 0; 124 display: flex; 125 flex-direction: column; 126 align-items: flex-start; 127 } 128 129 .can-personalization, 130 .is-new { 131 font-size: 10px; 132 line-height: 12px; 133 color: var(--color-base-bright); 134 padding: 4px 8px; 135 } 136 137 .can-personalization { 138 background-color: #EF5D60; 139 } 140 141 :host(:not([can-personalization])) .can-personalization { 142 display: none; 143 } 144 145 .is-new { 146 background-color: #C9B67E; 147 } 148 149 :host(:not([is-new])) .is-new { 150 display: none; 151 } 152 153 .image { 154 display: block; 155 position: absolute; 156 top: 0; 157 left: 0; 158 width: 100%; 159 height: 100%; 160 object-fit: cover; 161 border: 0; 162 opacity: 0; 163 transition: opacity 0.5s; 164 } 165 166 .image[src] { 167 opacity: 1 !important; 168 } 169 170 .info-container { 171 padding-top: 8px; 172 } 173 174 .text { 175 line-height: 1.4; 176 white-space: nowrap; 177 overflow: hidden; 178 text-overflow: ellipsis; 179 } 180 181 .brand-title { 182 font-size: 10px; 183 color: var(--color-base-deep); 184 margin-bottom: 4px; 185 } 186 187 .title { 188 font-size: 12px; 189 font-weight: bold; 190 margin-bottom: 4px; 191 color: var(--color-base); 192 } 193 194 .product-group { 195 font-size: 12px; 196 color: var(--color-base-deep); 197 margin-bottom: 8px; 198 } 199 200 .bottom-container { 201 display: flex; 202 justify-content: space-between; 203 align-items: flex-start; 204 margin-bottom: 8px; 205 } 206 207 .price { 208 font-size: 14px; 209 line-height: 20px; 210 color: var(--color-base); 211 } 212 213 .sold-out { 214 display: none; 215 font-size: 10px; 216 line-height: 10px; 217 color: var(--color-base-deep); 218 background-color: var(--color-base-middle); 219 border-radius: 4px; 220 padding: 6px 8px; 221 } 222 223 :host([sold-out]) .sold-out { 224 display: inline-block; 225 } 226
227 .min-shipping-date { 228 display: none; 229 font-size: 12px; 230 font-weight: normal; 231 color: var(--color-base); 232 } 233 234 .min-shipping-date span { 235 color: var(--color-secondary); 236 font-weight: bold; 237 } 238 239 :host([min-shipping-date]) .min-shipping-date { 240 display: block; 241 } 242 243 :host([device="sp"]) .rank { 244 left: 4px; 245 top: 4px; 246 font-size: 10px; 247 } 248 249 :host([device="sp"]) .info-container { 250 padding: 8px; 251 } 252 253 :host([device="sp"]) .title { 254 font-size: 10px; 255 min-height: 28px; 256 white-space: normal; 257 display: -webkit-box; 258 -webkit-box-orient: vertical; 259 -webkit-line-clamp: 2; 260 } 261 262 :host([device="sp"]) .product-group { 263 font-size: 10px; 264 } 265 266 :host([device="sp"]) .price { 267 font-size: 16px; 268 line-height: 1.2; 269 } 270 271 :host([device="sp"]) .min-shipping-date { 272 font-size: 10px; 273 } 274 </style> 275</template> 276
277<script> 278 customElements.define('product-item', 279 class extends HTMLElement { 280 constructor() { 281 super(); 282 283 // ãã®Elementã«Shadow DOMãattachãã 284 const shadowRoot = this.attachShadow({mode: 'open'}); 285 286 // <template> ã¿ã°ã®å 容ãè¤è£½ããShadow DOMã«è¿½å 287 const template = document.getElementById('template-product-item'); 288 shadowRoot.appendChild(template.content.cloneNode(true)); 289 } 290 291 connectedCallback() { 292 // linkã®è¨å® 293 const linkElement = this.shadowRoot.querySelector('.container'); 294 linkElement.href = `/products/view/${this.productId}`; 295 296 // rankã®è¨å® 297 const rankElement = this.shadowRoot.querySelector('.rank'); 298 if (this.rank) { 299 rankElement.innerText = `${this.rank} ä½`; 300 } 301 302 // imageã®è¨å® 303 // TODO: loading: lazy屿§ãæ®åãããããã«ç½®ãæãã 304 const imageElement = this.shadowRoot.querySelector('.image'); 305 imageElement.alt = this.title; 306 const this_ = this; 307 // ç»é¢ã«å ¥ã£ãã¨ãã«ç»åãèªã¿è¾¼ã 308 this.observer = new IntersectionObserver((entries, observer) => { 309 const entry = entries[0]; 310 if (entry.isIntersecting) { 311 observer.unobserve(entry.target); 312 entry.target.src = this_.imageUrl; 313 } 314 }, {rootMargin: '1000px 0px'}); 315 this.observer.observe(imageElement); 316 317 // brand titleã®è¨å® 318 const brandTitleElem = this.shadowRoot.querySelector('.brand-title'); 319 brandTitleElem.innerText = this.brandTitle; 320 321 // titleã®è¨å® 322 const titleElem = this.shadowRoot.querySelector('.title'); 323 titleElem.innerText = this.title; 324 325 // product groupã®è¨å® 326 const productGroupElem = this.shadowRoot.querySelector('.product-group'); 327 productGroupElem.innerText = this.productGroup; 328 329 // priceã®è¨å® 330 const priceElem = this.shadowRoot.querySelector('.price'); 331 if (this.shouldDisplayPriceRangeMark) { 332 priceElem.innerHTML = `¥ ${this.price.toLocaleString()}ã`; 333 } else { 334 priceElem.innerHTML = `¥ ${this.price.toLocaleString()}`; 335 } 336 337 // min-shipping-dateã®è¨å® 338 if (this.minShippingDate) { 339 const minShippingDateElem = this.shadowRoot.querySelector('.min-shipping-date'); 340 minShippingDateElem.innerHTML = `æç<span>${this.minShippingDate.toLocaleString()}</span>ãå±ã`; 341 } 342 } 343 344 /* 345 * Attributes 346 */ 347 get productId() { 348 return this.getAttribute('product-id'); 349 } 350 351 get rank() { 352 return this.getAttribute('rank'); 353 } 354 355 get imageUrl() { 356 return this.getAttribute('image-url'); 357 } 358 359 get title() { 360 return this.getAttribute('title'); 361 } 362 363 get brandTitle() { 364 return this.getAttribute('brand-title'); 365 } 366 367 get productGroup() { 368 return this.getAttribute('product-group'); 369 } 370 371 get price() { 372 return Number(this.getAttribute('price')); 373 } 374 375 get shouldDisplayPriceRangeMark() { 376 const val = this.getAttribute('should-display-price-range-mark'); 377 return val === '' || val === 'true'; 378 } 379 380 get minShippingDate() { 381 return this.getAttribute('min-shipping-date'); 382 } 383 384 get device() { 385 return this.getAttribute('device') ?? 'pc'; 386 } 387 } 388 ); 389</script>
389 390 391<template id='template-login-modal'> 392 <div class="background"> 393 <div class="modal"> 394 <div class="header"> 395 <span class="close-button">×</span> 396 </div> 397 <div class="content"> 398 <div class="content-image-box"> 399 <img class="content-image" 400 src="https://images.tanp.jp/gracia.tanp/icons/login_modal_img.png" 401 alt="login_modal_img" 402 > 403 </div> 404 <p class="content-title">ãæ°ã«å ¥ãã«è¿½å </p> 405 <p class="content-sub-title">ãåå ¥è·ãããå¤ä¸ãããããã«ãç¥ãã</p> 406 <p class="content-description"> 407 ã¡ã«ãã¬ãã¢ããªããã·ã¥éç¥ã<br> 408 許å¯ãã¦ããã ããæ¹ã«ã®ã¿éä»ãããã¾ãã 409 </p> 410 <p class="content-attention">ãæ°ã«å ¥ãã®è¿½å ã«ã¯ãã°ã¤ã³ãå¿ è¦ã§ã</p> 411 <div class="login-link-container"> 412 <a href="/users/login" class="login-link"> 413 <button class="login-link-container-button login">ãã°ã¤ã³</button> 414 </a> 415 <a href="/users/registrationForm" class="login-link"> 416 <button class="login-link-container-button signUp">æ°è¦ä¼å¡ç»é²</button> 417 </a> 418 </div> 419 </div> 420 </div> 421 </div> 422 423 <style> 424 * { 425 box-sizing: border-box; 426 } 427 428 .background { 429 z-index: 100; 430 position: fixed; 431 left: 0; 432 top: 0; 433 width: 100vw; 434 height: 100vh; 435 background-color: rgba(0, 0, 0, 0.4); 436 animation: fade-in 0.8s; 437 } 438 439 @keyframes fade-in { 440 from { 441 opacity: 0; 442 } 443 to { 444 opacity: 1; 445 } 446 } 447 448 .modal { 449 max-width: 406px; 450 width: calc(100% - 20px); 451 background-color: var(--color-base-bright); 452 border-radius: 5px; 453 margin: calc((100vh - 596.5px) / 2) auto; 454 } 455 456 :host([device="sp"]) .modal { 457 max-width: 343px; 458 margin: calc((100vh - 530px) / 2) auto; 459 } 460 461 .header { 462 position: relative; 463 padding: 20px; 464 } 465 466 :host([device="sp"]) .header { 467 padding: 16px: 468 } 469 470 .close-button { 471 position: absolute; 472 right: 21px; 473 top: 21px; 474 font-size: 24px; 475 color: var(--color-base-deep); 476 cursor: pointer; 477 } 478 479 .content { 480 padding: 20px; 481 } 482 483 :host([device="sp"]) .content { 484 padding: 16px; 485 } 486 487 .content-image-box { 488 position: relative; 489 margin: 0 auto; 490 height: 162px; 491 width: 162px; 492 } 493 494 :host([device="sp"]) .content-image-box { 495 height: 137px; 496 width: 137px; 497 } 498 499 .content-image-box img { 500 object-fit: contain; 501 position: absolute; 502 width: 100%; 503 height: 100%; 504 } 505 506 .content-title { 507 font-size: 24px; 508 text-align: center; 509 font-weight: 700; 510 line-height: 150%; 511 } 512 513 :host([device="sp"]) .content-title { 514 font-size: 18px; 515 } 516 517 .content-sub-title { 518 font-size: 18px; 519 text-align: center; 520 font-weight: 700; 521 line-height: 100%; 522 } 523 524 :host([device="sp"]) .content-sub-title { 525 font-size: 14px; 526 } 527 528 .content-description { 529 font-size: 12px; 530 text-align: center; 531 font-weight: 400; 532 color: var(--color-base-deep); 533 } 534 535 :host([device="sp"]) .content-description { 536 font-size: 10px; 537 } 538 539 .content-attention { 540 font-size: 14px; 541 text-align: center; 542 font-weight: 400; 543 color: var(--color-notification); 544 margin-top: 32px; 545 } 546 547 :host([device="sp"]) .content-attention { 548 font-size: 12px; 549 } 550 551 .login-link-container { 552 margin-top: 16px; 553 text-align: center; 554 padding: 0 11px; 555 } 556 557 :host([device="sp"]) .login-link-container { 558 font-size: 15px; 559 } 560 561 .login-link-container-button { 562 width: 100%; 563 height: 48px; 564 margin-bottom: 16px; 565 border-radius: 8px; 566 border: 1px solid #E4A357; 567 font-size: 15px; 568 line-height: 100%; 569 font-weight: 700; 570 } 571 572 :hover .login-link-container-button { 573 cursor: pointer; 574 } 575 576 .login { 577 background: var(--color-primary); 578 color: var(--color-base-bright); 579 } 580 581 .signUp { 582 background: var(--color-base-bright); 583 color: var(--color-primary); 584 } 585 586 .login-link { 587 font-size: 14px; 588 color: var(--color-notification); 589 text-decoration: underline; 590 } 591 592 :host([device="sp"]) .login-link { 593 font-size: 16px; 594 color: var(--color-primary); 595 } 596 597 .login-link:first-of-type { 598 margin-right: 30px; 599 } 600 </style> 601</template> 602
603<script> 604customElements.define('login-modal', 605 class extends HTMLElement { 606 constructor() { 607 super(); 608 609 // ãã®Elementï¼<login-modal>ã¿ã°ï¼ã«Shadow DOMãattachãã 610 const shadowRoot = this.attachShadow({mode: 'open'}); 611 612 const template = document.getElementById('template-login-modal'); 613 shadowRoot.appendChild(template.content.cloneNode(true)); 614 } 615 616 connectedCallback() { 617 this.shadowRoot.querySelectorAll('.login-link').forEach((link) => { 618 link.href += '?redirect=' + this.getCurrentPath(); 619 }); 620 621 // close-buttonã®è¨å® 622 const closeButton = this.shadowRoot.querySelector('.close-button'); 623 const this_ = this; 624 closeButton.addEventListener('click', () => { 625 this_.remove(); 626 }); 627 } 628 629 getCurrentPath() { 630 return window.location.pathname; 631 } 632 } 633); 634</script>
634 635<template id='template-login-modal-for-fav'> 636 <login-modal> 637 </login-modal> 638</template> 639 640<template id='template-fav-button'> 641 <button> 642 <svg> 643 <use xlink:href="/img/icons.svg#icon-heart-fill"></use> 644 </svg> 645 </button> 646 647 <style> 648 button { 649 box-sizing: border-box; 650 display: block; 651 padding: 0; 652 height: 20px; 653 width: 20px; 654 background: transparent; 655 border: none; 656 } 657 658 svg { 659 width: 100%; 660 height: 100%; 661 fill: var(--color-base-middle); 662 } 663 664 :host([favorited=""]) svg, :host([favorited="true"]) svg { 665 fill: var(--color-notification); 666 } 667 </style> 668</template>
669<script> 670 const FAVORITE_TOAST_EVENT = 'tanp:favorites:show-toast'; 671 672 class FavButtonElement extends HTMLElement { 673 674 // åä¸ååã®ãæ°ã«å ¥ãç¶æ ãåæããããã«ããã¼ã¸å ã®å ¨ã¦ã®FavButtonElementãä¿æãã¦ããï¼ãããç¶æ¿ãã¦ããFavButtonWithCountElementãä¿æããï¼ 675 static favoriteButtonElements = []; 676 677 constructor() { 678 super(); 679 // shadow-domã«é ãããå ´åãwindow.querySelectorãªã©ã§ã¯ 680 // ã¨ã¬ã¡ã³ãã«ã¢ã¯ã»ã¹ã§ããªããããã¨ã¬ã¡ã³ãã®ãªã¹ããå¥ã§ç®¡çããã 681 FavButtonElement.favoriteButtonElements.push(this); 682 } 683 684 // ã«ã¹ã¿ã è¦ç´ ãDOMã«æ¥ç¶ãããæã«å¼ã³åºããã 685 connectedCallback() { 686 if (!this.shadowRoot) { 687 // ãã®Elementï¼<fav-button>ã¿ã°ï¼ã«Shadow DOMãattachãã 688 const shadowRoot = this.attachShadow({mode: 'open'}); 689 690 // <template> ã¿ã°ã®å 容ãè¤è£½ããShadow DOMã«è¿½å 691 const template = document.getElementById('template-fav-button'); 692 shadowRoot.appendChild(template.content.cloneNode(true)); 693 694 // ãã¿ã³ãã¯ãªãã¯ããæã®æåãã»ãããã 695 this.setButtonEvent(); 696 } 697 } 698 699 setButtonEvent() { 700 this.isRequesting = false; 701 702 const button = this.shadowRoot.querySelector('button'); 703 704 // ã¢ã¤ã³ã³ãã¯ãªãã¯ããæã®æå 705 button.addEventListener('click', (e) => { 706 e.stopPropagation(); 707 e.preventDefault(); 708 709 // "show-modal-on-click" 屿§ãæå®ããã¦ããå ´å㯠710 // ã¢ã¼ãã«ã表示ãã¦å¦çãçµãã 711 if (this.showModalOnClick) { 712 const modalTemplate = document.getElementById('template-login-modal-for-fav'); 713 const modalNode = modalTemplate.content.cloneNode(true); 714 // "device" attributeãè¨å®ãã 715 modalNode.querySelector('login-modal').setAttribute('device', this.device); 716 document.body.appendChild(modalNode); 717 return; 718 } 719 720 if (this.shouldOpenFavoriteListSelector) { 721 window.dispatchEvent(new CustomEvent('tanp:favorites:open-selector', { 722 detail: { 723 productId: Number(this.productId), 724 logAddFavEvent: this.logAddFavEvent, 725 logDeleteFavEvent: this.logDeleteFavEvent, 726 }, 727 })); 728 return; 729 } 730 731 if (this.isRequesting === false) { 732 // ï¼éãªã¯ã¨ã¹ããèµ·ããªãããã«ãã 733 this.isRequesting = true; 734 const nextFavorited = !this.isFavorited; 735 736 // requestãéä¿¡ãã 737 this.requestFavorite(nextFavorited) 738 .then((res) => { 739 if (res.ok) { 740 // 表示ãåãæ¿ãã 741 this.brotherElements.forEach((elem) => elem.toggle()); 742 // ãã°ãéä¿¡ããï¼ã¨ã©ã¼å¦çã¯ããªãï¼ 743 this.pushLog(this.isFavorited); 744 this.showFavoriteToast(nextFavorited); 745 } 746 }) 747 .finally(() => { 748 // å¦çãçµãã£ãã®ã§isRequestingãæ´æ°ãã 749 this.isRequesting = false; 750 }); 751 } 752 }); 753 } 754 755 // 'favorited' attributeãåãæ¿ãã 756 toggle() { 757 this.isFavorited = !this.isFavorited; 758 } 759 760 // favoriteç¶æ ã®æ´æ°ãªã¯ã¨ã¹ãããµã¼ãã¼ã«éã 761 // - val : Boolean 762 // - requestFavorite() : Promise<Response> 763 requestFavorite(val) { 764 const path = val ? '/favorites/add' : '/favorites/delete'; 765 const csrfToken = document.querySelector('input[name="_csrfToken"]').value; 766 const formData = new FormData(); 767 formData.append('product_id', this.productId); 768 formData.append('is_published', this.isPublishedList); 769 770 return fetch(path, {
771 method: 'POST', 772 credentials: 'same-origin', 773 headers: { 774 'X-CSRF-Token': csrfToken, 775 }, 776 body: formData, 777 }); 778 } 779 780 pushLog(val) { 781 // TanpLoggerã¯logger.jsãã¡ã¤ã«ã§å®ç¾©ããã¦ãã 782 if (window.TanpLogger === undefined) { 783 return; 784 } 785 786 const type = val ? this.logAddFavEvent : this.logDeleteFavEvent; 787 788 const logObj = { 789 type, 790 product_id: this.productId, 791 }; 792 window.TanpLogger.pushStandardLog(logObj); 793 } 794 795 showFavoriteToast(isFavorited) { 796 window.dispatchEvent(new CustomEvent(FAVORITE_TOAST_EVENT, { 797 detail: { 798 isPublished: this.isPublishedList, 799 favorited: isFavorited, 800 }, 801 })); 802 } 803 804 /* 805 * Attributes 806 */ 807 get productId() { 808 return this.getAttribute('product-id'); 809 } 810 811 get isFavorited() { 812 const val = this.getAttribute('favorited'); 813 return val === '' || val === 'true'; 814 } 815 816 set isFavorited(val) { 817 if (val) { 818 this.setAttribute('favorited', ''); 819 } else { 820 this.removeAttribute('favorited'); 821 } 822 } 823 824 get showModalOnClick() { 825 const val = this.getAttribute('show-modal-on-click'); 826 return val === '' || val === 'true'; 827 } 828 829 get shouldOpenFavoriteListSelector() { 830 return false; 831 } 832 833 get device() { 834 const val = this.getAttribute('device'); 835 return val ?? 'pc'; 836 } 837 838 get logAddFavEvent() { 839 return this.getAttribute('log-add-fav-event') ?? 'add_favorite'; 840 } 841 842 get logDeleteFavEvent() { 843 return this.getAttribute('log-delete-fav-event') ?? 'delete_favorite'; 844 } 845 846 get isPublishedList() { 847 const val = this.getAttribute('is-published'); 848 if (val === null) { 849 return false; 850 } 851 852 return val === '' || val === 'true' || val === '1'; 853 } 854 855 /* 856 * Computed fields 857 */ 858 859 // èªåã¨åãååIDããã¤ãæ°ã«å ¥ããã¿ã³ãè¿ã 860 get brotherElements() { 861 return FavButtonElement.favoriteButtonElements.filter((element) => { 862 return element.productId === this.productId 863 && element.isPublishedList === this.isPublishedList; 864 }); 865 } 866 } 867 868 // <fav-button> ã¿ã°ã®ç»é² 869 customElements.define('fav-button', FavButtonElement); 870</script>
870 871 872<template id='template-fav-button-with-count'> 873 <button> 874 <svg class="icon"> 875 <use xlink:href="/img/icons.svg#icon-heart-fill"></use> 876 </svg> 877 <span class="count"></span> 878 </button> 879 <style> 880 * { 881 box-sizing: border-box; 882 padding: 0; 883 } 884 885 button { 886 display: block; 887 padding: 2px; 888 background: transparent; 889 border: none; 890 margin: 0 auto; 891 width: 100%; 892 height: 100%; 893 cursor: pointer; 894 } 895 896 .icon { 897 display: block; 898 margin: 0 auto; 899 width: 24px; 900 height: 24px; 901 fill: var(--color-base-middle); 902 } 903 904 .count { 905 display: block; 906 font-size: 10px; 907 color: var(--color-base); 908 margin-top: 4px; 909 } 910 911 :host([favorited=""]) svg, :host([favorited="true"]) svg { 912 fill: var(--color-notification); 913 } 914 </style> 915</template>
916<script> 917 class FavButtonWithCountElement extends FavButtonElement { 918 919 constructor() { 920 super(); 921 } 922 923 // ã«ã¹ã¿ã è¦ç´ ãDOMã«æ¥ç¶ãããæã«å¼ã³åºããã 924 // constructorã®ç´å¾ã«å¼ã³åºããã 925 connectedCallback() { 926 927 // ãã®Elementï¼<fav-button-with-count>ã¿ã°ï¼ã«Shadow DOMãattachãã 928 const shadowRoot = this.attachShadow({mode: 'open'}); 929 930 // <template> ã¿ã°ã®å 容ãè¤è£½ããShadow DOMã«è¿½å 931 const template = document.getElementById('template-fav-button-with-count'); 932 933 shadowRoot.appendChild(template.content.cloneNode(true)); 934 935 // ãã¿ã³ãã¯ãªãã¯ããæã®æåãã»ãããã 936 this.setButtonEvent(); 937 938 // ãæ°ã«å ¥ãæ°ã表示ããspanè¦ç´ ãä¿æãã¦ãã 939 this.countElement = this.shadowRoot.querySelector('.count'); 940 941 // ãæ°ã«å ¥ãæ°ã®è¡¨ç¤ºãã»ãããã 942 this.setFavoriteCountText(); 943 } 944 945 // 'favorited' 'favorite-count' attributeãåãæ¿ãã 946 toggle() { 947 this.isFavorited = !this.isFavorited; 948 const count = parseInt(this.favoriteCount); 949 if (this.isFavorited) { 950 this.favoriteCount = (count + 1).toString(); 951 } else { 952 this.favoriteCount = (count - 1).toString(); 953 } 954 } 955 956 // spanè¦ç´ ã«countã表示ãã 957 setFavoriteCountText() { 958 this.countElement.innerText = parseInt(this.favoriteCount).toLocaleString(); 959 } 960 961 /* 962 * Attributes 963 */ 964 get favoriteCount() { 965 return this.getAttribute('favorite-count'); 966 } 967 968 set favoriteCount(val) { 969 this.setAttribute('favorite-count', val); 970 this.setFavoriteCountText(); 971 } 972 973 get shouldOpenFavoriteListSelector() { 974 return true; 975 } 976 977 } 978 979 // <fav-button-with-count> ã¿ã°ã®ç»é² 980 customElements.define('fav-button-with-count', FavButtonWithCountElement); 981 982 window.addEventListener('tanp:favorites:sync', (event) => { 983 const detail = event.detail ?? {}; 984 if (!detail.productId) { 985 return; 986 } 987 const targetProductId = detail.productId.toString(); 988 const shouldFavorite = Boolean(detail.favorited); 989 FavButtonElement.favoriteButtonElements.forEach((element) => { 990 if (element.productId === targetProductId && element.isFavorited !== shouldFavorite) { 991 element.toggle(); 992 } 993 }); 994 }); 995</script>
vendor: 70 bytes, lines 995-998
995 996 997 998<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=
998GTM-54ST37K
vendor: 96 bytes, lines 998-1000
998" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript> 999 1000
1000<header class="entryFormHeader"> 1001 <div class="entryFormHeader__inner"> 1002 <div class="entryFormHeaderContent"> 1003 <a href="/"> 1004 <img class="entryFormHeaderContent__image" 1005 src="https://images.tanp.jp/gracia.tanp/banners/logo/tanp_logo.png" alt="TANPï¼ã¿ã³ãï¼ ãã´"> 1006 </a> 1007 </div> 1008 </div> 1009 </header> 1010 <div class="wrapper"> 1011 <div class="cartPage"> 1012 <div class="cartMain"> 1013 <h1 class="cartMain__title">ã·ã§ããã³ã°ã«ã¼ã</h1> 1014 <div class="cartMain__content"> 1015 <div class="cartPageEmptyContent"> 1016 <p class="cartPageEmptyContent__message">ã«ã¼ãå ã«ååãããã¾ããã</p> 1017 <a class="outlineButton" href="/">è²·ãç©ãç¶ãã</a> 1018 </div> 1019 </div> 1020 </div> 1021 <div class="cartPageSection"> 1022 <h2 class="cartPageSection__title">ãã¡ããä¸ç·ã«ãããã§ããï¼</h2> 1023 <div class="cartPageSection__content gridProducts"> 1024 1025 <product-item 1026 class="gtmImpression gtmProductClick " 1027 data-id="43996" 1028 product-id="43996" 1029 title="ããåéãè²ãé¸ã¹ããReFa AILE BRUSH (ãªãã¡ã¨ã¼ã«ãã©ã·)" 1030 brand-title="ReFaï¼ãªãã¡ï¼" 1031 product-group="ãã¢ãã©ã·" 1032 price="3800" 1033 min-shipping-date="10æ03æ¥(å)" 1034 image-url="https://images.tanp.jp/gracia.tanp/product43996/1600x1600-aile-brush-d1.jpg?w=560" 1035 > 1036 <fav-button 1037 slot="fav-button" 1038 product-id="43996" 1039 show-modal-on-click 1040 log-add-fav-event="add_favorite_from_product_list" 1041 log-delete-fav-event="delete_favorite_from_product_list" 1042 > 1043 </fav-button> 1044 </product-item> 1045 <product-item 1046 class="gtmImpression gtmProductClick " 1047 data-id="38040" 1048 product-id="38040" 1049 title="éããªãå¤©ç¶æ¸©æ³ã«è¿ãå ¥æµ´å¤ãHAA for bath æ¥ã ã" 1050 brand-title="HAAï¼ãã¼ï¼" 1051 product-group="å ¥æµ´å¤" 1052 price="5280" 1053 min-shipping-date="10æ03æ¥(å)" 1054 image-url="https://images.tanp.jp/gracia.tanp/product38040/%E6%97%A5%E3%80%8510%E5%80%8B%E5%85%A5%E3%82%8A_TOP.jpg?w=560" 1055 > 1056 <fav-button 1057 slot="fav-button" 1058 product-id="38040" 1059 show-modal-on-click 1060 log-add-fav-event="add_favorite_from_product_list" 1061 log-delete-fav-event="delete_favorite_from_product_list" 1062 > 1063 </fav-button> 1064 </product-item> 1065 <product-item 1066 class="gtmImpression gtmProductClick " 1067 data-id="11999" 1068 product-id="11999" 1069 title="ãæ¸©ç±&EMSãããã¯ã±ã¢ï¼NECK RELAXï¼" 1070 brand-title="NIPLUXï¼ãããã©ãã¯ã¹ï¼" 1071 product-group="ããã£ã±ã¢æ©å¨" 1072 price="9680" 1073 min-shipping-date="10æ03æ¥(å)" 1074 image-url="https://images.tanp.jp/gracia.tanp/product11999/%25E3%2583%258D%25E3%2583%2583%25E3%2582%25AF%25E3%2582%25B1%25E3%2582%25A2.jpg?w=560" 1075 > 1076 <fav-button 1077 slot="fav-button" 1078 product-id="11999" 1079 show-modal-on-click 1080 log-add-fav-event="add_favorite_from_product_list" 1081 log-delete-fav-event="delete_favorite_from_product_list" 1082 > 1083 </fav-button> 1084 </product-item> 1085 <product-item 1086 class="gtmImpression gtmProductClick " 1087 data-id="56837" 1088 product-id="56837" 1089 title="ãå ¨å½ç´18,000æ½è¨ããé¸ã¹ãã宿æ³ã®ããã«ã¼ã(ããã«ã»æ 館)" 1090 brand-title="TANPã«ã¿ãã°ã®ãã"
1091 product-group="ä½é¨ãã±ããã»ãã®ä»" 1092 price="10600" 1093 should-display-price-range-mark 1094 min-shipping-date="10æ03æ¥(å)" 1095 image-url="https://images.tanp.jp/gracia.tanp/product56837/ChatGPT%20Image%202026%E5%B9%B47%E6%9C%8828%E6%97%A5%2017_33_26.png?w=560" 1096 > 1097 <fav-button 1098 slot="fav-button" 1099 product-id="56837" 1100 show-modal-on-click 1101 log-add-fav-event="add_favorite_from_product_list" 1102 log-delete-fav-event="delete_favorite_from_product_list" 1103 > 1104 </fav-button> 1105 </product-item> 1106 <product-item 1107 class="gtmImpression gtmProductClick " 1108 data-id="42967" 1109 product-id="42967" 1110 title="ãçµå©ç¥ããã«ã¿ãã°ã®ãã "Wedding"ãBLUEã" 1111 brand-title="TANPã«ã¿ãã°ã®ãã" 1112 product-group="ãã©ã³ãã«ã¿ãã°ã»ãã®ä»" 1113 price="9900" 1114 min-shipping-date="10æ03æ¥(å)" 1115 image-url="https://images.tanp.jp/gracia.tanp/product42967/ChatGPT%20Image%202026%E5%B9%B48%E6%9C%8812%E6%97%A5%2018_14_53.png?w=560" 1116 > 1117 <fav-button 1118 slot="fav-button" 1119 product-id="42967" 1120 show-modal-on-click 1121 log-add-fav-event="add_favorite_from_product_list" 1122 log-delete-fav-event="delete_favorite_from_product_list" 1123 > 1124 </fav-button> 1125 </product-item> 1126 </div> 1127 </div> 1128 </div> 1129 </div> 1130 1131<input type="hidden" name="_csrfToken" value="Qlg5BybBCGlGWXQkcRZ8LstwaWtxV+CyVey+wBF/5T2AJdT3QroL5Z8Tujm+UY4J/x/3sIWRZp3sE6/sJZ0K2hlhOl1CNBen+RFZCRBkg4Az1Nz2dRqHBbYX4ZR22zjdqHGCW9hp72+ae5KJsqQC+Q=="/> 1132 1133 <footer class="footer"> 1134 <div class="footer__simple"> 1135 <p class="footerCopyright__text">ãããã§ã®ãããè´ããªã | TANPï¼ã¿ã³ãï¼</p> 1136 <p class="footerCopyright__text">Copyright© TANP Inc.</p> 1137 </div> 1138 </footer> 1139
1140<script src="https://assets.tanp.jp/72a9040/js/laravel-mix/dist/common/pages/Carts/index.js"></script>
1140<script src="https://assets.tanp.jp/72a9040/js/dist/pages/favorite_toast/index.js"></script>
1140</body> 1141</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.