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