问题:每个帖子左侧都有一个主体部分,右侧有一个社交按钮容器.我希望社交按钮容器在用户滚动时沿着帖子的主体移动,并停在父div的底部,以便当它们到达帖子的底部时它们可以喜欢它.问题是通过我的AJAX滚动函数加载的一些帖子似乎没有正确计算父项高度,当浏览器窗口的顶部到达时,它们或者从不移动或直接跳到父div的底部. Here is a visual illustration的理想行为.
实现:我无法编译一个工作的jsFiddle,它可以模拟加载图像和视频的AJAX请求与“滚动”调用相结合的行为.这是我的实现和调试尝试:
每篇文章都有以下结构:
<div class="article-container"> <div class="article-body-left"><img src="..."></div> <div class="social-buttons-right"> <div class="facebook-button">...</div> </div> </div>
在每个AJAX请求完成后,我尝试使用’scroll’来确定每个社交按钮容器位置,并在用户使用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'); } }); }); }); }
调试和注释:滚动功能在第一次AJAX请求后工作正常,但之后有些中断,因为一些.social-buttons-right不沿着文章正文或在网站滚动期间直接跳到父div的底部.
当我检查了我发现行为不端的元素时,它们都有“.following”,这意味着滚动函数已经找到它们,但是它们也得到了bind_sticky_Boxes给出的css属性的错误组合.
这让我相信它在图像加载过程中与高度计算有关,所以我使用requestanimationframe()等待一点然后setTimeout(function(){..},2000)来触发滚动绑定甚至更晚.这些都没有真正解决问题(后者无论如何都不是解决方案.)我也试图更快地触发AJAX请求,但由于某种原因,这似乎有更糟糕的影响.
更新:我现在确信该问题与父高度计算有关.我用相同的属性交换了具有相同属性的唯一类的css属性,并注意到行为错误元素的类更改几乎总是出现在父div的开头,我相信这是一个强烈的迹象表明它的高度没有正确计算将它附加到主div.
关于我的无限卷轴.我不包括整个AJAX,因为我不认为它与问题严格相关.但是我以这种方式将内容附加到主div:
success: function(response){ if ( max_page >= paged){ $('#page').append(response.content); } else{ has_content = false; } loading = false; }
页面完成加载后,我启动无限滚动.当用户到达具有id load-more-posts的元素时,AJAX请求会触发,该元素位于主包装器下方.
$(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(); } });
});
解决方法
$('.article-body-left img').one('load',function() { var element = $(this).parent().parent().find('.social-buttons-right'),destination = parent_offset+parent_height-element.height() -10; //alert("Element offset: "+originalY+"\nParent offset: "+parent_offset+"\nParent height: "+parent_height+"\nElement height: "+element_height+"\nDestination: "+destination); $(window).on('scroll',function(event) { var scrollTop = $(window).scrollTop(); if (scrollTop > originalY - 10){ element.removeClass('above').removeClass('below').addClass('along'); element.css('top',(parseInt(scrollTop - parent_offset + 10)) + 'px'); if (scrollTop > (destination -10 ) ) { element.removeClass('above').removeClass('along').addClass('below'); element.css('top',''); } } else { element.removeClass('below').removeClass('along').addClass('above'); element.css('top',''); } }); }).each(function() { if(this.complete) $(this).load(); });
CSS:
.along{ position: absolute; right : 0px; } .below{ position: absolute; right: 0px; bottom: 0px; } .above{ position: relative; }