【发布时间】:2021-04-08 11:55:17
【问题描述】:
我使用function from W3Schools 作为起点来制作可拖动的画廊滑块(在我的代码中为.slider-all-items)。为了防止垂直拖动,已从原始文件中删除了几行。
我正在尝试实现与jsfiddle example 非常相似的东西,这是一个可拖动的幻灯片,并且:
-
总是全屏显示 (
.item { width: 100vw || 100%}) -
响应式即使在
window.resize - 和没有无限模式(查看上面的jsfiddle)。
添加了 3 张幻灯片,每张幻灯片占用窗口的100%(响应式)。
<div data-item="slider-full" class="slider-container">
<div class="slider-all-items">
<div class="slider-item slider-item1"></div>
<div class="slider-item slider-item2"></div>
<div class="slider-item slider-item3"></div>
</div>
</div>
现在,我不需要无限模式,但是在幻灯片之间切换的动画是可拖动滑块的一部分.
如果您尝试在 jsfiddle 示例中拖动幻灯片(方向无关紧要)只是几个px 它不会获得(下一张或上一张)幻灯片并将其居中,简而言之 功能被阻止。
要为left 和right .items 设置动画,我做了这样的事情:
/* If the user is dragging to -1 (no slide), it'll set the slider `left` to *0* */
if (sliderLeft >= 0) {theSlider.style.left = "0px";}
最后一个.item(幻灯片)也一样:
/* If dragging greater than the last one, set to the last with animation */
if (sliderRight <= sliderWidth) {theSlider.style.left = on the last item}
动画 - 过渡: property transition 及其值 0.5s ease 存储在名为 .shifting 的 class 中。
如果两者(上述条件)中的任何一个是true,.shifting class 将被添加到Slider,它将transition: 0.5s(如上所述)。同时会执行一个setTimeout() function, delay 0.5s,它会添加和删除它。 (延迟是为了平衡transition 在删除class 之前完全完成所花费的时间)。值得一提的是,class.shifting 应该被移除以保持快速和平滑的拖动。简而言之:它只会让class 起作用(当鼠标空闲时)。
.shifting{
transition: all 0.5s ease;
}
我想要达到的目标:
使幻灯片可拖动(全屏 - 响应式 - 无无限模式),并且:
如果拖动只是 X(small number)px 阻止它(如 jsfiddle - 使用 .shifting 和我的代码)。
如果超过X(greater than the x before)px,获取要求的幻灯片并将其居中。
现场(类似)示例:
编辑:您必须登录才能看到它,抱歉没有注意到并且找不到另一个示例
- Fiverr - 向下滚动并检查横幅(滑块)。忽略无限模式和导航点。
我尝试过的事情:
-
使用
for和forEachloops获取items但无法在它们和theSlider.style.left之间建立连接。 -
尝试了上面的 jsfiddle example 并进行了一些更改 (
set to full screen),它可以工作,但问题出在window.resize上,它出现故障,需要刷新页面以使其按预期工作。 -
使用
JavaScript或jQuery刷新页面in 和非 页面本身的特定内容(不重新加载)不起作用。 p>
当刷新页面中的内容不起作用时,我有一个想法,使用上面提到的 jsfiddle 将 width 和 height 更改为 100% and 100vh, and on window.resize` 得到当前幻灯片索引,删除滑块,并使用存储的索引再次附加它,但有时可能会出现故障,因此决定坚持使用我的代码,问题是:
如何在幻灯片之间连接以使滑块按要求工作?
我的代码:
// get the slider
var theSlider = document.querySelector(".slider-all-items");
// get the items in the slider
var sliderItem = document.querySelectorAll('.slider-item');
// variables saved for later
var sliderWidth;
var sliderRight;
// run the function
dragElement(theSlider);
function dragElement(theSlider) {
var pos1 = 0, pos3 = 0;
theSlider.onmousedown = dragMouseDown;
function dragMouseDown(e) {
e = e || window.event;
e.preventDefault();
// get the mouse cursor position at startup:
pos3 = e.clientX;
document.onmouseup = closeDragElement;
// call a function whenever the cursor moves:
document.onmousemove = elementDrag;
}
function elementDrag(e) {
e = e || window.event;
e.preventDefault();
// calculate the new cursor position:
pos1 = pos3 - e.clientX;
pos3 = e.clientX;
// set the element's new position:
theSlider.style.left = (theSlider.offsetLeft - pos1) + "px";
}
function closeDragElement() {
// add the class .shifting to the slider for every css change (transition)
theSlider.classList.add("shifting");
// get each item width
sliderWidth = theSlider.getBoundingClientRect().width / sliderItem.length;
// get the right side position of the slider
sliderRight = theSlider.getBoundingClientRect().right;
// get the left side position of the slider
sliderLeft = theSlider.getBoundingClientRect().left;
if(sliderLeft >= 0){
theSlider.style.left = "0px";
}
if(sliderRight <= sliderWidth){
theSlider.style.left = -Math.abs((sliderWidth * sliderItem.length) - sliderWidth) + "px";
}
// delay 0.5s, then remove the class .shifting when finished checking and styling
// .shifting {transition: all 0.5s ease;}
setTimeout(() => {
theSlider.classList.remove("shifting");
}, 500);
// stop moving when mouse button is released:
document.onmouseup = null;
document.onmousemove = null;
}
}
*, *:before, *:after {
margin: 0;
padding: 0;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.slider-container {
position: relative;
height: 80vh;
overflow-x: scroll;
overflow-y: hidden;
}
.slider-container::-webkit-scrollbar {
display: none !important;
}
.slider-all-items {
position: absolute;
display: inline-flex;
}
.slider-item {
width: calc(100vw - 0px);
height: 80vh;
cursor: grab;
display: block;
}
.slider-item1 {
background: red;
}
.slider-item2 {
background-color: blue;
}
.slider-item3 {
background-color: yellow;
}
.shifting{
transition: all 0.5s ease;
}
<div data-item="slider-full" class="slider-container">
<div class="slider-all-items">
<div class="slider-item slider-item1"></div>
<div class="slider-item slider-item2"></div>
<div class="slider-item slider-item3"></div>
</div>
</div>
【问题讨论】:
-
您能否提供更多关于您尝试达到的效果的具体细节?
-
我想提供帮助,但目前还不清楚您想在代码行为中改进什么。您指定您的目标是“即使在 window.resize 上也有响应,始终全屏显示(项目宽度:100vw 或 100%)并且没有无限模式。”。然而,它已经在调整窗口大小时调整大小,总是达到容器宽度的 100%,并且没有无限滚动。我看不到缺少什么。另外,我不明白您刷新部分屏幕的特定内容是什么意思。你是怎么做到的?
-
已编辑,请检查。
标签: javascript jquery