app/template/default/Block/myModal.twig line 1

Open in your IDE?
  1. {# 自動表示モーダルブロック #}
  2. <div id="ecAutoModal" class="ec-modal-overlay">
  3.     <div class="ec-modal-content">
  4.         <button class="ec-modal-close" onclick="ECAutoModal.close()" aria-label="モーダルを閉じる"></button>
  5.         <a href="https://www.instagram.com/iseyabread/" target="_blank" rel="noopener noreferrer">
  6.             <img src="{{ asset('/html/user_data/ContentImg/instagram.png') }}" 
  7.                  alt="キャンペーン画像" 
  8.                  class="ec-modal-image" />
  9.         </a>
  10.     </div>
  11. </div>
  12. <script>
  13.         (function() {
  14.             'use strict';
  15.             
  16.             const CONFIG = {
  17.                 MODAL_ID: 'ecAutoModal',
  18.                 AUTO_SHOW_DELAY: 2500, // 2.5秒
  19.                 STORAGE_KEY: 'ecAutoModalLastClosed',
  20.                 SUPPRESS_DURATION: 5 * 60 * 1000 // 5分(ミリ秒)
  21.             };
  22.             
  23.             const modal = document.getElementById(CONFIG.MODAL_ID);
  24.             let isModalOpen = false;
  25.             let autoShowTimer = null;
  26.             
  27.             function getLastClosedTime() {
  28.                 try {
  29.                     const timestamp = localStorage.getItem(CONFIG.STORAGE_KEY);
  30.                     return timestamp ? parseInt(timestamp, 10) : 0;
  31.                 } catch (e) {
  32.                     // localStorageが使えない場合はcookieで代用
  33.                     const match = document.cookie.match(new RegExp(CONFIG.STORAGE_KEY + '=([^;]+)'));
  34.                     return match ? parseInt(match[1], 10) : 0;
  35.                 }
  36.             }
  37.             
  38.             // 最後に閉じた時刻を保存
  39.             function setLastClosedTime() {
  40.                 const now = Date.now();
  41.                 try {
  42.                     localStorage.setItem(CONFIG.STORAGE_KEY, now.toString());
  43.                 } catch (e) {
  44.                     // localStorageが使えない場合はcookieで代用(5分有効)
  45.                     const expireTime = new Date(now + CONFIG.SUPPRESS_DURATION);
  46.                     document.cookie = `${CONFIG.STORAGE_KEY}=${now}; expires=${expireTime.toUTCString()}; path=/`;
  47.                 }
  48.             }
  49.             
  50.             // モーダル表示を抑制するかチェック
  51.             function shouldSuppressModal() {
  52.                 const lastClosed = getLastClosedTime();
  53.                 if (lastClosed === 0) return false;
  54.                 
  55.                 const now = Date.now();
  56.                 const timeSinceLastClosed = now - lastClosed;
  57.                 return timeSinceLastClosed < CONFIG.SUPPRESS_DURATION;
  58.             }
  59.             
  60.             /**
  61.              * モーダルを開く関数
  62.              */
  63.             function openModal() {
  64.                 if (!modal || shouldSuppressModal()) return;
  65.                 
  66.                 modal.classList.add('active');
  67.                 isModalOpen = true;
  68.                 
  69.                 dispatchModalEvent('Open');
  70.             }
  71.             
  72.             /**
  73.              * モーダルを閉じる関数
  74.              */
  75.             function closeModal() {
  76.                 if (!modal) return;
  77.                 
  78.                 modal.classList.remove('active');
  79.                 isModalOpen = false;
  80.                 
  81.                 // 閉じた時刻を保存
  82.                 setLastClosedTime();
  83.                 
  84.                 // タイマーをクリア
  85.                 if (autoShowTimer) {
  86.                     clearTimeout(autoShowTimer);
  87.                     autoShowTimer = null;
  88.                 }
  89.                 
  90.                 // カスタムイベント発火
  91.                 dispatchModalEvent('Close');
  92.             }
  93.             
  94.             /**
  95.              * カスタムイベント発火
  96.              */
  97.             function dispatchModalEvent(eventType) {
  98.                 const event = new CustomEvent('ecAutoModal' + eventType, {
  99.                     detail: { 
  100.                         isOpen: isModalOpen,
  101.                         modalId: CONFIG.MODAL_ID
  102.                     }
  103.                 });
  104.                 document.dispatchEvent(event);
  105.             }
  106.             
  107.             /**
  108.              * 自動表示タイマーの開始
  109.              */
  110.             function startAutoShowTimer() {
  111.                 if (shouldSuppressModal()) {
  112.                     console.log('EC Auto Modal: Suppressed due to recent closure');
  113.                     return;
  114.                 }
  115.                 
  116.                 autoShowTimer = setTimeout(function() {
  117.                     openModal();
  118.                 }, CONFIG.AUTO_SHOW_DELAY);
  119.             }
  120.             
  121.             if (modal) {
  122.                 modal.addEventListener('click', function(event) {
  123.                     // モーダル外をクリックしても閉じない
  124.                     // 必要に応じてコメントアウトを外す
  125.                     // if (event.target === modal) {
  126.                     //     closeModal();
  127.                     // }
  128.                 });
  129.             }
  130.             
  131.             /**
  132.              * 初期化関数
  133.              */
  134.             function init() {
  135.                 if (!modal) {
  136.                     console.warn('EC Auto Modal: Modal element not found');
  137.                     return;
  138.                 }
  139.                 
  140.                 // ページが完全に読み込まれてからタイマー開始
  141.                 if (document.readyState === 'loading') {
  142.                     document.addEventListener('DOMContentLoaded', startAutoShowTimer);
  143.                 } else {
  144.                     startAutoShowTimer();
  145.                 }
  146.             }
  147.             
  148.             // グローバルオブジェクトとして公開
  149.             window.ECAutoModal = {
  150.                 open: openModal,
  151.                 close: closeModal,
  152.                 isOpen: function() {
  153.                     return isModalOpen;
  154.                 },
  155.                 reset: function() {
  156.                     // 抑制状態をリセット(デバッグ用)
  157.                     try {
  158.                         localStorage.removeItem(CONFIG.STORAGE_KEY);
  159.                     } catch (e) {
  160.                         document.cookie = `${CONFIG.STORAGE_KEY}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/`;
  161.                     }
  162.                 },
  163.                 // 残り抑制時間を取得(デバッグ用)
  164.                 getRemainingSuppressionTime: function() {
  165.                     const lastClosed = getLastClosedTime();
  166.                     if (lastClosed === 0) return 0;
  167.                     
  168.                     const now = Date.now();
  169.                     const elapsed = now - lastClosed;
  170.                     const remaining = CONFIG.SUPPRESS_DURATION - elapsed;
  171.                     return Math.max(0, remaining);
  172.                 },
  173.                 config: CONFIG
  174.             };
  175.             
  176.             // 初期化実行
  177.             init();
  178.             
  179.         })();
  180.         
  181.         /**
  182.          * EC-CUBE Twig用の初期化関数
  183.          * 使用例: initECAutoModal('{{ asset("assets/img/campaign.jpg") }}')
  184.          */
  185.         function initECAutoModal(imageUrl, customDelay) {
  186.             const modalImage = document.querySelector('#ecAutoModal .ec-modal-image');
  187.             if (modalImage && imageUrl) {
  188.                 modalImage.src = imageUrl;
  189.                 modalImage.alt = 'キャンペーン画像';
  190.             }
  191.             
  192.             // カスタム遅延時間の設定
  193.             if (customDelay && typeof customDelay === 'number') {
  194.                 ECAutoModal.config.AUTO_SHOW_DELAY = customDelay;
  195.             }
  196.         }
  197.         
  198.         // イベントリスナーの例
  199.         document.addEventListener('ecAutoModalOpen', function(e) {
  200.             console.log('EC Auto Modal opened:', e.detail);
  201.         });
  202.         
  203.         document.addEventListener('ecAutoModalClose', function(e) {
  204.             console.log('EC Auto Modal closed:', e.detail);
  205.         });
  206.   </script>
  207.     <style>
  208.         /* モーダルのベーススタイル */
  209.         .ec-modal-overlay {
  210.             position: fixed;
  211.             top: 0;
  212.             left: 0;
  213.             width: 100%;
  214.             height: 100%;
  215.             background-color: rgba(0, 0, 0, 0.7);
  216.             display: flex;
  217.             justify-content: center;
  218.             align-items: center;
  219.             z-index: 9999;
  220.             opacity: 0;
  221.             visibility: hidden;
  222.             transition: all 0.3s ease;
  223.         }
  224.         .ec-modal-overlay.active {
  225.             opacity: 1;
  226.             visibility: visible;
  227.         }
  228.         .ec-modal-content {
  229.             position: relative;
  230.             max-width: 500px;
  231.             max-height: auto;
  232.             background: transparent;
  233.             border-radius: 15px;
  234.             overflow: hidden;
  235.             transform: scale(0.8);
  236.             transition: transform 0.3s ease;
  237.             box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
  238.         }
  239.         .ec-modal-overlay.active .ec-modal-content {
  240.             transform: scale(1);
  241.         }
  242.         .ec-modal-image {
  243.             width: 100%;
  244.             height: auto;
  245.             display: block;
  246.             border-radius: 15px;
  247.         }
  248.         /* 閉じるボタン */
  249.         .ec-modal-close {
  250.             position: absolute;
  251.             top: 15px;
  252.             right: 15px;
  253.             width: 40px;
  254.             height: 40px;
  255.             background-color: rgba(0, 0, 0, 0.8);
  256.             border: none;
  257.             border-radius: 50%;
  258.             cursor: pointer;
  259.             display: flex;
  260.             justify-content: center;
  261.             align-items: center;
  262.             transition: all 0.3s ease;
  263.             z-index: 10001;
  264.             color: white;
  265.             font-size: 20px;
  266.             font-weight: bold;
  267.         }
  268.         .ec-modal-close:hover {
  269.             background-color: rgba(255, 0, 0, 0.8);
  270.             transform: scale(1.1);
  271.         }
  272.         .ec-modal-close:before {
  273.             content: "×";
  274.             line-height: 1;
  275.         }
  276.         /* レスポンシブ対応 */
  277.         @media (max-width: 768px) {
  278.             .ec-modal-content {
  279.                 max-width: 75%;
  280.                 max-height: 75%;
  281.             }
  282.             
  283.             .ec-modal-close {
  284.                 width: 35px;
  285.                 height: 35px;
  286.                 top: 10px;
  287.                 right: 10px;
  288.                 font-size: 18px;
  289.             }
  290.         }
  291.         @media (max-width: 480px) {
  292.             .ec-modal-content {
  293.                 max-width: 85%;
  294.                 max-height: 85%;
  295.             }
  296.         }
  297. </style>