feat: replace hero video fallback shortcode with dynamic Swiper slider and enable observer settings for swiper instances
This commit is contained in:
@@ -1,56 +1,67 @@
|
|||||||
<div class="content-top">
|
<div class="content-top">
|
||||||
<div class="lc--layout-container lc--full">
|
<div class="lc--layout-container lc--full">
|
||||||
<div class="l--layout l--full">
|
<div class="l--layout l--full">
|
||||||
<div class="lr--layout-region lr--main">
|
<div class="lr--layout-region lr--main">
|
||||||
<div class="cc--component-container cc--homepage-hero">
|
<div class="cc--component-container cc--homepage-hero">
|
||||||
<div class="c--component c--homepage-hero">
|
<div class="c--component c--homepage-hero">
|
||||||
<div class="slides-container">
|
<div class="slides-container">
|
||||||
<div class="image-video-container has-video">
|
<div class="image-video-container has-video">
|
||||||
<img
|
<img
|
||||||
src="https://www.umass.edu/sites/default/files/styles/1_1_1920x1920/public/2025-09/250616_UMASS_4515.jpg"
|
src="https://www.umass.edu/sites/default/files/styles/1_1_1920x1920/public/2025-09/250616_UMASS_4515.jpg"
|
||||||
alt="Students collaborate using a driving simulator in the UMass Center for Transportation."
|
alt="Students collaborate using a driving simulator in the UMass Center for Transportation."
|
||||||
srcset="
|
srcset="
|
||||||
https://www.umass.edu/sites/default/files/styles/1_1_1920x1920/public/2025-09/250616_UMASS_4515.jpg?h=9855f42d&itok=d27r8GaT 1920w
|
https://www.umass.edu/sites/default/files/styles/1_1_1920x1920/public/2025-09/250616_UMASS_4515.jpg?h=9855f42d&itok=d27r8GaT 1920w
|
||||||
"
|
"
|
||||||
/>
|
/>
|
||||||
<div class="f--ambient-video" id="hero-ambient-video">
|
<div class="f--ambient-video" id="hero-ambient-video">
|
||||||
<video role="presentation" tabindex="-1" loop="" autoplay="" playsinline="" muted=""
|
<video
|
||||||
id="hero-video" onerror="handleVideoError()">
|
role="presentation"
|
||||||
<source
|
tabindex="-1"
|
||||||
src="http://localhost:8080/uploads/2026/07/9375f45b-027a-4fb4-bd18-66889309280d.mp4"
|
loop=""
|
||||||
type="video/mp4" onerror="handleVideoError()" />
|
autoplay=""
|
||||||
</video>
|
playsinline=""
|
||||||
</div>
|
muted=""
|
||||||
|
id="hero-video"
|
||||||
|
onerror="handleVideoError()"
|
||||||
|
>
|
||||||
|
<source
|
||||||
|
src="http://localhost:8080/uploads/2026/07/9375f45b-027a-4fb4-bd18-66889309280d.mp4"
|
||||||
|
type="video/mp4"
|
||||||
|
onerror="handleVideoError()"
|
||||||
|
/>
|
||||||
|
</video>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="hero-video-fallback"
|
<div
|
||||||
style="display: none; position: absolute; top:0; left:0; width:100%; height:100%; z-index: 2;">
|
id="hero-video-fallback"
|
||||||
<th:block
|
style="display: none; position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 2"
|
||||||
th:utext="${@hookManager.applyFilters('the_content', '[plugin:swiper-slider slug=''video-fallback'']')}">
|
>
|
||||||
</th:block>
|
<th:block th:utext="${@hookManager.applyFilters('the_content', '[plugin:swiper-slider slug=''video-fallback-slider'']')}">
|
||||||
</div>
|
</th:block>
|
||||||
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
function handleVideoError() {
|
function handleVideoError() {
|
||||||
var vidContainer = document.getElementById('hero-ambient-video');
|
var vidContainer = document.getElementById('hero-ambient-video');
|
||||||
if(vidContainer) vidContainer.style.display = 'none';
|
if (vidContainer) vidContainer.style.display = 'none';
|
||||||
|
|
||||||
var controls = document.querySelector('.video-controls');
|
var controls = document.querySelector('.video-controls');
|
||||||
if(controls) controls.style.display = 'none';
|
if (controls) controls.style.display = 'none';
|
||||||
|
|
||||||
var fallback = document.getElementById('hero-video-fallback');
|
var fallback = document.getElementById('hero-video-fallback');
|
||||||
if(fallback) fallback.style.display = 'block';
|
if (fallback) fallback.style.display = 'block';
|
||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener('DOMContentLoaded', function() {
|
window.addEventListener('DOMContentLoaded', function () {
|
||||||
var v = document.getElementById('hero-video');
|
var v = document.getElementById('hero-video');
|
||||||
if (v && v.error) {
|
if (v && v.error) {
|
||||||
handleVideoError();
|
handleVideoError();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<div class="video-controls" data-once="ambientVideo">
|
<div class="video-controls" data-once="ambientVideo">
|
||||||
<div class="video-controls-inner">
|
<div class="video-controls-inner">
|
||||||
<button aria-labelledby="pauseBtn" class="video-button video-pause-button">
|
<button aria-labelledby="pauseBtn" class="video-button video-pause-button">
|
||||||
<svg height="14" viewBox="0 0 10 14" width="10" xmlns="http://www.w3.org/2000/svg">
|
<svg height="14" viewBox="0 0 10 14" width="10" xmlns="http://www.w3.org/2000/svg">
|
||||||
<title id="pauseBtn">Pause Background Video</title>
|
<title id="pauseBtn">Pause Background Video</title>
|
||||||
<path
|
<path
|
||||||
@@ -61,7 +72,7 @@
|
|||||||
></path>
|
></path>
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
<button aria-labelledby="playBtn" class="video-button video-play-button">
|
<button aria-labelledby="playBtn" class="video-button video-play-button">
|
||||||
<svg height="29" viewBox="0 0 29 29" width="29" xmlns="http://www.w3.org/2000/svg">
|
<svg height="29" viewBox="0 0 29 29" width="29" xmlns="http://www.w3.org/2000/svg">
|
||||||
<title id="playBtn">Play Background Video</title>
|
<title id="playBtn">Play Background Video</title>
|
||||||
<path
|
<path
|
||||||
@@ -72,67 +83,76 @@
|
|||||||
></path>
|
></path>
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="text-container centered">
|
|
||||||
<div class="slide-text-container-inner">
|
|
||||||
<h3>
|
|
||||||
<a href="https://www.umass.edu/gateway/why-umass">Stroke International School
|
|
||||||
2026.</a>
|
|
||||||
</h3>
|
|
||||||
<div class="f--field f--button">
|
|
||||||
<a href="https://www.umass.edu/gateway/why-umass"
|
|
||||||
class="button-secondary button-context-dark"
|
|
||||||
aria-label="Learn More Learn more about UMass Amherst."
|
|
||||||
data-component-id="umass_base:button">
|
|
||||||
<span class="button-text"> Learn More </span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<nav class="mc--menu mc--info-menu"
|
|
||||||
th:if="${infoMenu != null and not #lists.isEmpty(infoMenu.items)}">
|
|
||||||
<ul class="menu m--menu m--info-menu">
|
|
||||||
<li class="menu-item menu-item--expanded">
|
|
||||||
<details class="utility-button-wrapper mc--info-menu-container">
|
|
||||||
<summary type="button"
|
|
||||||
aria-label="Display submenu for Information menu"
|
|
||||||
aria-expanded="false" aria-haspopup="true"
|
|
||||||
class="utility-button arrow-toggle information-for-toggle">
|
|
||||||
<span th:text="${infoMenu.name}">Info For</span>
|
|
||||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
viewBox="0 0 16 7" enable-background="new 0 0 16 7"
|
|
||||||
xml:space="preserve" width="16" height="7" class="arrow">
|
|
||||||
<polygon fill-rule="evenodd" clip-rule="evenodd"
|
|
||||||
fill="#ffffff" points="7,7 0,0 16,0 "></polygon>
|
|
||||||
</svg>
|
|
||||||
</summary>
|
|
||||||
<div class="submenu-wrapper">
|
|
||||||
<ul class="submenu">
|
|
||||||
<li class="menu-item" th:each="item : ${infoMenu.items}">
|
|
||||||
<a th:href="${item.url}"
|
|
||||||
th:text="${item.label}">Prospective Students</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</details>
|
|
||||||
<div class="submenu-wrapper-desktop">
|
|
||||||
<ul class="submenu">
|
|
||||||
<li class="menu-item" th:each="item : ${infoMenu.items}">
|
|
||||||
<a th:href="${item.url}" th:text="${item.label}">Prospective
|
|
||||||
Students</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="text-container centered">
|
||||||
|
<div class="slide-text-container-inner">
|
||||||
|
<h3>
|
||||||
|
<a href="https://www.umass.edu/gateway/why-umass">Stroke International School 2026.</a>
|
||||||
|
</h3>
|
||||||
|
<div class="f--field f--button">
|
||||||
|
<a
|
||||||
|
href="https://www.umass.edu/gateway/why-umass"
|
||||||
|
class="button-secondary button-context-dark"
|
||||||
|
aria-label="Learn More Learn more about UMass Amherst."
|
||||||
|
data-component-id="umass_base:button"
|
||||||
|
>
|
||||||
|
<span class="button-text"> Learn More </span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<nav class="mc--menu mc--info-menu" th:if="${infoMenu != null and not #lists.isEmpty(infoMenu.items)}">
|
||||||
|
<ul class="menu m--menu m--info-menu">
|
||||||
|
<li class="menu-item menu-item--expanded">
|
||||||
|
<details class="utility-button-wrapper mc--info-menu-container">
|
||||||
|
<summary
|
||||||
|
type="button"
|
||||||
|
aria-label="Display submenu for Information menu"
|
||||||
|
aria-expanded="false"
|
||||||
|
aria-haspopup="true"
|
||||||
|
class="utility-button arrow-toggle information-for-toggle"
|
||||||
|
>
|
||||||
|
<span th:text="${infoMenu.name}">Info For</span>
|
||||||
|
<svg
|
||||||
|
version="1.1"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
x="0px"
|
||||||
|
y="0px"
|
||||||
|
viewBox="0 0 16 7"
|
||||||
|
enable-background="new 0 0 16 7"
|
||||||
|
xml:space="preserve"
|
||||||
|
width="16"
|
||||||
|
height="7"
|
||||||
|
class="arrow"
|
||||||
|
>
|
||||||
|
<polygon fill-rule="evenodd" clip-rule="evenodd" fill="#ffffff" points="7,7 0,0 16,0 "></polygon>
|
||||||
|
</svg>
|
||||||
|
</summary>
|
||||||
|
<div class="submenu-wrapper">
|
||||||
|
<ul class="submenu">
|
||||||
|
<li class="menu-item" th:each="item : ${infoMenu.items}">
|
||||||
|
<a th:href="${item.url}" th:text="${item.label}">Prospective Students</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
<div class="submenu-wrapper-desktop">
|
||||||
|
<ul class="submenu">
|
||||||
|
<li class="menu-item" th:each="item : ${infoMenu.items}">
|
||||||
|
<a th:href="${item.url}" th:text="${item.label}">Prospective Students</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
<article class="relative p-3 lg:p-4 bg-white rounded-lg border border-gray-100 group flex flex-col justify-between text-left w-full h-full">
|
<article class="relative p-3 lg:p-4 bg-white rounded-lg border border-gray-100 group flex flex-col justify-between text-left w-full h-full">
|
||||||
<div class="flex flex-col gap-3.5">
|
<div class="flex flex-col gap-3.5">
|
||||||
<a class="relative overflow-hidden rounded block aspect-[9/5]" href="{{linkUrl}}" th:href="@{${item.linkUrl}}">
|
<a class="relative overflow-hidden rounded block aspect-[9/5]" href="{{linkUrl}}" th:href="@{${item.linkUrl}}">
|
||||||
<img alt="{{title}}" th:alt="${item.title}" class="object-cover h-full w-full" src="{{imageUrl}}" th:src="@{${item.imageUrl}}"/>
|
<img alt="{{title}}" th:alt="${item.title}" class="object-cover h-full w-full" data-src="{{imageUrl}}" th:src="@{${item.imageUrl}}"/>
|
||||||
<div class="absolute inset-0 w-full h-full bg-black/40 opacity-0 lg:group-hover:opacity-100 duration-300 ease-in-out"></div>
|
<div class="absolute inset-0 w-full h-full bg-black/40 opacity-0 lg:group-hover:opacity-100 duration-300 ease-in-out"></div>
|
||||||
</a>
|
</a>
|
||||||
<div class="px-1.5 w-full flex flex-col gap-3.5">
|
<div class="px-1.5 w-full flex flex-col gap-3.5">
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
+7
@@ -367,6 +367,13 @@ document.addEventListener("DOMContentLoaded", function() {
|
|||||||
new Swiper('.swiper-{{slug}}', {
|
new Swiper('.swiper-{{slug}}', {
|
||||||
slidesPerView: 'auto',
|
slidesPerView: 'auto',
|
||||||
spaceBetween: 16,
|
spaceBetween: 16,
|
||||||
|
observer: true,
|
||||||
|
observeParents: true,
|
||||||
|
autoplay: {
|
||||||
|
delay: 3500,
|
||||||
|
disableOnInteraction: false,
|
||||||
|
pauseOnMouseEnter: true,
|
||||||
|
},
|
||||||
navigation: {
|
navigation: {
|
||||||
nextEl: '.btn-navigation-{{slug}}-next',
|
nextEl: '.btn-navigation-{{slug}}-next',
|
||||||
prevEl: '.btn-navigation-{{slug}}-prev',
|
prevEl: '.btn-navigation-{{slug}}-prev',
|
||||||
|
|||||||
@@ -1431,3 +1431,7 @@ figure.table table tr:hover {
|
|||||||
color: #9b1b1b !important;
|
color: #9b1b1b !important;
|
||||||
transform: scale(1.08);
|
transform: scale(1.08);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.h-full {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
@@ -9,6 +9,8 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
const courseSwiper = new Swiper('.courseSwiper', {
|
const courseSwiper = new Swiper('.courseSwiper', {
|
||||||
loop: true,
|
loop: true,
|
||||||
spaceBetween: 20, // Khoảng cách giữa các card
|
spaceBetween: 20, // Khoảng cách giữa các card
|
||||||
|
observer: true,
|
||||||
|
observeParents: true,
|
||||||
autoplay: {
|
autoplay: {
|
||||||
delay: 3500, // Tự động trượt sau 3.5 giây
|
delay: 3500, // Tự động trượt sau 3.5 giây
|
||||||
disableOnInteraction: false,
|
disableOnInteraction: false,
|
||||||
|
|||||||
@@ -20,6 +20,14 @@
|
|||||||
}
|
}
|
||||||
/* Desktop/Tablet: Video most, Slide second, Image last */
|
/* Desktop/Tablet: Video most, Slide second, Image last */
|
||||||
@media (min-width: 769px) {
|
@media (min-width: 769px) {
|
||||||
|
.image-video-container {
|
||||||
|
display: grid;
|
||||||
|
grid-template-rows: 100%;
|
||||||
|
}
|
||||||
|
.image-video-container > * {
|
||||||
|
grid-column: 1;
|
||||||
|
grid-row: 1;
|
||||||
|
}
|
||||||
.image-video-container > img {
|
.image-video-container > img {
|
||||||
z-index: 1 !important;
|
z-index: 1 !important;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -29,12 +37,9 @@
|
|||||||
#hero-video-fallback {
|
#hero-video-fallback {
|
||||||
z-index: 2 !important;
|
z-index: 2 !important;
|
||||||
}
|
}
|
||||||
#hero-ambient-video {
|
/* #hero-ambient-video {
|
||||||
z-index: 3 !important;
|
z-index: 3 !important;
|
||||||
}
|
} */
|
||||||
.content-top .text-container.centered {
|
|
||||||
z-index: 4 !important;
|
|
||||||
}
|
|
||||||
video#hero-video {
|
video#hero-video {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@@ -69,8 +74,29 @@
|
|||||||
id="hero-video-fallback"
|
id="hero-video-fallback"
|
||||||
style="display: none; position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 2"
|
style="display: none; position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 2"
|
||||||
>
|
>
|
||||||
<th:block th:utext="${hookManager.applyFilters('the_content', '[plugin:swiper-slider slug=''video-fallback'']')}">
|
<div class="swiper hero-fallback-swiper w-full h-full">
|
||||||
</th:block>
|
<div class="swiper-wrapper">
|
||||||
|
<!-- Dynamic Slides from Plugin Database -->
|
||||||
|
<th:block th:utext="${hookManager.applyFilters('swiper_slider_items', 'video-fallback-slider')}"></th:block>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
if (typeof Swiper !== 'undefined') {
|
||||||
|
new Swiper('.hero-fallback-swiper', {
|
||||||
|
effect: 'fade', // Optional: smooth fade transition for hero
|
||||||
|
loop: true,
|
||||||
|
observer: true,
|
||||||
|
observeParents: true,
|
||||||
|
autoplay: {
|
||||||
|
delay: 4000,
|
||||||
|
disableOnInteraction: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|||||||
+23
-2
@@ -73,8 +73,29 @@
|
|||||||
id="hero-video-fallback"
|
id="hero-video-fallback"
|
||||||
style="display: none; position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 2"
|
style="display: none; position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 2"
|
||||||
>
|
>
|
||||||
<th:block th:utext="${hookManager.applyFilters('the_content', '[plugin:swiper-slider slug=''video-fallback'']')}">
|
<div class="swiper hero-fallback-swiper w-full h-full">
|
||||||
</th:block>
|
<div class="swiper-wrapper">
|
||||||
|
<!-- Dynamic Slides from Plugin Database -->
|
||||||
|
<th:block th:utext="${hookManager.applyFilters('swiper_slider_items', 'video-fallback-slider')}"></th:block>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
if (typeof Swiper !== 'undefined') {
|
||||||
|
new Swiper('.hero-fallback-swiper', {
|
||||||
|
effect: 'fade', // Optional: smooth fade transition for hero
|
||||||
|
loop: true,
|
||||||
|
observer: true,
|
||||||
|
observeParents: true,
|
||||||
|
autoplay: {
|
||||||
|
delay: 4000,
|
||||||
|
disableOnInteraction: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|||||||
Reference in New Issue
Block a user