简体   繁体   中英

Making a responsive image slider/carousel

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.

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!

Here's the 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--;
    }
}

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!

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 eg every <li> is 100% wide) and when you animate your slider you will apply transform: translate(-100%, 0) , for the 2 nd image, then transform: translate(-200%, 0) for the 3 rd and so on.

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)

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.


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

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM