json
Код: Выделить всё
[
{
"name": "Alice Novak",
"role": "COO of FutureTech",
"image": "images/alice.png",
"linkedin": "https://linkedin.com/in/reviewerLINKEDIN1",
"text": "Professional, fast and reliable results. Highly recommend."
},
{
"name": "Carlos Duran",
"role": "Founder of WebWave",
"image": "images/carlos.png",
"linkedin": "https://linkedin.com/in/reviewerLINKEDIN2",
"text": "Super helpful in scaling our outreach. Great comms."
},
{
"name": "Linda Park",
"role": "Lead at PixelNest",
"image": "images/linda.png",
"linkedin": "https://linkedin.com/in/reviewerLINKEDIN3",
"text": "Very creative! A lot of attention to detail in the work."
}
//Many more random examples below
]
Код: Выделить всё
// Global flag to notify scroll script
window.reviewsReady = false;
fetch('review.json')
.then(res => res.json())
.then(data => {
const track = document.getElementById('scrollCards');
track.innerHTML = ''; // clear any fallback
data.forEach(review => {
const card = document.createElement('div');
card.className = 'review-card';
card.innerHTML = `
[img]${review.image}[/img]
${review.name}
${review.role}
[url=${review.linkedin}]
[img]https://static.vecteezy.com/system/resources/previews/018/930/480/non_2x/linkedin-logo-linkedin-icon-transparent-free-png.png[/img]
[/url]
${review.text}
`;
track.appendChild(card);
});
// Notify that reviews are loaded
window.reviewsReady = true;
})
.catch(err => console.error("Failed to load reviews:", err));
function initReviewScroller() {
const wrapper = document.querySelector('.review-scroll-wrapper');
const track = document.getElementById('scrollCards');
const originalCards = Array.from(track.children);
const MULTIPLIER = 20;
for (let i = 0; i < MULTIPLIER - 1; i++) {
originalCards.forEach(card => track.appendChild(card.cloneNode(true)));
}
const allCards = track.querySelectorAll('.review-card');
const cardWidth = allCards[0].offsetWidth + 30;
const totalCards = allCards.length;
const totalWidth = cardWidth * totalCards;
wrapper.scrollLeft = totalWidth / 2;
let isDragging = false;
let dragStartX = 0;
let scrollStart = 0;
let pauseAuto = false;
wrapper.addEventListener('mousedown', (e) => {
isDragging = true;
pauseAuto = true;
dragStartX = e.pageX;
scrollStart = wrapper.scrollLeft;
});
wrapper.addEventListener('mouseup', () => {
isDragging = false;
pauseAuto = false;
});
wrapper.addEventListener('mouseleave', () => {
isDragging = false;
pauseAuto = false;
});
wrapper.addEventListener('mousemove', (e) => {
if (!isDragging) return;
const dx = e.pageX - dragStartX;
wrapper.scrollLeft = scrollStart - dx;
});
wrapper.addEventListener('scroll', () => {
const current = wrapper.scrollLeft;
if (current = totalWidth - wrapper.clientWidth - cardWidth) {
wrapper.scrollLeft -= totalWidth / 2;
}
});
function autoScrollStep() {
if (!pauseAuto) {
wrapper.scrollBy({ left: cardWidth, behavior: 'smooth' });
}
setTimeout(autoScrollStep, 5000);
}
setTimeout(autoScrollStep, 500);
}
// Wait for reviews to load
function waitForReviews() {
if (window.reviewsReady) {
initReviewScroller();
} else {
setTimeout(waitForReviews, 100);
}
}
waitForReviews();
Код: Выделить всё
Review of our clients
Есть ли лучший способ имитировать это: < /p>
Без огромного раздувания DOM? Я видел это на некоторых веб -сайтах, но понятия не имею, как это можно сделать ... это какая -то библиотека или что -то особенное?
Подробнее здесь: https://stackoverflow.com/questions/796 ... ched-conte