Search code examples
jqueryajaxanimationscroll

jQuery, how to don't restart the UL scroll animation


I have a piece of jQuery code with an AJAX function that updates 2 UL lists when the data on a WordPress page is updated.

This works and the scrolling also works as I want it to. However, how can I make it so that when the data is updated, the scroll simply continues instead of the animation restarting from the first LI.

I have tried it with this code but it will not work:

var $lists = [$('#list01 ul').get(0), $('#list02 ul').get(0)];
var scrollPositions = [0, 0]; // Array om scrollposities bij te houden

function checkPostContent() {
    var postId = <?php echo get_the_ID(); ?>;
    var timer = null;

    // Scrol animatie voor de twee UL lijsten
    $lists.forEach(function(list, index) {
        var $this = $(list);
        var scrollTop = $this.scrollTop();
        var liHeight = $this.find('li:first').height();
        var scrollSpeed = 1000; // Scroll snelheid in milliseconden
        var pauseTime = 2000; // Pauze tijd tussen LI items in milliseconden

        function animateList() {
            $this.animate({
                scrollTop: '+=' + liHeight
            }, scrollSpeed, function() {
                $this.find('li:first').appendTo($this);
                $this.scrollTop(0);
                timer = setTimeout(animateList, pauseTime);
            }).delay(pauseTime);
        }

        timer = setTimeout(animateList, pauseTime);
        scrollPositions[index] = scrollTop; // Sla de scrollpositie op
    });

    $.ajax({
        url: '<?php echo admin_url("admin-ajax.php"); ?>',
        type: 'POST',
        cache: false,
        timeout: 0,
        data: {
            action: 'check_post_content',
            post_id: postId,
        },
        success: function(response) {
            if (response === 'changed') {
                $.get(window.location.href, function(data) {
                    var $newContent = $('<div />').append(data).find('#list01, #list02');
                    $('#list01').html($newContent.filter('#list01').html());
                    $('#list02').html($newContent.filter('#list02').html());

                    // Selecteer de ingeladen lijsten opnieuw en hervat de scrollanimatie
                    $lists = [$('#list01 ul').get(0), $('#list02 ul').get(0)];
                    $lists.forEach(function(list, index) {
                        var $this = $(list);
                        $this.scrollTop(scrollPositions[index]);
                    });

                    checkPostContent();
                });
            } else {
                checkPostContent();
            }
        },
        error: function(req, err) {
            checkPostContent();
            console.log('my message' + err);
        }
    });
}
checkPostContent();

Solution

  • I changed the scroll animation and put everything in 1 list instead of 2 lists and now everything works as it should.

    Here is de code for it if other people wanna use something like this:

    jQuery(document).ready(function($) {
        var $list = $('#list ul');
        var itemHeight = 37;
        var currentPosition = 0;
        var isAnimating = false;
        var numItems = <?php echo $total_rows; ?>;
    
        function checkPostContent() {
            var postId = <?php echo get_the_ID(); ?>;
            
            $.ajax({
                url: '<?php echo admin_url("admin-ajax.php"); ?>',
                type: 'POST',
                cache: false,
                timeout: 0,
                data: {
                    action: 'check_post_content',
                    post_id: postId,
                },
                success: function(response) {
                    if (response === 'changed') {
                        $.get(window.location.href, function(data) {
                            var $newContent = $('<div />').append(data).find('#list ul');
                            
                            var $newList = $newContent.filter('#list ul');
                            $list.html($newList.html());
                            numItems = $list.find('li').length;
                            var listHeight = itemHeight * numItems;
                            $list.css('height', listHeight);
                            checkPostContent();
                        });
                    } else {
                        checkPostContent();
                    }
                },
                error: function(req, err) {
                    checkPostContent();
                    console.log('my message' + err);
                }
            });
        }
    
        checkPostContent();
    
        function animateList() {
            if (!isAnimating) {
                isAnimating = true;
                var newPosition = currentPosition - itemHeight;
                $list.animate({ top: newPosition }, 'slow', function() {
                    currentPosition = newPosition;
                    if (currentPosition < -($list.find('li').last().position().top - $list.parent().height())) {
                        // if the last item is showing, wait for a few seconds and then animate to the top
                        $list.delay(2000).animate({ top: 0 }, 'slow', function() {
                            currentPosition = 0;
                            $list.css('top', currentPosition);
                            isAnimating = false;
                        });
                    } else {
                        isAnimating = false;
                    }
                });
            }
        }
    
        setInterval(animateList, 2000);
    });