Scroll Animation Enhancement
February 11, 2025 · AI Conversations
echo '';
foreach ($settings['scroll_list'] as $index => $item) {
echo '';
break;
}
echo '';
echo '';
// Add a static title above the dynamic items
// echo 'Unsere besten Böckmann-Anhänger im Überblick:';
foreach ($settings['scroll_list'] as $index => $item) {
$opacity='0';
if($index==0)
$opacity='1';
echo '';
echo '' . ($item['timeline_title']) . '';
echo '' . wp_kses_post($item['timeline_desc']) . '';
echo '' . esc_html($item['button_text']) . '';
echo '';
}
echo '';
echo '';
We have above sturcutue
document.addEventListener('DOMContentLoaded', function () {
const scrollContainer = document.querySelector('.post-blog-scroll');
if (scrollContainer) {
const items = scrollContainer.querySelectorAll('.post-scroll-item');
const contentContainer = scrollContainer.querySelector('.post-scroll-content');
const imageContainer = document.querySelector('.post-scroll-image');
let activeIndex = -1; // Track the last active item
let lastImageSrc = ''; // Track last image to avoid unnecessary updates
contentContainer.addEventListener('scroll', function () {
let closestItemIndex = -1;
let closestDistance = Infinity;
items.forEach((item, index) => {
const itemTop = item.offsetTop – contentContainer.offsetTop;
const distance = Math.abs(contentContainer.scrollTop – itemTop);
if (distance < closestDistance) {
closestDistance = distance;
closestItemIndex = index;
}
});
if (closestItemIndex !== -1 && closestItemIndex !== activeIndex) {
// Reset previous active item
if (activeIndex !== -1) {
items[activeIndex].style.opacity = '0';
}
// Update new active item
activeIndex = closestItemIndex;
items[activeIndex].style.opacity = '1';
// Change image only if needed
const imgSrc = items[activeIndex].getAttribute('data-img');
if (imgSrc && imageContainer && imgSrc !== lastImageSrc) {
imageContainer.innerHTML = “;
lastImageSrc = imgSrc;
}
}
});
}
});
need to change post-scroll-item on every single scroll
### Key Changes:
1. **Use `scroll` Event More Effectively** – The event listener already tracks the closest element, but we ensure it reacts to even small scroll movements.
2. **Improve Opacity Handling** – Instead of just setting `opacity`, we can use `classList.toggle()` for better control.
3. **Ensure Image Updates on Each Scroll Move** – Modify the image update logic so that the transition feels fluid.
### Updated Code:
document.addEventListener('DOMContentLoaded', function () {
const scrollContainer = document.querySelector('.post-blog-scroll');
if (scrollContainer) {
const items = scrollContainer.querySelectorAll('.post-scroll-item');
const contentContainer = scrollContainer.querySelector('.post-scroll-content');
const imageContainer = document.querySelector('.post-scroll-image');
let activeIndex = -1; // Track the last active item
let lastImageSrc = ''; // Track last image to avoid unnecessary updates
contentContainer.addEventListener('scroll', function () {
let closestItemIndex = -1;
let closestDistance = Infinity;
items.forEach((item, index) => {
const itemTop = item.offsetTop - contentContainer.offsetTop;
const distance = Math.abs(contentContainer.scrollTop - itemTop);
if (distance < closestDistance) {
closestDistance = distance;
closestItemIndex = index;
}
});
if (closestItemIndex !== -1 && closestItemIndex !== activeIndex) {
// Remove 'active' class from previous active item
if (activeIndex !== -1) {
items[activeIndex].classList.remove('active');
}
// Update new active item
activeIndex = closestItemIndex;
items[activeIndex].classList.add('active');
// Change image only if needed
const imgSrc = items[activeIndex].getAttribute('data-img');
if (imgSrc && imageContainer && imgSrc !== lastImageSrc) {
imageContainer.innerHTML = `<img src="${imgSrc}" class="scroll-img-post-${activeIndex}" alt="Scroll Image" />`;
lastImageSrc = imgSrc;
}
}
});
}
});
### CSS Enhancement (Smooth Transition):
.post-scroll-item {
opacity: 0;
transition: opacity 0.3s ease-in-out;
}
.post-scroll-item.active {
opacity: 1;
}
### Changes & Improvements:
✔ **Smooth Transitions** – The `.active` class ensures a smooth fade-in effect for the active item.
✔ **More Frequent Updates** – The script now updates items on every small scroll.
✔ **Better Image Update Handling** – Avoids unnecessary image changes while ensuring an updated display.
Let me know if you need further refinements! 🚀
## **Updated Approach**
1. **Directly Adjust `opacity` Instead of Class-Based Activation**
– This ensures immediate effect without dependency on `.active` class.
2. **Use `getBoundingClientRect()` for Accurate Item Positioning**
– Instead of relying on `offsetTop`, `getBoundingClientRect()` provides precise positioning relative to the viewport.
3. **Ensure the Image Updates Correctly**
– Only update if the image has changed.
—
### **Final Updated Code:**
document.addEventListener('DOMContentLoaded', function () {
const scrollContainer = document.querySelector('.post-blog-scroll');
if (scrollContainer) {
const items = scrollContainer.querySelectorAll('.post-scroll-item');
const contentContainer = scrollContainer.querySelector('.post-scroll-content');
const imageContainer = document.querySelector('.post-scroll-image img');
let activeIndex = -1; // Track the last active item
let lastImageSrc = ''; // Track last image to avoid unnecessary updates
contentContainer.addEventListener('scroll', function () {
let closestItemIndex = -1;
let closestDistance = Infinity;
items.forEach((item, index) => {
const rect = item.getBoundingClientRect();
const containerRect = contentContainer.getBoundingClientRect();
const itemTop = rect.top - containerRect.top; // Relative position
const distance = Math.abs(itemTop);
if (distance < closestDistance) {
closestDistance = distance;
closestItemIndex = index;
}
});
if (closestItemIndex !== -1 && closestItemIndex !== activeIndex) {
// Reset all items to low opacity
items.forEach((el, idx) => {
el.style.opacity = idx === closestItemIndex ? '1' : '0';
});
// Update new active item
activeIndex = closestItemIndex;
// Change image only if needed
const imgSrc = items[activeIndex].getAttribute('data-img');
if (imgSrc && imgSrc !== lastImageSrc) {
imageContainer.src = imgSrc;
lastImageSrc = imgSrc;
}
}
});
}
});
—
### **CSS (Ensure Smooth Transition)**
.post-scroll-item {
opacity: 0;
transition: opacity 0.4s ease-in-out;
}
.post-scroll-item:first-child {
opacity: 1; /* Ensure the first item is visible by default */
}
—
### **Key Fixes & Features**
✅ **Accurate Scroll Detection** – Uses `getBoundingClientRect()` to get exact positions.
✅ **Smooth Opacity Change** – Instead of adding/removing classes, directly modifies `opacity`.
✅ **Image Updates Efficiently** – Prevents unnecessary reloading by checking `lastImageSrc`.
✅ **Fixes the Issue of Items Not Updating on Scroll**
—
### **What You Need to Ensure:**
– The `.post-scroll-image` has an “ inside it initially (e.g., the first item’s image).
– The `.post-scroll-content` has enough items to trigger scrolling.
– The JavaScript is inside a “ tag at the bottom of the page or inside `DOMContentLoaded`.
This should work perfectly! 🎯 Let me know if you face any issues. 🚀
—
## **Final Optimized JavaScript:**
document.addEventListener('DOMContentLoaded', function () {
const scrollContainer = document.querySelector('.post-blog-scroll');
if (scrollContainer) {
const items = scrollContainer.querySelectorAll('.post-scroll-item');
const contentContainer = scrollContainer.querySelector('.post-scroll-content');
const imageContainer = scrollContainer.querySelector('.post-scroll-image img');
let activeIndex = -1; // Track the last active item
let lastImageSrc = ''; // Track last image to avoid unnecessary updates
contentContainer.addEventListener('scroll', function () {
let closestItemIndex = -1;
let closestDistance = Infinity;
items.forEach((item, index) => {
const rect = item.getBoundingClientRect();
const containerRect = contentContainer.getBoundingClientRect();
const itemTop = rect.top - containerRect.top; // Get relative position
const distance = Math.abs(itemTop);
if (distance < closestDistance) {
closestDistance = distance;
closestItemIndex = index;
}
});
if (closestItemIndex !== -1 && closestItemIndex !== activeIndex) {
// Reset opacity for all items
items.forEach((el, idx) => {
el.style.opacity = idx === closestItemIndex ? '1' : '0';
});
// Update the new active index
activeIndex = closestItemIndex;
// Change image only if necessary
const imgSrc = items[activeIndex].getAttribute('data-img');
if (imgSrc && imgSrc !== lastImageSrc) {
imageContainer.src = imgSrc;
lastImageSrc = imgSrc;
}
}
});
}
});
—
## **CSS for Smooth Transition**
.post-scroll-item {
opacity: 0;
transition: opacity 0.5s ease-in-out;
}
.post-scroll-item:first-child {
opacity: 1; /* Ensure the first item is visible initially */
}
.post-scroll-image img {
transition: opacity 0.5s ease-in-out;
}
—
## **How This Works**
✅ **Smooth Scroll Effect** – The `post-scroll-item` updates on every small scroll movement.
✅ **Accurate Item Tracking** – Uses `getBoundingClientRect()` to determine the closest item.
✅ **Efficient Image Updates** – Changes the image only when necessary.
✅ **Smooth Opacity Changes** – Ensures a fading effect for items and images.
This will now apply the scrolling effect properly under your `.post-blog-scroll` container.
Let me know if you need further refinements! 🚀