美國新聯華假期 XO Tours - 美加首選華人旅行社, 全球豪華郵輪, 歐洲精緻團

��<style> .responsive-wrapper { position: relative; padding-bottom: 56.25%; /* 16:9 aspect ratio */ height: 0; overflow: hidden; } .responsive-wrapper iframe, .responsive-wrapper img, .responsive-wrapper video { position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; } /* Horizontal Scroll Gallery Styles */ .horizontal-scroll-gallery { position: relative; overflow: hidden; margin-top: 20px; } .scroll-container { display: flex; gap: 20px; overflow-x: auto; scroll-behavior: smooth; padding: 20px 0; -webkit-overflow-scrolling: touch; scrollbar-width: thin; scrollbar-color: #43A2AE #f0f0f0; } .scroll-container::-webkit-scrollbar { height: 8px; } .scroll-container::-webkit-scrollbar-track { background: #f0f0f0; border-radius: 10px; } .scroll-container::-webkit-scrollbar-thumb { background: #43A2AE; border-radius: 10px; } .scroll-container::-webkit-scrollbar-thumb:hover { background: #358a94; } .gallery-item { flex: 0 0 auto; width: 350px; transition: transform 0.3s ease, box-shadow 0.3s ease; } .gallery-item:hover { transform: translateY(-5px); box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15); } .gallery-item-content { background: #fff; border-radius: 8px; overflow: hidden; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); } .gallery-item h5, .gallery-item .h5 { padding: 8px; margin: 0 !important; color: #000; font-size: 14px; text-align: center; background: #f8f8f8; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .gallery-item a { text-decoration: none; color: inherit; display: block; } /* Link thumbnail placeholder */ .link-thumbnail { background: linear-gradient(135deg, #43A2AE 0%, #358a94 100%); display: flex; align-items: center; justify-content: center; color: white; font-size: 48px; font-weight: bold; } /* Arrow Buttons */ .arrow-btn { position: absolute; top: 50%; transform: translateY(-50%); background: rgba(67, 162, 174, 0.8); color: white; border: none; width: 50px; height: 50px; border-radius: 50%; cursor: pointer; font-size: 24px; z-index: 10; transition: background 0.3s ease; } .arrow-btn:hover { background: rgba(67, 162, 174, 1); } .arrow-btn:disabled { background: rgba(204, 204, 204, 0.5); cursor: not-allowed; } .arrow-btn.left { left: 10px; } .arrow-btn.right { right: 10px; } @media (max-width: 768px) { .gallery-item { width: 290px; } .arrow-btn { width: 40px; height: 40px; font-size: 18px; } .horizontal-scroll-gallery { margin-top: 10px !important; } .scroll-container { padding: 15px 0 !important; gap: 15px !important; } #aq0q3Cq, #news #aq0q3Cq, #news { min-height: 260px !important; } } </style> <h2 class="sr-only">������%�b%����</h2> <div class="module-container"> <div class="main"> <div data-unicode="mdu_bKdb294vREqSp9coatRPNw" data-max-show="3" data-hover="#43A2AE" data-recovery="#000000" class="mdu_bKdb294vREqSp9coatRPNw_wrap hover-wall" id="aq0q3Cq"> <div class="container-fluid"> <!-- Horizontal Scroll Gallery --> <div class="horizontal-scroll-gallery" data-scroll-gallery="gallery1"> <button class="arrow-btn left" data-scroll-left>��c%</button> <button class="arrow-btn right" data-scroll-right>��Q%</button> <div class="scroll-container"> <!-- Gallery items will be generated from videoConfig array --> </div> </div> </div> </div> </div> </div> <script> // Horizontal Scroll Gallery Component var HorizontalScrollGallery = (function () { // Shuffle array randomly (Fisher-Yates algorithm) function shuffleArray(array) { var shuffled = array.slice(); // Create a copy for (var i = shuffled.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var temp = shuffled[i]; shuffled[i] = shuffled[j]; shuffled[j] = temp; } return shuffled; } // Generate gallery items from config function generateGalleryItems(config) { var html = ''; $.each(config, function (index, item) { if (item.type === 'image') { html += '<div class="gallery-item">' + '<div class="gallery-item-content">' + '<a target="_blank" href="' + item.link + '">' + '<div class="responsive-wrapper">' + '<img src="' + item.src + '" alt="' + item.title + '">' + '</div>' + '<div class="h5 mt-2">' + item.title + '</div>' + '</a>' + '</div>' + '</div>'; } else if (item.type === 'hls') { var titleHtml = '<div class="h5 mt-2">' + item.title + '</div>'; if (item.link) { titleHtml = '<div class="h5 mt-2"><a target="_blank" href="' + item.link + '" style="text-decoration: underline; color: inherit;">' + item.title + '</a></div>'; } html += '<div class="gallery-item">' + '<div class="gallery-item-content">' + '<div class="responsive-wrapper">' + '<video class="hls-video" data-src="' + item.src + '" controls style="width: 100%; height: 100%; object-fit: cover; background: black;" poster="' + (item.poster || '') + '"></video>' + '</div>' + titleHtml + '</div>' + '</div>'; } else if (item.type === 'link') { var thumbnailHtml = ''; if (item.thumbnail) { thumbnailHtml = '<img src="' + item.thumbnail + '" alt="' + item.title + '" onerror="this.parentElement.innerHTML=\'<div class=\\\'link-thumbnail\\\'>a"���</div>\'">'; } else { thumbnailHtml = '<div class="link-thumbnail">a"���</div>'; } html += '<div class="gallery-item">' + '<div class="gallery-item-content">' + '<a target="_blank" href="' + item.url + '">' + '<div class="responsive-wrapper">' + thumbnailHtml + '</div>' + '<div class="h5 mt-2">' + item.title + '</div>' + '</a>' + '</div>' + '</div>'; } }); return html; } function init(gallerySelector, config) { var $gallery = $(gallerySelector); if (!$gallery.length) return; var $container = $gallery.find('.scroll-container'); var $leftBtn = $gallery.find('[data-scroll-left]'); var $rightBtn = $gallery.find('[data-scroll-right]'); // Shuffle the config array for random order var shuffledConfig = shuffleArray(config); // Limit to 2 items on mobile if ($(window).width() < 768) { shuffledConfig = shuffledConfig.slice(0, 2); } // Generate and insert gallery items var galleryHTML = generateGalleryItems(shuffledConfig); $container.html(galleryHTML); var scrollAmount = 370; // Item width + gap // Scroll Left $leftBtn.on('click', function () { $container.animate({ scrollLeft: $container.scrollLeft() - scrollAmount }, 300); }); // Scroll Right $rightBtn.on('click', function () { $container.animate({ scrollLeft: $container.scrollLeft() + scrollAmount }, 300); }); // Update button states function updateButtonStates() { var scrollLeft = $container.scrollLeft(); var maxScroll = $container[0].scrollWidth - $container[0].clientWidth; $leftBtn.prop('disabled', scrollLeft <= 0); $rightBtn.prop('disabled', scrollLeft >= maxScroll); } $container.on('scroll', updateButtonStates); updateButtonStates(); // Mobile check function checkMobile() { if ($(window).width() < 768) { $gallery.find('.arrow-btn').hide(); } else { $gallery.find('.arrow-btn').show(); } } checkMobile(); $(window).on('resize', checkMobile); // Pause videos when scrolling $container.on('scroll', function () { $container.find('video').each(function () { if (!isElementInViewport(this)) { this.pause(); } }); }); function isElementInViewport(el) { var rect = el.getBoundingClientRect(); return ( rect.left >= 0 && rect.right <= (window.innerWidth || document.documentElement.clientWidth) ); } } function loadNewsPlaylist() { if (window._newsPlaylistLoaded) return; window._newsPlaylistLoaded = true; fetch('/includes/news_playlist.json?t=' + new Date().getTime()) .then(function(response) { if (!response.ok) throw new Error('Network response was not ok'); return response.json(); }) .then(function(config) { $('[data-scroll-gallery]').each(function () { init(this, config); }); // Initialize HLS for dynamically injected videos if (typeof Hls !== 'undefined' && Hls.isSupported()) { $('.hls-video').each(function() { var video = this; var src = $(video).attr('data-src'); if (src && src.endsWith('.m3u8')) { var hls = new Hls(); hls.loadSource(src); hls.attachMedia(video); } }); } }) .catch(function(error) { console.error('Error fetching news playlist configuration:', error); }); } function initAll() { if ('requestIdleCallback' in window) { requestIdleCallback(loadNewsPlaylist, { timeout: 3000 }); } else { setTimeout(loadNewsPlaylist, 1500); } ['scroll', 'touchstart', 'mousemove'].forEach(function(evt) { window.addEventListener(evt, loadNewsPlaylist, { once: true, passive: true }); }); } return { init: init, initAll: initAll }; })(); // Initialize the component (deferred to break critical request chain) HorizontalScrollGallery.initAll(); </script>

熱賣行程