我正在使用带有动画的jquery创建垂直自动滚动div ...我已经完成了创建,但是唯一的问题是当我向下滚动窗口到div滚动的列表div的中间时,它将窗口向上推到滚动列表div。我不知道问题是什么。但是,当我尝试以像素为单位指定列表div宽度时,它并没有增加...
尝试向下滚动到滚动列表div的中间。您将了解问题所在。谢谢...
setInterval(function(){
$('#list').stop().animate({scrollTop:40}, 400, 'swing', function(){
$(this).scrollTop(0).find('div:last').after($('div:first', this));
});
}, 1000);
* {
box-sizing: border-box;
}
body {
height: 1000px;
}
#list {
overflow: hidden;
width: 100%;
height: 250px;
background: red;
padding: 10px;
margin-top: 100px;
}
#list div {
display: block;
height: 30px;
padding: 10px 10px;
margin-bottom: 10px;
background: yellow;
}
.item:last-child {
margin-bottom: 0px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="list">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
<div>Item 5</div>
<div>Item 6</div>
<div>Item 7</div>
<div>Item 8</div>
<div>Item 9</div>
<div>Item 10</div>
</div>
答案 0 :(得分:2)
真是个奇怪的错误。据我所知,由于第一个元素的removal/insertion
到列表的末尾,这导致Chrome重新渲染列表,导致scrollY
偏移量发生变化。
我个人可以想到两种解决问题的方法。
1)从DOM流中删除div(#list)。
注意:这需要将#list
元素包装在containing
元素中。
由于将删除/附加元素添加到#list
元素中,因此导致发生重排(???)。最初,我认为使用position: absolute
可以解决此问题,因为您不再影响DOM流。但是,即使position: absolute
仍会导致滚动位置跳转。
然后,我查看了position: fixed
,它确实起作用(因为它基本上位于所有内容的顶部)-显然,这不起作用,因为您希望列表随页面一起滚动!那么,我们如何解决这个问题?
transform
来营救!让我们利用transform
quirk!通常,当元素为position: fixed
时,它是相对于视口的。但是,如果祖先元素具有transformation
,则位于fixed
的元素将相对于转换后的元素。让我们试一下吧!
正如我提到的,您需要应用包装/包含元素进行转换。在下面的代码段中,我用新的#list
包裹了您的div#transformed
元素。
CSS更改很简单,看起来像:
#transformed { transform: translateZ(0); }
#list { position: fixed; }
就是这样!请查看下面的代码片段,以查看实际效果。
setInterval(function(){
$('#list').stop().animate({scrollTop:40}, 400, 'swing', function(){
$(this).find('div:last').after($('div:first', this));
});
}, 1000);
* {
box-sizing: border-box;
}
body {
height: 1000px;
}
#transformed {
transform: translateZ(0);
}
#list {
position: fixed;
overflow: hidden;
width: 100%;
height: 250px;
background: red;
padding: 10px;
margin-top: 100px;
}
#list div {
display: block;
height: 30px;
padding: 10px 10px;
margin-bottom: 10px;
background: yellow;
}
.item:last-child {
margin-bottom: 0px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="transformed">
<div id="list">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
<div>Item 5</div>
<div>Item 6</div>
<div>Item 7</div>
<div>Item 8</div>
<div>Item 9</div>
<div>Item 10</div>
</div>
</div>
2)滑动图层
关于解决该问题的第二种方法,这更多地是关于如何解决此问题的讨论/意见(因此,很遗憾无法提供代码)。
我不是操纵scrollTop
,而是研究一种“滑动”层方法(使用transformY
或top
)。
您会发现基于JS的轮播采用类似的方法(很有趣,轮播倾向于使用滚动偏移方法-类似于此问题,或者是“滑动”层方法!他们只是倾向于这样做水平)
对于您要操纵的层,我再次建议将其从DOM流中删除(因此position: absolute
)。从理论上讲,操纵该层不应影响滚动偏移量。
无论如何,希望这对您有所帮助,position: fixed
方法对您有用:)
关于您的评论,您可以通过反转setInterval
逻辑来实现“向下”滚动。但是,除了滚动然后将刚刚滚动到列表底部的项目移动到列表底部之外,您需要将要滚动到其中的元素移到列表顶部,使scrollTop偏移,然后滚动。 / p>
这是一个演示以下内容的代码段:
setInterval(function(){
$('#list')
.find('div:first')
.before($('div:last', '#list'))
.end()
.scrollTop(40)
.stop()
.animate({scrollTop:0}, 400, 'swing');
}, 1000);
* {
box-sizing: border-box;
}
body {
height: 1000px;
}
#transformed {
transform: translateZ(0);
}
#list {
position: fixed;
overflow: hidden;
width: 100%;
height: 250px;
background: red;
padding: 10px;
margin-top: 100px;
}
#list div {
display: block;
height: 30px;
padding: 10px 10px;
margin-bottom: 10px;
background: yellow;
}
.item:last-child {
margin-bottom: 0px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="transformed">
<div id="list">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
<div>Item 5</div>
<div>Item 6</div>
<div>Item 7</div>
<div>Item 8</div>
<div>Item 9</div>
<div>Item 10</div>
</div>
</div>
关于上/下按钮,通过组合到目前为止我们编写的两个脚本,您可以轻松实现这一目标!这是两个单击时会向上/向下动画的片段(第一个片段将在您每次单击时滚动,第二个片段将更改动画方向):
function animateList(direction) {
if (direction === 'down') {
$('#list')
.find('div:first')
.before($('div:last', '#list'))
.end()
.scrollTop(40)
.stop()
.animate({scrollTop:0}, 400, 'swing');
} else {
$('#list')
.animate({scrollTop:40}, 400, 'swing', function(){
$(this)
.find('div:last')
.after($('div:first', this));
});
}
}
$('button').on('click', function () {
var direction = $(this).attr('id');
animateList(direction);
});
* {
box-sizing: border-box;
}
body {
height: 1000px;
}
#transformed {
transform: translateZ(0);
}
#list {
position: fixed;
overflow: hidden;
width: 100%;
height: 250px;
background: red;
padding: 10px;
margin-top: 100px;
}
#list div {
display: block;
height: 30px;
padding: 10px 10px;
margin-bottom: 10px;
background: yellow;
}
.item:last-child {
margin-bottom: 0px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="transformed">
<div id="list">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
<div>Item 5</div>
<div>Item 6</div>
<div>Item 7</div>
<div>Item 8</div>
<div>Item 9</div>
<div>Item 10</div>
</div>
</div>
<button id="up">Scroll Up</button>
<button id="down">Scroll Down</button>
以及更改方向的代码段:
var interval;
function animateList(direction) {
// Reset interval
if (interval) {
clearInterval(interval);
}
if (direction === 'down') {
interval = setInterval(function () {
$('#list')
.find('div:first')
.before($('div:last', '#list'))
.end()
.scrollTop(40)
.stop()
.animate({scrollTop:0}, 400, 'swing');
}, 1000);
} else {
interval = setInterval(function () {
$('#list')
.animate({scrollTop:40}, 400, 'swing', function(){
$(this)
.find('div:last')
.after($('div:first', this));
});
}, 1000);
}
}
$('button').on('click', function () {
var direction = $(this).attr('id');
animateList(direction);
});
// Initial animation
animateList('up');
* {
box-sizing: border-box;
}
body {
height: 1000px;
}
#transformed {
transform: translateZ(0);
}
#list {
position: fixed;
overflow: hidden;
width: 100%;
height: 250px;
background: red;
padding: 10px;
margin-top: 100px;
}
#list div {
display: block;
height: 30px;
padding: 10px 10px;
margin-bottom: 10px;
background: yellow;
}
.item:last-child {
margin-bottom: 0px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="transformed">
<div id="list">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
<div>Item 5</div>
<div>Item 6</div>
<div>Item 7</div>
<div>Item 8</div>
<div>Item 9</div>
<div>Item 10</div>
</div>
</div>
<button id="up">Scroll Up</button>
<button id="down">Scroll Down</button>
答案 1 :(得分:1)
我已将您的内部div转换为无序列表。最初,我添加了一个overflow-y:scroll
,但也可以使用,但是在看到您的评论后将其更改为overflow-y:hidden
。我找到了,但是都可以。如果您向下滚动页面然后向上滚动,则它不会“重新开始”(除非有时间遍历所有10个列表项)。您可能需要调整css / box的高度,以在底部显示红色边框,但我会留给您
希望这会有所帮助
隐藏的流量:
setInterval(function() {
$('#ulList').stop().animate({
scrollTop: 40
}, 400, 'swing', function() {
$(this).scrollTop(0).find('li:last').after($('li:first', this));
});
}, 1000);
* {
box-sizing: border-box;
}
body {
height: 1000px;
}
#list {
overflow-y:hidden;
width: 100%;
height: 250px;
background: red;
padding: 10px;
margin-top: 100px;
}
#list ul {
margin: 10px 10px;
padding: 10px 0px;
}
#list ul li {
display: block;
height: 30px;
margin-bottom: 10px;
background: yellow;
}
.item:last-child {
margin-bottom: 0px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="list">
<ul id="ulList">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li>
<li>Item 7</li>
<li>Item 8</li>
<li>Item 9</li>
<li>Item 10</li>
</ul>
</div>
溢出:滚动
setInterval(function() {
$('#ulList').stop().animate({
scrollTop: 40
}, 400, 'swing', function() {
$(this).scrollTop(0).find('li:last').after($('li:first', this));
});
}, 1000);
* {
box-sizing: border-box;
}
body {
height: 1000px;
}
#list {
overflow-y:scroll;
width: 100%;
height: 250px;
background: red;
padding: 10px;
margin-top: 100px;
}
#list ul {
margin: 10px 10px;
padding: 10px 0px;
}
#list ul li {
display: block;
height: 30px;
margin-bottom: 10px;
background: yellow;
}
.item:last-child {
margin-bottom: 0px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="list">
<ul id="ulList">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li>
<li>Item 7</li>
<li>Item 8</li>
<li>Item 9</li>
<li>Item 10</li>
</ul>
</div>