I upload messages consisting of pictures or videos to the main div of my site with infinite scrolling (implemented via AJAX). The system works almost the same as on any popular meme site.
Problem: Each message has a body section on the left and a social button icon on the right. I want the social buttons container to move along with the body of the message when the user scrolls and stops at the bottom of the parent div so that they can be liked when they reach the bottom of the message. The problem is that some of the messages downloaded through my AJAX scroll function do not seem to correctly calculate the height of the parents, and they either never move or jump directly to the bottom of the parent div when the top of the browser window reaches them. Here is a visual illustration of the desired behavior.
Implementation: I could not compile a working jsFiddle that would mimic the behavior of AJAX requests by loading images and videos in conjunction with scrolling calls. Here are my implementation and debugging attempts:
Each article has the following structure:
<div class="article-container"> <div class="article-body-left"><img src="..."></div> <div class="social-buttons-right"> <div class="facebook-button">...</div> </div> </div>
After executing each AJAX request, I try to use the "scroll" to determine each of the positions of the container of social buttons and change them when the user scrolls using ajaxComplete ():
$(document).ajaxComplete(function() { bind_sticky_boxes(); }); function bind_sticky_boxes() { $(window).on('scroll', function() { $('.social-buttons-right').not('.following').each( function() { var element = $(this).addClass('following'), originalY = element.offset().top, parent_offset = element.parent().offset().top, parent_height = element.parent().height(), element_height = element.height(), destination = originalY+parent_height-element.height() -10; $(window).on('scroll', function(event) { var scrollTop = $(window).scrollTop(); if (scrollTop > originalY - 10){ element.css('position','absolute'); element.css('top',(scrollTop - parent_offset + 10) + 'px'); element.css('right', '0px'); if (scrollTop > (destination -10 ) ) { element.css('top',parent_height-element_height); element.css('right', '0px'); element.css('bottom', '0px'); } } else { element.css('position','relative'); element.css('top','initial'); element.css('left', 'initial'); element.css('right','initial'); element.css('bottom', 'initial'); } }); }); }); }
Debugging and notes: The scroll function works fine after the first AJAX request, but it breaks somewhat after some of the .social buttons on the right do not follow the body of the article or jump directly to the bottom of the parent div while scrolling through the site.
When I looked at those elements that were incorrect, I found that they all have ".following", which means that the scroll function detected them, but they also get the poor combination of css properties that bind_sticky_boxes provides.
This led me to believe that it had something to do with calculating the height during image loading, so I used requestanimationframe () to wait a bit, and then setTimeout (function () {..}, 2000) to cause the scroll to bind even later. None of them really solved the problem (the latter was not a solution in any case). I also tried to speed up AJAX requests a bit, but for some reason this seemed even worse.
Update: Now I am convinced that the problem is with calculating the height of the parent. I changed the css properties for unique classes with the same attributes and noticed that the class change for erroneous elements almost always occurs at the beginning of the parent div, which, in my opinion, is a convincing sign that the height is not calculated properly immediately after adding it to the main div
As for my endless scroll. I do not include all of AJAX, as I do not think this is strictly related to the problem. But I am adding content to the main div this way:
success: function(response){ if ( max_page >= paged){ $('#page').append(response.content); } else{ has_content = false; } loading = false; }
After the page is loaded, I initiate my endless scroll. AJAX requests a trigger when a user reaches an element with the identifier load more-posts, which is below the main shell.
$(window).on('load',function(){ $(window).on('scroll', function() { var element_position = $('#load-more-posts').offset().top + $('#load-more-posts').outerHeight() - window.innerHeight; var y_scroll_pos = $(window).scrollTop(); if( ( y_scroll_pos >= element_position ) && !loading) { paged++; load_more_posts(); } });
});