לצפייה
בפרויקט

קלפים מוערמים: הופכים את הגלילה של הלופ למיוחדת

במקום לגלול בלי סוף, תנו למשתמשים שלכם להחליק קלפים אחד אחרי השני – בדיוק כמו באפליקציות הכי אהובות.

תוכן עניינים

נמאס לכם מגלילה אינסופית ומשעממת? דמיינו עמוד באתר שלכם שבו התוכן מוצג כקלפים אינטראקטיביים שניתן להחליק בקלות אחד אחרי השני – ממש כמו באפליקציות שאתם מכירים ואוהבים. "קלפים מוערמים" הופכים את הגלילה המסורתית לחוויה דינמית, מרתקת ואינטואיטיבית עבור המשתמשים שלכם.

למה "קלפים מוערמים"? כי זה פשוט עובד!

כולנו מכירים את הקסם הזה: אתה פותח אפליקציה שמציגה תוכן בקלפים, ופתאום אתה מוצא את עצמך מחליק בלי הפסקה. בדיוק את האפקט הזה אתם יכולים ליצור באתר שלכם. תנועת ההחלקה טבעית, מוכרת וממכרת, והיא הופכת את הניווט לפעילות מהנה שמעודדת את המשתמשים להמשיך ולגלות עוד תוכן. במקום עמוד עמוס במידע, המשתמש מתמקד בקלף אחד בכל פעם, מה שמפחית עומס ויזואלי ומשפר את המיקוד.

אז מה זה אומר בפועל?

המשתמשים שלכם יישארו יותר זמן באתר, יצפו ביותר תכנים, ובעיקר – יזכרו את החוויה כחדשנית ומהנה. זה לא רק עיצוב יפה; זוהי אסטרטגיה עוצמתית להגברת מעורבות המשתמשים ולבידול האתר שלכם מהמתחרים.

מתי כדאי להשתמש ב"קלפים מוערמים" – בקצרה:

"קלפים מוערמים" הם פתרון אידיאלי למקרים בהם אתם רוצים להציג תוכן ויזואלי ועשיר בדרך אינטראקטיבית וממכרת, במיוחד במובייל, לדוגמה:

  • אתרי פורטפוליו: הצגת פרויקטים, עבודות אמנות, או קטלוגים ויזואליים.
  • אתרי מתכונים: הצגת מתכון אחד בכל קלף, או שלבי הכנה ממוקדים.
  • אתרי בלוגים ואתרי חדשות: פירוק פוסט ארוך לטיפים קצרים, עובדות מהירות או סיפורים ממוקדים.
  • אתרי מכירות: הצגת מוצרים בודדים, במיוחד בתחומי אופנה, קוסמטיקה ותכשיטים.
  • אתרי היכרויות: הצגת פרופילים.
  • אתרי תיירות: הצגת יעדים או אטרקציות ספציפיות.

ככה מטמיעים את הקוד באתר:

1. הוספת הקוד: גררו ווידג'ט "HTML" באלמנטור מעל לווידג'ט "Loop Grid" או "Listing Grid" של JetEngine) והדביקו בו את הקוד המתאים.

2. הגדרת קלאס ייחודי: בחרו את ווידג'ט ה-"Loop Grid" , עברו ללשונית "מתקדם" ובשדה "CSS Class " הוסיפו את הקלאס: stacked-cards

קוד גלילה ללופ גריד אלמנטור במובייל

<style>

/**
 * stacked-cards for Elementor
 * Developed by Twist | https://twist-digital.co.il/ 
 */
 
    @media (max-width: 480px) {
        :root {
            --card-perspective: 700px;
            --card-z-offset: 12px;
            --card-y-offset: 7px;
            --card-max-z-index: 100;
            --card-swap-duration: 0.25s;
            --swipe-x: 0px;
            --swipe-rotate: 0deg;
        }

        .stacked-cards .elementor-loop-container,
        .stacked-cards .e-loop-container {
            height: 360px;
            position: relative;
            perspective: var(--card-perspective);
            user-select: none;
            touch-action: pan-y pinch-zoom;
            margin: 0 auto;
            display: block !important;
        }

        .stacked-cards .elementor-loop-item,
        .stacked-cards .e-loop-item {
            position: absolute !important;
            width: 100% !important;
            height: 100% !important;
            background: white;
            border-radius: 16px;
            cursor: grab;
            overflow: hidden;
            transform: 
                translateZ(calc(-1 * var(--card-z-offset) * var(--i, 0)))
                translateY(calc(var(--card-y-offset) * var(--i, 0)))
                translateX(var(--swipe-x, 0px)) 
                rotateY(var(--swipe-rotate, 0deg));
            transition: transform var(--card-swap-duration) ease, opacity var(--card-swap-duration) ease;
            will-change: transform;
            backface-visibility: hidden;
            z-index: calc(var(--card-max-z-index) - var(--i, 0));
            margin: 0 !important;
            display: flex !important;
            flex-direction: column !important;
            box-shadow: 0 4px 20px rgba(0,0,0,0.1);
        }

        .stacked-cards .elementor-loop-item:active,
        .stacked-cards .e-loop-item:active {
            cursor: grabbing;
        }
    }
    </style>

    <script>
    class ElementorCardSlider {
        constructor(container) {
            this.container = container;
            this.cards = [...container.querySelectorAll('.elementor-loop-item, .e-loop-item')];
            this.isSwiping = false;
            this.isScrolling = false;
            this.startX = 0;
            this.currentX = 0;
            this.startY = 0;
            this.currentY = 0;
            this.animationFrameId = null;
            this.startTime = 0;
            this.hasMoved = false;
            this.directionDetermined = false;
            
            this.init();
        }

        init() {
            if (this.cards.length === 0) return;
            this.updatePositions();
            this.addEventListeners();
        }

        getDurationFromCSS(variableName, element = document.documentElement) {
            const value = getComputedStyle(element)?.getPropertyValue(variableName)?.trim();
            if (!value) return 250;
            if (value.endsWith('ms')) return parseFloat(value);
            if (value.endsWith('s')) return parseFloat(value) * 1000;
            return parseFloat(value) || 250;
        }

        getActiveCard() {
            return this.cards[0];
        }

        updatePositions() {
            this.cards.forEach((card, i) => {
                card.style.setProperty('--i', i);
                card.style.setProperty('--swipe-x', '0px');
                card.style.setProperty('--swipe-rotate', '0deg');
                card.style.opacity = '1';
                card.style.transform = `
                    translateZ(calc(-1 * var(--card-z-offset) * ${i}))
                    translateY(calc(var(--card-y-offset) * ${i}))
                    translateX(var(--swipe-x, 0px)) 
                    rotateY(var(--swipe-rotate, 0deg))
                `;
            });
        }

        applySwipeStyles(deltaX) {
            const card = this.getActiveCard();
            if (!card) return;
            
            card.style.setProperty('--swipe-x', `${deltaX}px`);
            card.style.setProperty('--swipe-rotate', `${deltaX * 0.15}deg`);
            card.style.opacity = 1 - Math.min(Math.abs(deltaX) / 120, 1) * 0.6;
        }

        resetStates() {
            this.isSwiping = false;
            this.isScrolling = false;
            this.startX = this.currentX = 0;
            this.startY = this.currentY = 0;
            this.startTime = 0;
            this.hasMoved = false;
            this.directionDetermined = false;
            
            const card = this.getActiveCard();
            if (card) {
                card.style.transition = `transform var(--card-swap-duration) ease, opacity var(--card-swap-duration) ease`;
            }
        }

        handleStart(clientX, clientY, event) {
            if (this.isSwiping || this.isScrolling) return;
            
            this.startX = this.currentX = clientX;
            this.startY = this.currentY = clientY;
            this.startTime = Date.now();
            this.hasMoved = false;
            this.isSwiping = false;
            this.isScrolling = false;
            this.directionDetermined = false;
            
            const card = this.getActiveCard();
            if (card) {
                card.style.transition = 'none';
            }
        }

        handleMove(clientX, clientY, event) {
            if (!this.startTime) return;
            
            const deltaX = clientX - this.startX;
            const deltaY = clientY - this.startY;
            const absDeltaX = Math.abs(deltaX);
            const absDeltaY = Math.abs(deltaY);
            const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
            
            if (distance > 5 && !this.directionDetermined) {
                this.hasMoved = true;
                this.directionDetermined = true;
                
                if (absDeltaX > absDeltaY * 0.8) {
                    this.isSwiping = true;
                    this.isScrolling = false;
                } else if (absDeltaY > absDeltaX * 0.8) {
                    this.isScrolling = true;
                    this.isSwiping = false;
                    this.resetStates();
                    return;
                }
            }
            
            if (this.isSwiping && !this.isScrolling) {
                if (event && event.preventDefault) {
                    event.preventDefault();
                }
                
                cancelAnimationFrame(this.animationFrameId);
                this.animationFrameId = requestAnimationFrame(() => {
                    this.currentX = clientX;
                    this.currentY = clientY;
                    this.applySwipeStyles(deltaX);
                    
                    if (Math.abs(deltaX) > 30) {
                        this.handleEnd();
                    }
                });
            }
        }

        handleEnd(event) {
            if (!this.startTime) return;
            
            const touchDuration = Date.now() - this.startTime;
            const deltaX = this.currentX - this.startX;
            
            cancelAnimationFrame(this.animationFrameId);
            
            if (this.isScrolling) {
                this.resetStates();
                return;
            }
            
            if (!this.hasMoved && touchDuration < 200) {
                this.handleClick(event);
            } else if (this.isSwiping) {
                this.handleSwipe(deltaX);
            } else {
                this.resetCard();
            }
            
            this.resetStates();
        }
        
        handleClick(event) {
            const card = this.getActiveCard();
            if (card) {
                const link = card.querySelector('a[href]');
                if (link) {
                    const href = link.getAttribute('href');
                    const target = link.getAttribute('target');
                    
                    if (target === '_blank') {
                        window.open(href, '_blank');
                    } else {
                        window.location.href = href;
                    }
                }
            }
        }
        
        handleSwipe(deltaX) {
            const threshold = 30;
            const duration = this.getDurationFromCSS('--card-swap-duration');
            const card = this.getActiveCard();
            
            if (card) {
                card.style.transition = `transform ${duration}ms ease, opacity ${duration}ms ease`;
                
                if (Math.abs(deltaX) > threshold) {
                    const direction = Math.sign(deltaX);
                    card.style.setProperty('--swipe-x', `${direction * 400}px`);
                    card.style.setProperty('--swipe-rotate', `${direction * 25}deg`);
                    
                    setTimeout(() => {
                        card.style.setProperty('--swipe-rotate', `${-direction * 15}deg`);
                    }, duration * 0.4);
                    
                    setTimeout(() => {
                        this.cards = [...this.cards.slice(1), card];
                        this.updatePositions();
                    }, duration);
                } else {
                    this.resetCard();
                }
            }
        }
        
        resetCard() {
            this.applySwipeStyles(0);
        }

        addEventListeners() {
            this.container.addEventListener('touchstart', (e) => {
                this.handleStart(e.touches[0].clientX, e.touches[0].clientY, e);
            }, { passive: false });

            this.container.addEventListener('touchmove', (e) => {
                if (this.startTime) {
                    this.handleMove(e.touches[0].clientX, e.touches[0].clientY, e);
                }
            }, { passive: false });

            this.container.addEventListener('touchend', (e) => {
                this.handleEnd(e);
            }, { passive: false });

            this.container.addEventListener('mousedown', (e) => {
                e.preventDefault();
                this.handleStart(e.clientX, e.clientY, e);
            });

            this.container.addEventListener('mousemove', (e) => {
                if (this.startTime) {
                    this.handleMove(e.clientX, e.clientY, e);
                }
            });

            this.container.addEventListener('mouseup', (e) => {
                this.handleEnd(e);
            });
        }
    }

    function isMobileDevice() {
        return window.matchMedia('(max-width: 480px)').matches || 
               (/Android|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) && 
                !window.matchMedia('(min-width: 481px)').matches);
    }

    function initElementorCardSliders() {
        if (!isMobileDevice()) return;
        
        const containers = document.querySelectorAll('.stacked-cards .elementor-loop-container, .stacked-cards .e-loop-container');
        
        containers.forEach((container) => {
            if (!container.dataset.sliderInit) {
                new ElementorCardSlider(container);
                container.dataset.sliderInit = 'true';
            }
        });
    }

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', initElementorCardSliders);
    } else {
        initElementorCardSliders();
    }

    window.addEventListener('load', initElementorCardSliders);

    if (typeof elementorFrontend !== 'undefined') {
        elementorFrontend.hooks.addAction('frontend/element_ready/widget', initElementorCardSliders);
    }

    document.addEventListener('jet-filter-content-rendered', initElementorCardSliders);

    const observer = new MutationObserver((mutations) => {
        if (!isMobileDevice()) return;
        
        let shouldInit = false;
        mutations.forEach((mutation) => {
            if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
                mutation.addedNodes.forEach((node) => {
                    if (node.nodeType === 1) {
                        if (node.matches && (node.matches('.stacked-cards .elementor-loop-container') || node.matches('.stacked-cards .e-loop-container'))) {
                            shouldInit = true;
                        }
                        if (node.querySelector && (node.querySelector('.stacked-cards .elementor-loop-container') || node.querySelector('.stacked-cards .e-loop-container'))) {
                            shouldInit = true;
                        }
                    }
                });
            }
        });
        
        if (shouldInit) {
            setTimeout(initElementorCardSliders, 50);
        }
    });

    observer.observe(document.body, {
        childList: true,
        subtree: true
    });

    const maxAttempts = 10;
    let attemptCount = 0;

    function tryInitWithInterval() {
        if (!isMobileDevice()) return;
        
        attemptCount++;
        const containers = document.querySelectorAll('.stacked-cards .elementor-loop-container, .stacked-cards .e-loop-container');
        
        if (containers.length > 0) {
            initElementorCardSliders();
            return;
        }
        
        if (attemptCount < maxAttempts) {
            setTimeout(tryInitWithInterval, 300 + (attemptCount * 100));
        }
    }

    setTimeout(tryInitWithInterval, 500);

    window.addEventListener('resize', () => {
        setTimeout(initElementorCardSliders, 200);
    });
    </script>
Expand

קוד גלילה לליסטינג גריד של ג'ט אנג'ין (קרוקובלוק) במובייל

 <style>
 
 /**
 * stacked-cards for Elementor
 * Developed by Twist | https://twist-digital.co.il/ 
 */
 
    @media (max-width: 480px) {
        :root {
            --card-perspective: 700px;
            --card-z-offset: 12px;
            --card-y-offset: 7px;
            --card-max-z-index: 100;
            --card-swap-duration: 0.2s;
            --swipe-x: 0px;
            --swipe-rotate: 0deg;
        }

        .stacked-cards .jet-listing-grid__items {
            width: 350px;
            height: 360px;
            position: relative;
            perspective: var(--card-perspective);
            user-select: none;
            touch-action: pan-y;
            margin: 0 auto;
            display: block !important;
        }

        .stacked-cards .jet-listing-grid__item {
            position: absolute !important;
            width: 100% !important;
            height: 100% !important;
            background: white;
            border-radius: 16px;
            cursor: grab;
            overflow: hidden;
            transform: 
                translateZ(calc(-1 * var(--card-z-offset) * var(--i, 0)))
                translateY(calc(var(--card-y-offset) * var(--i, 0)))
                translateX(var(--swipe-x, 0px)) 
                rotateY(var(--swipe-rotate, 0deg));
            transition: transform var(--card-swap-duration) ease, opacity var(--card-swap-duration) ease;
            will-change: transform;
            backface-visibility: hidden;
            z-index: calc(var(--card-max-z-index) - var(--i, 0));
            margin: 0 !important;
            display: flex !important;
            flex-direction: column !important;
            box-shadow: 0 4px 20px rgba(0,0,0,0.1);
        }

        .stacked-cards .jet-listing-grid__item:active {
            cursor: grabbing;
        }
    }
    </style>

    <script>
    class ElementorCardSlider {
        constructor(container) {
            this.container = container;
            this.cards = [...container.querySelectorAll('.jet-listing-grid__item')];
            this.isSwiping = false;
            this.isScrolling = false;
            this.startX = 0;
            this.currentX = 0;
            this.startY = 0;
            this.currentY = 0;
            this.animationFrameId = null;
            this.startTime = 0;
            this.hasMoved = false;
            this.directionDetermined = false;
            
            this.init();
        }

        init() {
            if (this.cards.length === 0) return;
            this.updatePositions();
            this.addEventListeners();
        }

        getDurationFromCSS(variableName, element = document.documentElement) {
            const value = getComputedStyle(element)?.getPropertyValue(variableName)?.trim();
            if (!value) return 200;
            if (value.endsWith('ms')) return parseFloat(value);
            if (value.endsWith('s')) return parseFloat(value) * 1000;
            return parseFloat(value) || 200;
        }

        getActiveCard() {
            return this.cards[0];
        }

        updatePositions() {
            this.cards.forEach((card, i) => {
                card.style.setProperty('--i', i);
                card.style.setProperty('--swipe-x', '0px');
                card.style.setProperty('--swipe-rotate', '0deg');
                card.style.opacity = '1';
                card.style.transform = `
                    translateZ(calc(-1 * var(--card-z-offset) * ${i}))
                    translateY(calc(var(--card-y-offset) * ${i}))
                    translateX(var(--swipe-x, 0px)) 
                    rotateY(var(--swipe-rotate, 0deg))
                `;
            });
        }

        applySwipeStyles(deltaX) {
            const card = this.getActiveCard();
            if (!card) return;
            
            card.style.setProperty('--swipe-x', `${deltaX}px`);
            card.style.setProperty('--swipe-rotate', `${deltaX * 0.15}deg`);
            card.style.opacity = 1 - Math.min(Math.abs(deltaX) / 120, 1) * 0.6;
        }

        resetStates() {
            this.isSwiping = false;
            this.isScrolling = false;
            this.startX = this.currentX = 0;
            this.startY = this.currentY = 0;
            this.startTime = 0;
            this.hasMoved = false;
            this.directionDetermined = false;
            
            const card = this.getActiveCard();
            if (card) {
                card.style.transition = `transform var(--card-swap-duration) ease, opacity var(--card-swap-duration) ease`;
            }
        }

        handleStart(clientX, clientY, event) {
            if (this.isSwiping || this.isScrolling) return;
            
            this.startX = this.currentX = clientX;
            this.startY = this.currentY = clientY;
            this.startTime = Date.now();
            this.hasMoved = false;
            this.isSwiping = false;
            this.isScrolling = false;
            this.directionDetermined = false;
            
            const card = this.getActiveCard();
            if (card) {
                card.style.transition = 'none';
            }
        }

        handleMove(clientX, clientY, event) {
            if (!this.startTime) return;
            
            const deltaX = clientX - this.startX;
            const deltaY = clientY - this.startY;
            const absDeltaX = Math.abs(deltaX);
            const absDeltaY = Math.abs(deltaY);
            const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
            
           
            if (distance > 5 && !this.directionDetermined) {
                this.hasMoved = true;
                this.directionDetermined = true;
                
              
                if (absDeltaX > absDeltaY * 0.7) {
                    this.isSwiping = true;
                    this.isScrolling = false;
                } else if (absDeltaY > absDeltaX * 0.7) {
                    this.isScrolling = true;
                    this.isSwiping = false;
                    this.resetStates();
                    return;
                }
            }
            
            if (this.isSwiping && !this.isScrolling) {
                if (event && event.preventDefault) {
                    event.preventDefault();
                }
                
                cancelAnimationFrame(this.animationFrameId);
                this.animationFrameId = requestAnimationFrame(() => {
                    this.currentX = clientX;
                    this.currentY = clientY;
                    this.applySwipeStyles(deltaX);
                    
                 
                    if (Math.abs(deltaX) > 30) {
                        this.handleEnd();
                    }
                });
            }
        }

        handleEnd(event) {
            if (!this.startTime) return;
            
            const touchDuration = Date.now() - this.startTime;
            const deltaX = this.currentX - this.startX;
            
            cancelAnimationFrame(this.animationFrameId);
            
            if (this.isScrolling) {
                this.resetStates();
                return;
            }
            
            if (!this.hasMoved && touchDuration < 300) {
                this.handleClick(event);
            } else if (this.isSwiping) {
                this.handleSwipe(deltaX);
            } else {
                this.resetCard();
            }
            
            this.resetStates();
        }
        
        handleClick(event) {
            const card = this.getActiveCard();
            if (card) {
                const link = card.querySelector('a[href]');
                if (link) {
                    const href = link.getAttribute('href');
                    const target = link.getAttribute('target');
                    
                    if (target === '_blank') {
                        window.open(href, '_blank');
                    } else {
                        window.location.href = href;
                    }
                }
            }
        }
        
        handleSwipe(deltaX) {
            const threshold = 25;
            const duration = this.getDurationFromCSS('--card-swap-duration');
            const card = this.getActiveCard();
            
            if (card) {
                card.style.transition = `transform ${duration}ms ease, opacity ${duration}ms ease`;
                
                if (Math.abs(deltaX) > threshold) {
                    const direction = Math.sign(deltaX);
                    card.style.setProperty('--swipe-x', `${direction * 400}px`);
                    card.style.setProperty('--swipe-rotate', `${direction * 25}deg`);
                    
                    setTimeout(() => {
                        card.style.setProperty('--swipe-rotate', `${-direction * 15}deg`);
                    }, duration * 0.4);
                    
                    setTimeout(() => {
                        this.cards = [...this.cards.slice(1), card];
                        this.updatePositions();
                    }, duration);
                } else {
                    this.resetCard();
                }
            }
        }
        
        resetCard() {
            this.applySwipeStyles(0);
        }

        addEventListeners() {
          

            this.container.addEventListener('touchstart', (e) => {
                this.handleStart(e.touches[0].clientX, e.touches[0].clientY, e);
            }, { passive: false });

            this.container.addEventListener('touchmove', (e) => {
                if (this.startTime) {
                    this.handleMove(e.touches[0].clientX, e.touches[0].clientY, e);
                }
            }, { passive: false });

            this.container.addEventListener('touchend', (e) => {
                this.handleEnd(e);
            }, { passive: false });

            
            this.container.addEventListener('mousedown', (e) => {
                e.preventDefault();
                this.handleStart(e.clientX, e.clientY, e);
            });

            this.container.addEventListener('mousemove', (e) => {
                if (this.startTime) {
                    this.handleMove(e.clientX, e.clientY, e);
                }
            });

            this.container.addEventListener('mouseup', (e) => {
                this.handleEnd(e);
            });

           
            window.addEventListener('mouseup', (e) => {
                if (this.startTime) {
                    this.handleEnd(e);
                }
            });

            window.addEventListener('mousemove', (e) => {
                if (this.startTime && this.isSwiping) {
                    this.handleMove(e.clientX, e.clientY, e);
                }
            });
        }
    }

    function isMobileDevice() {
        return window.matchMedia('(max-width: 480px)').matches || 
               (/Android|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) && 
                !window.matchMedia('(min-width: 481px)').matches);
    }

    function initElementorCardSliders() {
        if (!isMobileDevice()) return;
        
        const containers = document.querySelectorAll('.stacked-cards .jet-listing-grid__items');
        
        containers.forEach((container) => {
            if (!container.dataset.sliderInit) {
                new ElementorCardSlider(container);
                container.dataset.sliderInit = 'true';
            }
        });
    }

   
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', initElementorCardSliders);
    } else {
        initElementorCardSliders();
    }

    window.addEventListener('load', initElementorCardSliders);

    if (typeof elementorFrontend !== 'undefined') {
        elementorFrontend.hooks.addAction('frontend/element_ready/widget', initElementorCardSliders);
    }

    document.addEventListener('jet-filter-content-rendered', initElementorCardSliders);

    const observer = new MutationObserver((mutations) => {
        if (!isMobileDevice()) return;
        
        let shouldInit = false;
        mutations.forEach((mutation) => {
            if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
                mutation.addedNodes.forEach((node) => {
                    if (node.nodeType === 1) {
                        if (node.matches && node.matches('.stacked-cards .jet-listing-grid__items')) {
                            shouldInit = true;
                        }
                        if (node.querySelector && node.querySelector('.stacked-cards .jet-listing-grid__items')) {
                            shouldInit = true;
                        }
                    }
                });
            }
        });
        
        if (shouldInit) {
            setTimeout(initElementorCardSliders, 50);
        }
    });

    observer.observe(document.body, {
        childList: true,
        subtree: true
    });

    const maxAttempts = 10;
    let attemptCount = 0;

    function tryInitWithInterval() {
        if (!isMobileDevice()) return;
        
        attemptCount++;
        const containers = document.querySelectorAll('.stacked-cards .jet-listing-grid__items');
        
        if (containers.length > 0) {
            initElementorCardSliders();
            return;
        }
        
        if (attemptCount < maxAttempts) {
            setTimeout(tryInitWithInterval, 300 + (attemptCount * 100));
        }
    }

    setTimeout(tryInitWithInterval, 500);

    window.addEventListener('resize', () => {
        setTimeout(initElementorCardSliders, 200);
    });
    </script>
Expand

לסיכום: קחו את האתר שלכם לשלב הבא!

"קלפים מוערמים" הם לא רק טרנד עיצובי, אלא כלי עוצמתי לשיפור חווית המשתמש והנעת גולשים לפעולה. אם אתם רוצים להפוך את הגלילה באתר שלכם לכיפית, אינטראקטיבית וממכרת, ולהגדיל את זמן השהות והמעורבות של המשתמשים – הפיצ'ר הזה הוא בדיוק מה שאתם צריכים.

רוצים ליישם את האפקט המרשים הזה באתר שלכם, או לשדרג אותו עם פתרונות עיצוב ופיתוח מתקדמים נוספים? אני כאן כדי לעזור לכם להפוך את החזון שלכם למציאות.

צרו קשר עוד היום וניצור יחד חוויה דיגיטלית שתשאיר את המשתמשים שלכם עם עם פה פתוח!

הכל על דיגיטל ועסקים

אל תפספסו! הצטרפו לקבלת עדכונים מעולם הדיגיטל והעסקים ישר למייל שלכם.

מדריכים
דומים

בטוויסט, אני לא רק בונה אתרים מושלמים. אלא גם רואה את עצמי שותף להצלחה, ודואג לספק לכם את הכלים שדרושים כדי לקחת את העסק שלכם לשלב הבא.

מדריכים
Css טיפים לאלמנטור
מדריך לעיצוב צ'קבוקסים באלמנטור ובלי להסתיר הודעות שגיאה
אפקט זוהר צפוני באלמנטור
מדריכים
Js בניית אתרים
מדריך מלא לאפקט Aurora באלמנטור – איך להוסיף רקע זוהר ודינמי
הצ'קליסט המלא לבניית אתר מוצלח

צ'קליסט מיוחד בשבילכם - כדי שלא תפספסו כלום.

מדריכים
Js עיצוב אתרים
איך ליצור אנימציית אותיות מתהפכות באלמנטור
אפקט גלים בתמונה
מדריכים
Js עיצוב אתרים
איך להוסיף אפקט גלים אינטראקטיבי (Water Ripple) באלמנטור
מדריכים
Js טיפים לאלמנטור
חשיפת תוכן במעבר עכבר עם אפקט פנס מדליק

האם האתר שלכם באמת מוגן?

אל תחכו שהאתר יקרוס כדי לגלות שיש בעיה.

בדקו עכשיו את מצב התחזוקה, האבטחה והתקינות של האתר וקבלו דוח מקצועי תוך פחות מדקה.

פססס... מצאתם מה שחיפשתם?

אני מציע שיחת אפיון ראשונית מתנה לגמרי ובלי שום התחייבות