复杂的连续滚动循环

Fra*_*ckl 9 javascript jquery scroll infinite-scroll

我有一个类似于的代码:

<div id='right-column'>
    <div id='results'>
        <div id='result1>
            <div class='main'></div>
            <div class='details'></div>
        </div>
        <!-- ... -->
        <div id='result50>
            <div class='main'></div>
            <div class='details'></div>
        </div>
    </div>
</div>
Run Code Online (Sandbox Code Playgroud)
  • 结果总数取决于ajax查询,我一次性动态插入所有结果.
  • div.main当用户点击a时,总是可见(固定高度)和div.details"展开/折叠" .div.mainresult div
  • 细节div高度可以变化.

如果#results scrollHeight大于#right-column height,我想创建一个连续的滚动循环.
在这种情况下,滚动过去#result50会显示#result1,滚动之前#result1会显示#result50.

我不能.append()将第一个孩子放在底部,因为在某些情况下,result可以在列的顶部和底部看到一部分a .除非我检测到是否展开/折叠,否则我
无法复制a .当用户展开div 时,a 的高度会发生变化这一事实使得它变得更加复杂......result.details
result.details

以下是连续滚动循环(2列)的示例:

$(document).ready(function() {
  var num_children = $('#up-left').children().length;
  var child_height = $('#up-left').height() / num_children;
  var half_way = num_children * child_height / 2;
  $(window).scrollTop(half_way);

  function crisscross() {
    $('#up-left').css('bottom', '-' + window.scrollY + 'px');
    $('#down-right').css('bottom', '-' + window.scrollY + 'px');
    var firstLeft = $('#up-left').children().first();
    var lastLeft = $('#up-left').children().last();
    var lastRight = $('#down-right').children().last();
    var firstRight = $('#down-right').children().first();

    if (window.scrollY > half_way ) {
      $(window).scrollTop(half_way - child_height);
      lastRight.appendTo('#up-left');
      firstLeft.prependTo('#down-right');
    } else if (window.scrollY < half_way - child_height) {
      $(window).scrollTop(half_way);
      lastLeft.appendTo('#down-right');
      firstRight.prependTo('#up-left');
    }
  }

  $(window).scroll(crisscross);
});
Run Code Online (Sandbox Code Playgroud)
div#content {
  width: 100%;
  height: 100%;
  position: absolute;
  top:0;
  right:0;
  bottom:0;
  left:0;
}
#box {
  position: relative;
  vertical-align:top;
  width: 100%;
  height: 200px;
  margin: 0;
  padding: 0;
}
#up-left {
  position:absolute;
  z-index:4px;
  left: 0;
  top: 0px;
  width: 50%;
  margin: 0;
  padding: 0;
}
#down-right {
  position:fixed;
  bottom: 0px;
  z-index: 5px;
  left: 50%;
  width: 50%;
  margin: 0;
  padding: 0;
}
h1 {margin: 0;padding: 0;color:#fff}
.black {background: black;}
.white {background: grey;}
.green {background: green;}
.brown {background: brown;}
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>

<div id="content">
  <div id="up-left">
    <div id="box" class="brown">
      <h1>ONE</h1>
    </div>
    <div id="box" class="black">
      <h1>TWO</h1>
    </div>
    <div id="box" class="white">
      <h1>THREE</h1>
    </div>
    <div id="box" class="black">
      <h1>FOUR</h1>
    </div>
    <div id="box" class="white">
      <h1>FIVE</h1>
    </div>
    <div id="box" class="black">
      <h1>SIX</h1>
    </div>
  </div><!-- #up-left -->
  <div id="down-right">
    <div id="box" class="white">
      <h1>SIX</h1>
    </div>
    <div id="box" class="black">
      <h1>FIVE</h1>
    </div>
    <div id="box" class="white">
      <h1>FOUR</h1>
    </div>
    <div id="box" class="black">
      <h1>THREE</h1>
    </div>
    <div id="box" class="white">
      <h1>TWO</h1>
    </div>
    <div id="box" class="green">
      <h1>ONE</h1>
    </div>
  </div><!-- #down-right -->
</div><!-- .content -->
Run Code Online (Sandbox Code Playgroud)
(小提琴:http://jsfiddle.net/franckl/wszg1d6c/)

关于如何做到这一点的任何提示/想法?

gfu*_*lam 2

根据滚动方向将项目移动到顶部或底部

您可以使用 jQuery.append()移动.prepend()项目,而无需克隆它们。

您将使用与延迟加载 (AJAX) 无限滚动类似的技术,但在这种情况下,您想要处理向上和向下滚动,并且不是从服务器加载新内容,而是只是回收现有的 DOM 元素列表。

下面我演示一种技术。我将滚动位置存储在元素的.data缓存中,以便在检测滚动方向时轻松检索。我选择检测滚动方向以避免预先进行不必要的变量分配以提高性能。否则,您将获取元素并对不会在该方向发生的滚动事件进行数学计算。

滚动处理程序:

$('#right-column').on('scroll', function (e) {
    var $this = $(this),
        $results = $("#results"),
        scrollPosition = $this.scrollTop();

    if (scrollPosition > ($this.data('scroll-position') || 0)) {
        // Scrolling down
        var threshold = $results.height() - $this.height() - $('.result:last-child').height();

        if (scrollPosition > threshold) {
            var $firstResult = $('.result:first-child');
            $results.append($firstResult);
            scrollPosition -= $firstResult.height();
            $this.scrollTop(scrollPosition);
        }
    } else {
        // Scrolling up
        var threshold = $('.result:first-child').height();
        if (scrollPosition < threshold) {
            var $lastResult = $('.result:last-child');
            $results.prepend($lastResult);
            scrollPosition += $lastResult.height();
            $this.scrollTop(scrollPosition);
        }
    }
    $this.data('scroll-position', scrollPosition)
});
Run Code Online (Sandbox Code Playgroud)

一个完整的工作示例:

$('#right-column').on('scroll', function (e) {
    var $this = $(this),
        $results = $("#results"),
        scrollPosition = $this.scrollTop();

    if (scrollPosition > ($this.data('scroll-position') || 0)) {
        // Scrolling down
        var threshold = $results.height() - $this.height() - $('.result:last-child').height();

        if (scrollPosition > threshold) {
            var $firstResult = $('.result:first-child');
            $results.append($firstResult);
            scrollPosition -= $firstResult.height();
            $this.scrollTop(scrollPosition);
        }
    } else {
        // Scrolling up
        var threshold = $('.result:first-child').height();
        if (scrollPosition < threshold) {
            var $lastResult = $('.result:last-child');
            $results.prepend($lastResult);
            scrollPosition += $lastResult.height();
            $this.scrollTop(scrollPosition);
        }
    }
    $this.data('scroll-position', scrollPosition)
});
Run Code Online (Sandbox Code Playgroud)
$('#right-column').on('scroll', function (e) {
    var $this = $(this),
        $results = $("#results"),
        scrollPosition = $this.scrollTop();

    if (scrollPosition > ($this.data('scroll-position') || 0)) {
        // Scrolling down
        var threshold = $results.height() - $this.height() - $('.result:last-child').height();
      
      	if (scrollPosition > threshold) {
          	var $firstResult = $('.result:first-child');
            $results.append($firstResult);
          	scrollPosition -= $firstResult.height();
            $this.scrollTop(scrollPosition);
        }
    } else {
        // Scrolling up
        var threshold = $('.result:first-child').height();
        if (scrollPosition < threshold) {
            var $lastResult = $('.result:last-child');
            $results.prepend($lastResult);
          	scrollPosition += $lastResult.height();
            $this.scrollTop(scrollPosition);
        }
    }
  	$this.data('scroll-position', scrollPosition)
});

$('#results').on('click', '.result', function (e) {
  	$(this).find('.details').toggle();
});

$('#newNumber').on('input', function (e) {
    var results = '';
    for (var n = 1; n <= $(this).val(); n++) {
        results += 
          '<div class="result" id="result' + n + '">' +
          '    <div class="main">Result ' + n + '</div>' +
          '    <div class="details">Details for result ' + n + '</div>' +
          '</div>';
    }
  	$('#results').html(results);
});
Run Code Online (Sandbox Code Playgroud)
body {
  font-family: sans-serif;
}
h1 {
  font: bold 2rem/1 Georgia, serif;
}
p {
  line-height: 1.5;
  margin-bottom: 1em;
}
label {
  font-weight: bold;
  margin-bottom: 1em;
}
.column {
  box-sizing: border-box;
  float: left;
  width: 50%;
  height: 100vh;
  padding: 1em;
  overflow: auto;
}
#right-column {
  background-color: LemonChiffon;
}
.result {
  padding: 1em;
  cursor: pointer;
}
.result .main {
  height: 2em;
  font-weight: bold;
  line-height: 2;
}
.result .details {
  display: none;
}
Run Code Online (Sandbox Code Playgroud)

如果您愿意,可以在 CodePen 上查看完整的工作示例