设置scrollLeft确实会重置滚动条的位置,并且更新内容可以按预期进行,但是同时执行这两个操作时,滚动条会变得混乱并且不会重置。
要查看预期行为与意外行为,请在带有触摸板的设备上查看每个演示,并使用触摸板在包装器内向左或向右滚动,然后尝试在android设备上执行相同的操作。
请注意,在笔记本电脑上,元素将无限滚动,而在android设备上,元素将仅滚动直到达到初始设置的“最大滚动”
应该发生什么:
当用户向左或向右滚动时,将第一个子元素移动到nodeList的末尾,或者将最后一个子元素移动到开头,然后将滚动位置重置为第一个子元素的一半。
以下是我解决此问题的尝试
设置transform: translateX(0px)
在.inner
这里看到其中有比以前更糟的行为。
此处列出的修复程序是针对android中以前的错误的,其中设置scrollLeft根本不起作用。这根本没有帮助问题。
wrap.appendChild(inner)
每次滚动事件时,放慢了滚动速度,但没有解决问题,因为chrome记住滚动位置。即使我可以让chrome忘记滚动位置,这也将是一个hack(看起来似乎是合理的,但会是另一个hack)
我意识到我可以嗅探浏览器,而只是恢复到jQuery ui移动滑动设置,但是我认为,如果我能做到这一点,我就不必使用外部库来模仿本地行为(并且本地总是更好的做法) )。
var log = function(event) {
var log = document.querySelector('.log');
log.innerHTML = event + "<br>" + log.innerHTML;
};
var wrap = document.querySelector('.wrap');
var inner = document.querySelector('.inner');
var items = document.querySelectorAll('.item');
var controlLeft = document.createElement('a');
controlLeft.className = 'control control-left';
controlLeft.href = 'javascript:void(0)';
controlLeft.innerHTML = '<';
controlLeft.onclick = function() {
log('click left');
inner.scrollLeft++;
};
wrap.appendChild(controlLeft);
var controlRight = document.createElement('a');
controlRight.className = 'control control-right';
controlRight.href = 'javascript:void(0)';
controlRight.innerHTML = '>';
controlRight.onclick = function() {
log('click right');
inner.scrollLeft--;
};
wrap.appendChild(controlRight);
var darken1 = document.createElement('div');
var darken2 = document.createElement('div');
darken1.className = 'darken';
darken2.className = 'darken';
items[0].appendChild(darken1);
items[2].appendChild(darken2);
var getWidth = function(element) {
return Number(window.getComputedStyle(element, null).getPropertyValue('width').replace('px', '')) + 1;
};
wrap.style.overflow = 'hidden';
inner.style.overflowY = 'hidden';
inner.style.overflowX = 'auto';
wrap.style.height = inner.scrollHeight + 'px';
window.onresize = function() {
wrap.style.height = inner.scrollHeight + 'px';
inner.scrollLeft = 0;
inner.scrollLeft = getWidth(items[0]) / 2;
};
inner.scrollLeft = getWidth(items[0]) / 2;
oldScroll = inner.scrollLeft;
inner.onscroll = function() {
if (inner.scrollLeft < oldScroll) {
log('scroll right');
inner.appendChild(inner.querySelector('.item:first-child'));
inner.querySelector('.item:first-child').appendChild(darken1);
inner.querySelector('.item:nth-child(3)').appendChild(darken2);
} else if (inner.scrollLeft > oldScroll) {
log('scroll left');
var first = inner.querySelector('.item:first-child');
var last = inner.querySelector('.item:last-child');
inner.insertBefore(last, first);
inner.querySelector('.item:first-child').appendChild(darken1);
inner.querySelector('.item:nth-child(3)').appendChild(darken2);
}
inner.scrollLeft = 0;
inner.scrollLeft = getWidth(items[0]) / 2;
oldScroll = inner.scrollLeft;
};
*, *::before, *::after {
box-sizing: border-box;
}
html,
body {
padding: 0;
margin: 0;
max-height: 100%;
overflow: hidden;
}
.wrap {
position: relative;
}
.control {
font-weight: bold;
text-decoration: none;
display: inline-block;
position: absolute;
padding: 10px;
background: rgba(255, 255, 255, 0.5);
top: 50%;
transform: translateY(-50%);
color: #FFF;
font-size: 20pt;
}
.control-left {
padding-right: 20px;
border-top-right-radius: 50%;
border-bottom-right-radius: 50%;
left: 0;
}
.control-right {
padding-left: 20px;
border-top-left-radius: 50%;
border-bottom-left-radius: 50%;
right: 0;
}
.inner {
font-size: 0;
white-space: nowrap;
overflow: auto;
}
.item {
position: relative;
display: inline-block;
font-size: 1rem;
white-space: initial;
padding-bottom: 33.3333%;
width: 50%;
}
.item .darken {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.8);
}
.item[data-n="2"] {
background-image: url(http://www.lorempixel.com/400/300/animals);
background-size: cover;
}
.item[data-n="3"] {
background-image: url(http://www.lorempixel.com/400/300/business);
background-size: cover;
}
.item[data-n="4"] {
background-image: url(http://www.lorempixel.com/400/300/cats);
background-size: cover;
}
.item[data-n="5"] {
background-image: url(http://www.lorempixel.com/400/300/city);
background-size: cover;
}
.item[data-n="6"] {
background-image: url(http://www.lorempixel.com/400/300/food);
background-size: cover;
}
.item[data-n="7"] {
background-image: url(http://www.lorempixel.com/400/300/nightlife);
background-size: cover;
}
.item[data-n="8"] {
background-image: url(http://www.lorempixel.com/400/300/fashion);
background-size: cover;
}
.item[data-n="9"] {
background-image: url(http://www.lorempixel.com/400/300/people);
background-size: cover;
}
.item[data-n="10"] {
background-image: url(http://www.lorempixel.com/400/300/nature);
background-size: cover;
}
.item[data-n="11"] {
background-image: url(http://www.lorempixel.com/400/300/sports);
background-size: cover;
}
.item[data-n="12"] {
background-image: url(http://www.lorempixel.com/400/300/technics);
background-size: cover;
}
.item[data-n="13"] {
background-image: url(http://www.lorempixel.com/400/300/transport);
background-size: cover;
}
<div class="wrap">
<div class="inner">
<div class="item" data-n="2"></div>
<div class="item" data-n="3"></div>
<div class="item" data-n="4"></div>
<div class="item" data-n="5"></div>
<div class="item" data-n="6"></div>
<div class="item" data-n="7"></div>
<div class="item" data-n="8"></div>
<div class="item" data-n="9"></div>
<div class="item" data-n="10"></div>
<div class="item" data-n="11"></div>
<div class="item" data-n="12"></div>
<div class="item" data-n="13"></div>
</div>
</div>
<div class="log">
</div>
为了暂时解决此问题,我将函数包装为超时。超时时间可短至1毫秒。我不知道为什么,但是在滚动的确切事件发生时更改内容并设置scrollLeft会导致浏览器无法重置滚动条。
(演示)
inner.onscroll = function() {
window.clearTimeout(window.updateTimeout);
window.updateTimeout = window.setTimeout(function() {
if (inner.scrollLeft < oldScroll) {
log('scroll right');
inner.appendChild(inner.querySelector('.item:first-child'));
} else if (inner.scrollLeft > oldScroll) {
log('scroll left')
var first = inner.querySelector('.item:first-child');
var last = inner.querySelector('.item:last-child');
inner.insertBefore(last, first);
}
inner.querySelector('.item:first-child').appendChild(darken1);
inner.querySelector('.item:nth-child(3)').appendChild(darken2);
inner.scrollLeft = 0;
inner.scrollLeft = getWidth(items[0]) / 2;
oldScroll = inner.scrollLeft;
}, 1);
};
尽管这确实可以“解决”问题,但我认为这是一个hack。我让这个问题开放,看看我能否得到一个真正的答案。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句