jquery JavaScript -可拖动的图库滑块

ozxc1zmp  于 2023-04-05  发布在  jQuery
关注(0)|答案(2)|浏览(96)

我使用一个function from W3Schools作为起点来制作一个可拖动的图库滑块(在我的代码中是.slider-all-items)。
我试图实现一些非常类似这个jsfiddle example,一个可拖动的幻灯片,和:

*始终全屏(.item { width: 100vw || 100%})
*响应即使在window.resize

  • without无限模式(检查上面的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,它不会得到(下一个或上一个)幻灯片并将其居中,简而言之 * 该功能被阻止 *。
为了制作leftright.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存储在名为.shiftingclass中。
如果两者中的任何一个(以上条件)是true.shiftingclass将被添加到Slider,它将transition: 0.5s(如上所述)。同时,将执行setTimeout() function, delay 0.5s,这将添加和删除它。(延迟是为了平衡在删除class之前transition完全完成所需的时间)。重要的是要提到的class.shifting应该被删除,以保持拖动快速和平滑。简而言之:它将只有class在行动(当鼠标是免费的)。

.shifting{
    transition: all 0.5s ease;
}

我想实现的目标:

使幻灯片可拖动(全屏-响应-无无限模式),以及:
如果拖动只是X(small number)px,请阻止它(如jsfiddle-在我的代码中使用.shifting)。
如果超过X(greater than the x before)px,则获取所要求的幻灯片并将其居中。

直播(类似)示例:

  • 编辑:您必须登录才能查看,抱歉没有注意到,也找不到其他示例 *
  • Fiverr-向下滚动并检查横幅(滑块)。忽略无限模式和导航点。

我尝试过的事情:

1.使用forforEachloops获取items,但无法连接它们和theSlider.style.left
1.尝试了上面的jsfiddle example与一些变化(set to full screen),它的工作,但问题是在window.resize它的故障,需要刷新页面,使它的工作符合预期。
1.使用JavaScriptjQuery刷新页面中的特定内容,而不是页面本身(不重新加载)不起作用。
当刷新页面中的内容不起作用时,我有一个想法,使用上面提到的jsfiddlewidthheight更改为100% and 100vh, and on窗口。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>
csbfibhn

csbfibhn1#

我相信我们可以消除小故障,以及实现div的(滑块项)的相等宽度,因为你已经使用全屏=宽度100%)没有重新加载。

只需使用ResizeObserver:我相信我们所要做的就是在窗口调整大小时调用“closeDragElement”函数,因为这是唯一计算滑块大小的函数。

ResizeObserver的CDN。
代码

// 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;

        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() {
            // 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";
            }
            // stop moving when mouse button is released:
            document.onmouseup = null;
            document.onmousemove = null;
        }

        function dragElement(theSlider) {
            var pos1 = 0, pos3 = 0;
            theSlider.onmousedown = dragMouseDown;
            theSlider.addEventListener('resize', closeDragElement);
        }

        dragElement(theSlider);

        /* global ResizeObserver */

        const ro = new ResizeObserver(entries => {
            for (let entry of entries) {
                closeDragElement();
            }
        });

        ro.observe(theSlider); //<-- NOTICE HERE
*,
        *: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>

前:https://www.dropbox.com/s/y0oy4rwnlj5la4g/before.gif?dl=0
后:https://www.dropbox.com/s/jsqba0ef61ibef1/after.gif?dl=0

yx2lnoni

yx2lnoni2#

你提到你试过使用jQuery。我希望你的代码能正常工作,但如果不能,jQuery插件jCarousel能为你工作吗?这是一个适应性很强的小插件,支持响应式布局。

相关问题