制作响应式图像滑块/旋转木马

时间:2022-11-04 09:43:54

I'm creating my own slider and I need some help making it responsive. Right now it works with the responsive part on the first slide, but when I go to the next slide (in this case, any li that is NOT first child) the positioning and width's of the li's doesn't add up and everything gets wrong.

我正在创建自己的滑块,我需要一些帮助才能使其响应。现在它适用于第一张幻灯片上的响应部分,但当我转到下一张幻灯片(在这种情况下,任何不是第一个孩子的li)时,li的定位和宽度不会加起来,一切都会出错。

It's hard to explain and I'd love if anyone could take a look here:

这很难解释,如果有人可以看看,我很乐意:

http://robbinj.se/r/

I have a wrapper with a width of 100% and every li's width gets set to the width of the wrapper of 100%. If you don't understand what I'm after try go to the page, resize your browser on the first slide, that is how I want it to work on all the other slides as well but I need some ideas on how to do it!

我有一个宽度为100%的包装,每个li的宽度设置为100%的包装宽度。如果您不明白我之后尝试转到页面,请在第一张幻灯片上调整浏览器的大小,这也是我希望它在所有其他幻灯片上工作的方式,但我需要一些关于如何操作的想法!

Here's the jQuery:

这是jQuery:

    var slideLiWidth = $('#slider').width(),
    slideUl = $('#slider ul'),
    slideLi = $(slideUl).find('li'),
    slides = $(slideLi).length,
    slideNav = $('.slideNav'),
    current = 1;

slideLi.width(slideLiWidth);

$(window).resize(function() {
    var slideLiWidth = $('#slider').width();
    slideLi.width(slideLiWidth);
});

slideNav.click(function() {
    dir = $(this).data('dir');
    transition();
});

function transition() {
    var slideLiWidth = $('#slider').width();
    if (dir === 'next' && current < slides) {
        slideUl.transition({x: '-='+slideLiWidth}, 500, 'ease');
        current++;
    }
    else if (dir === 'back' && current > 1) {
        slideUl.transition({x: '+='+slideLiWidth}, 500, 'ease');
        current--;
    }
}

4 个解决方案

#1


1  

The problem lies with the way you calculate the translate distance. You were correct in adding and subtracting the translate value of the current list item width, but didn't take into consideration the fact that said value does not update as users might resize their viewport. Granted, this is only a problem for users who will, in fact, resize their viewport mid-browsing. Anyone using a tablet, for example, will have no problem with it.

问题在于计算平移距离的方式。您在添加和减去当前列表项宽度的转换值时是正确的,但没有考虑到因为用户可能调整其视口大小而不更新所述值的事实。当然,对于实际上会在浏览中调整其视口大小的用户来说,这只是一个问题。例如,任何使用平板电脑的人都没有问题。

Still, if you're really looking for a perfect slider, here's what I would do: create a variable to keep count of which slide is currently active use that variable to adjust the translate value in conformance with the resized viewport

尽管如此,如果你真的在寻找一个完美的滑块,我会这样做:创建一个变量以保持当前活动的幻灯片的数量使用该变量来调整与调整大小的视口一致的转换值

Here's what that code looks like:

这是代码的样子:

$(window).resize(function() {
    var slideCounter = 1; // Because the first slide is, well ... first.    
    var slideLiWidth = $('#slider').width();
    slideLi.width(slideLiWidth);
    slideUl.transition({x: '-='+slideCounter*slideLiWidth}, 500, 'ease'); // Adjust the UL's transition value to match the current slide position and width.
});

function transition() {
    var slideLiWidth = $('#slider').width();
    if (dir === 'next' && current < slides) {
        slideUl.transition({x: '-='+slideLiWidth}, 500, 'ease');
        current++;
        slideCounter++; // Increment the counter to keep up.
    }
    else if (dir === 'back' && current > 1) {
        slideUl.transition({x: '+='+slideLiWidth}, 500, 'ease');
        current--;
        slideCounter--; // Increment the counter to keep up.
    }
}

I've commented the added lines and, while I can't actually test the code above, I'm pretty sure it'll work. If it doesn't, at least I'm pointing you in the right direction.

我评论了添加的行,虽然我实际上无法测试上面的代码,但我很确定它会起作用。如果没有,至少我指的是你正确的方向。

Cheers!

#2


1  

The problem is related to the choice to specify width and slide offset in pixels when you should instead try to define the width in % (so e.g. every <li> is 100% wide) and when you animate your slider you will apply transform: translate(-100%, 0), for the 2nd image, then transform: translate(-200%, 0) for the 3rd and so on.

问题与指定宽度和幻灯片偏移(以像素为单位)的选择有关,而应尝试以%为单位定义宽度(例如,每个

  • 为100%宽),当您为滑块设置动画时,您将应用transform:translate (-100%,0),对于第二个图像,然后变换:翻译(-200%,0)为第3个,依此类推。

  • This should work fine even when you resize the browser, since your negative offset and the applied width will be ever automatically recalculated along with the browser size. The browser will turn your relative offset into the correct amount of pixel.

    即使您调整浏览器大小,这应该可以正常工作,因为您的负偏移量和应用的宽度将随浏览器大小自动重新计算。浏览器会将您的相对偏移量转换为正确的像素数量。

    Take a look at this fiddle for a proof of concept (tried on firefox and chrome) : http://jsbin.com/ecifoc/1/ (move the slider and resize the browser, then move slider again)

    看一下这个小提琴的概念证明(在firefox和chrome上试过):http://jsbin.com/ecifoc/1/(移动滑块并调整浏览器大小,然后再次移动滑块)

    Other methods like continuous recalculation of the width and negative offset may work fine too, but they are definitely too much expensive (typically, you need to attach some handler to the resize event) and make the code more error-prone because you introduce some complexity.

    其他方法,如连续重新计算宽度和负偏移也可以正常工作,但它们肯定太昂贵(通常,您需要将一些处理程序附加到resize事件)并使代码更容易出错,因为您引入了一些复杂性。


    Note: if you need to also manage an infinity slider you can look at this discussion

    注意:如果您还需要管理无限滑块,可以查看此讨论

    #3


    1  

    I think this one will help. This one will be working in small devices and tablets also. You can have multiple carousels on the same page as well. Just replicate the "DIV"-"SpecDataWrap" and change the ID.

    我认为这个会有所帮助。这个也适用于小型设备和平板电脑。您也可以在同一页面上放置多个轮播。只需复制“DIV” - “SpecDataWrap”并更改ID。

    <div class="ContainerWrap">
        <div class="Container">
            <div class="AllSpecsDataWrap">
                <div class="SpecDataWrap" id="SpecDataWrap1">
                    <div class="SpecDataSlides activeNavSlide">
                        <img src="http://s19.postimg.org/lzem156s3/image1.jpg" />
                        <div class="SpecDesc SpecDescRight">
                            <h2>Choose to be unique.</h2>
                            <div class="SpecDescDetails">
                                Metal accents, colorful hues, real woods and leathers, and a customizable laser-etched signature offer thousands of ways to make your Moto X unique.
                            </div>
                        </div>
                    </div>
                    <div class="SpecDataSlides InActiveNavSlide">
                        <img src="http://s19.postimg.org/6cira13mb/image2.jpg" />
                        <div class="SpecDesc SpecDescLeft">
                            <h2>Choose to be unique.</h2>
                            <div class="SpecDescDetails">
                                Metal accents, colorful hues, real woods and leathers, and a customizable laser-etched signature offer thousands of ways to make your Moto X unique.
                            </div>
                        </div>
                    </div>
                    <div class="SpecDataSlides InActiveNavSlide">
                        <img src="http://s19.postimg.org/f4zpxpor7/image3.jpg" />
                        <div class="SpecDesc SpecDescRight">
                            <h2>Choose to be unique.</h2>
                            <div class="SpecDescDetails">
                                Metal accents, colorful hues, real woods and leathers, and a customizable laser-etched signature offer thousands of ways to make your Moto X unique.
                            </div>
                        </div>
                    </div>
                    <div class="SpecSlideNavigation">
                        <div class="leftNavSpec SpecSlideNav"></div>
                        <div class="bulletsNavSpec">
                            <ul>
                                <li class="activeImage"></li>
                                <li class="InActiveImage"></li>
                                <li class="InActiveImage"></li>
                            </ul>
                            <div class="clearFix"></div>
                        </div>
                        <div class="RightNavSpec SpecSlideNav"></div>
                    </div>
                    <div class="clearFix"></div>
                </div>
            </div>
        </div>
    </div>
    

    You can see the JS and CSS code here: https://jsfiddle.net/raju_sumit/Ld21vutz/

    你可以在这里看到JS和CSS代码:https://jsfiddle.net/raju_sumit/Ld21vutz/

    #4


    0  

    var $slider = $('#slider'),
        imgW = $('#slider li').outerWidth(true),
        winW = 0,
        zero = 0;
    
    
    
    function getSizes(){
        winW = $(window).width();
        zero = (winW-imgW)/2;
        $slider.animate({left: zero},0); // This should 'zero' the position on resize
    }
    
    getSizes(); 
    
    
    $(window).resize(function() {
        getSizes();
    });
    

    If I missed something, retrieve the logic here: http://roxon.in/scripts/infinite_gal/index.html

    如果我错过了什么,请在这里检索逻辑:http://roxon.in/scripts/infinite_gal/index.html

    #1


    1  

    The problem lies with the way you calculate the translate distance. You were correct in adding and subtracting the translate value of the current list item width, but didn't take into consideration the fact that said value does not update as users might resize their viewport. Granted, this is only a problem for users who will, in fact, resize their viewport mid-browsing. Anyone using a tablet, for example, will have no problem with it.

    问题在于计算平移距离的方式。您在添加和减去当前列表项宽度的转换值时是正确的,但没有考虑到因为用户可能调整其视口大小而不更新所述值的事实。当然,对于实际上会在浏览中调整其视口大小的用户来说,这只是一个问题。例如,任何使用平板电脑的人都没有问题。

    Still, if you're really looking for a perfect slider, here's what I would do: create a variable to keep count of which slide is currently active use that variable to adjust the translate value in conformance with the resized viewport

    尽管如此,如果你真的在寻找一个完美的滑块,我会这样做:创建一个变量以保持当前活动的幻灯片的数量使用该变量来调整与调整大小的视口一致的转换值

    Here's what that code looks like:

    这是代码的样子:

    $(window).resize(function() {
        var slideCounter = 1; // Because the first slide is, well ... first.    
        var slideLiWidth = $('#slider').width();
        slideLi.width(slideLiWidth);
        slideUl.transition({x: '-='+slideCounter*slideLiWidth}, 500, 'ease'); // Adjust the UL's transition value to match the current slide position and width.
    });
    
    function transition() {
        var slideLiWidth = $('#slider').width();
        if (dir === 'next' && current < slides) {
            slideUl.transition({x: '-='+slideLiWidth}, 500, 'ease');
            current++;
            slideCounter++; // Increment the counter to keep up.
        }
        else if (dir === 'back' && current > 1) {
            slideUl.transition({x: '+='+slideLiWidth}, 500, 'ease');
            current--;
            slideCounter--; // Increment the counter to keep up.
        }
    }
    

    I've commented the added lines and, while I can't actually test the code above, I'm pretty sure it'll work. If it doesn't, at least I'm pointing you in the right direction.

    我评论了添加的行,虽然我实际上无法测试上面的代码,但我很确定它会起作用。如果没有,至少我指的是你正确的方向。

    Cheers!

    #2


    1  

    The problem is related to the choice to specify width and slide offset in pixels when you should instead try to define the width in % (so e.g. every <li> is 100% wide) and when you animate your slider you will apply transform: translate(-100%, 0), for the 2nd image, then transform: translate(-200%, 0) for the 3rd and so on.

    问题与指定宽度和幻灯片偏移(以像素为单位)的选择有关,而应尝试以%为单位定义宽度(例如,每个

  • 为100%宽),当您为滑块设置动画时,您将应用transform:translate (-100%,0),对于第二个图像,然后变换:翻译(-200%,0)为第3个,依此类推。

  • This should work fine even when you resize the browser, since your negative offset and the applied width will be ever automatically recalculated along with the browser size. The browser will turn your relative offset into the correct amount of pixel.

    即使您调整浏览器大小,这应该可以正常工作,因为您的负偏移量和应用的宽度将随浏览器大小自动重新计算。浏览器会将您的相对偏移量转换为正确的像素数量。

    Take a look at this fiddle for a proof of concept (tried on firefox and chrome) : http://jsbin.com/ecifoc/1/ (move the slider and resize the browser, then move slider again)

    看一下这个小提琴的概念证明(在firefox和chrome上试过):http://jsbin.com/ecifoc/1/(移动滑块并调整浏览器大小,然后再次移动滑块)

    Other methods like continuous recalculation of the width and negative offset may work fine too, but they are definitely too much expensive (typically, you need to attach some handler to the resize event) and make the code more error-prone because you introduce some complexity.

    其他方法,如连续重新计算宽度和负偏移也可以正常工作,但它们肯定太昂贵(通常,您需要将一些处理程序附加到resize事件)并使代码更容易出错,因为您引入了一些复杂性。


    Note: if you need to also manage an infinity slider you can look at this discussion

    注意:如果您还需要管理无限滑块,可以查看此讨论

    #3


    1  

    I think this one will help. This one will be working in small devices and tablets also. You can have multiple carousels on the same page as well. Just replicate the "DIV"-"SpecDataWrap" and change the ID.

    我认为这个会有所帮助。这个也适用于小型设备和平板电脑。您也可以在同一页面上放置多个轮播。只需复制“DIV” - “SpecDataWrap”并更改ID。

    <div class="ContainerWrap">
        <div class="Container">
            <div class="AllSpecsDataWrap">
                <div class="SpecDataWrap" id="SpecDataWrap1">
                    <div class="SpecDataSlides activeNavSlide">
                        <img src="http://s19.postimg.org/lzem156s3/image1.jpg" />
                        <div class="SpecDesc SpecDescRight">
                            <h2>Choose to be unique.</h2>
                            <div class="SpecDescDetails">
                                Metal accents, colorful hues, real woods and leathers, and a customizable laser-etched signature offer thousands of ways to make your Moto X unique.
                            </div>
                        </div>
                    </div>
                    <div class="SpecDataSlides InActiveNavSlide">
                        <img src="http://s19.postimg.org/6cira13mb/image2.jpg" />
                        <div class="SpecDesc SpecDescLeft">
                            <h2>Choose to be unique.</h2>
                            <div class="SpecDescDetails">
                                Metal accents, colorful hues, real woods and leathers, and a customizable laser-etched signature offer thousands of ways to make your Moto X unique.
                            </div>
                        </div>
                    </div>
                    <div class="SpecDataSlides InActiveNavSlide">
                        <img src="http://s19.postimg.org/f4zpxpor7/image3.jpg" />
                        <div class="SpecDesc SpecDescRight">
                            <h2>Choose to be unique.</h2>
                            <div class="SpecDescDetails">
                                Metal accents, colorful hues, real woods and leathers, and a customizable laser-etched signature offer thousands of ways to make your Moto X unique.
                            </div>
                        </div>
                    </div>
                    <div class="SpecSlideNavigation">
                        <div class="leftNavSpec SpecSlideNav"></div>
                        <div class="bulletsNavSpec">
                            <ul>
                                <li class="activeImage"></li>
                                <li class="InActiveImage"></li>
                                <li class="InActiveImage"></li>
                            </ul>
                            <div class="clearFix"></div>
                        </div>
                        <div class="RightNavSpec SpecSlideNav"></div>
                    </div>
                    <div class="clearFix"></div>
                </div>
            </div>
        </div>
    </div>
    

    You can see the JS and CSS code here: https://jsfiddle.net/raju_sumit/Ld21vutz/

    你可以在这里看到JS和CSS代码:https://jsfiddle.net/raju_sumit/Ld21vutz/

    #4


    0  

    var $slider = $('#slider'),
        imgW = $('#slider li').outerWidth(true),
        winW = 0,
        zero = 0;
    
    
    
    function getSizes(){
        winW = $(window).width();
        zero = (winW-imgW)/2;
        $slider.animate({left: zero},0); // This should 'zero' the position on resize
    }
    
    getSizes(); 
    
    
    $(window).resize(function() {
        getSizes();
    });
    

    If I missed something, retrieve the logic here: http://roxon.in/scripts/infinite_gal/index.html

    如果我错过了什么,请在这里检索逻辑:http://roxon.in/scripts/infinite_gal/index.html