动画后将元素移动到父元素的开头

时间:2015-12-25 17:37:33

标签: jquery

我有一个简单的连续5个图像以HTML格式显示。我给它们制作了动画,使它们慢慢向右移动(所有这些都在同一时间)。

当图像到达屏幕的末尾时,我希望将其推回到其父级的开头(div标签)。

在当前形状中,此动画将最后一个图像推回到第一个图像的位置,并且由于视图空间中总有一个图像,因此它会不断交换图像。你能不能教会我做错了什么?

这是我的代码:

HTML

Follower.find_by(user_id: params[:user_id]...)

CSS

<div class="sliding-box">
  <img id="img1" src="http://jlwallpaper.com/wp-content/uploads/2015/11/hd_wallpapers_a13.jpg">
  <img id="img2" src="http://www.planwallpaper.com/static/images/wallpapers-hd-8000-8331-hd-wallpapers.jpg">
  <img id="img3" src="http://feelgrafix.com/data/wallpaper-hd/Wallpaper-HD-9.jpg">
  <img id="img4" src="http://www.planwallpaper.com/static/images/Fall-wallpaper-1366x768-HD-wallpaper.jpg">
  <img id="img5" src="http://www.wallpaperel.com/wp-content/uploads/2015/11/HD-Wallpaper-Pictures-A71.jpg">
</div>

JQuery的

.sliding-box {
    position: absolute;
    left: 10px;
    top: 10px;
}

.sliding-box img {
    position: relative;
    height: 180px;
}

为了您的方便,Fiddle

(请在Javascript窗口中选择JQuery 2.1.4,我不知道它为什么不自动保存它)

编辑:这必须在JQuery中完成,没有其他扩展。

EDIT2 / ANSWER: Manish Mishra的解决方案是正确的,但我有一些补充。由于每个图像的相对定位,动画会变得结实而仓促,正如您在fiddle中看到的那样。我的解决方案是对图像强制执行绝对定位,以便忽略它们之间的空间。剩下的就是找出一种正确定位图像的方法。这是更新后的css:

$(document).ready(function() {
    function checkPos() {
        $('.sliding-box').children().each(function() {
            if(isOffscreen(this)) {
                $(this).parent().prepend(this);
            }
        });
    }

    setInterval(function() {
        $('.sliding-box').children().animate({left: '+=1'}, 1);
        checkPos();
    }, 1);
});

function isOffscreen(elem) {
    var off = $(elem).offset();
    var t = off.top;
    var l = off.left;
    var h = $(elem).height();
    var w = $(elem).width();
    var docH = $(window).height();
    var docW = $(window).width();

    return !(t > 0 && l > 0 && t + h < docH && l + w < docW);
}

1 个答案:

答案 0 :(得分:1)

首先,很好的技巧:)。所以你做的一切都很正确,除了很少的东西:

  1. 所以基本上当prepend img元素触及右边界时,即一旦left等于容器的宽度,你就是没有重置它的左边(现在已经增加到容器的右端),所以即使流中的元素现在位于容器的开头,它也有一个非常高的左边,这就是为什么你的所有元素都会向right移出屏幕。这样做 -

    checkPos中的

    ,在if条件中只需添加$(this).css('left','10px');

  2. 你需要摆脱setInterval间隔1ms。您可以使用animate完整回调来确保重复动画。像下面一样更新您的代码(我刚从jQuery.ready中取出了函数定义,而不是setInterval,将动画逻辑分离到一个单独的函数中,以便能够再次调用:

    $(document).ready(function() {animate();});
    
    function checkPos() {
    
        $('.sliding-box').children().each(function() {
    
            if(isOffscreen(this)) {
               $(this).parent().prepend(this);
               $(this).css('left',10 +'px');
            }
       });
    };  
    
    function animate(){
    
        $('.sliding-box').children().animate({left: '+=1'}, 1, animate);
        checkPos();
    };
    
    function isOffscreen(elem) {
    
       var off = $(elem).offset();
       var t = off.top;
       var l = off.left;
       var h = $(elem).height();
       var w = $(elem).width();
       var docH = $(window).height();
       var docW = $(window).width();
    
       return !(t > 0 && l > 0 && t + h < docH && l + w < docW);
    }
    

    请参阅此fiddle