Search code examples
javascriptjqueryimagejquery-uijquery-ui-slider

Jquery ui double image slider single command


I'm trying to make a double image slider commanded by the same button, but, with the code I have, I can't find how to select two different elements or all the instance on an element

html:

    <div class="slider-box">
    <div class="slider" id="slider">
        <div class="slider__item">
            <img src="https://placeimg.com/960/540/animals" alt="">
            <h2 class="slider__item__title">Slide 1 Title</h2>
        </div>
        <div class="slider__item">
            <img src="https://placeimg.com/960/540/arch" alt="">
            <h2 class="slider__item__title">Slide 2 Title</h2>
        </div>
        <div class="slider__item">
            <img src="https://placeimg.com/960/540/nature" alt="">
            <h2 class="slider__item__title">Slide 3 Title</h2>
        </div>
        <div class="slider__item">
            <img src="https://placeimg.com/960/540/people" alt="">
            <h2 class="slider__item__title">Slide 4 Title</h2>
        </div>
        <div class="slider__item">
            <img src="https://placeimg.com/960/540/tech" alt="">
            <h2 class="slider__item__title">Slide 5 Title</h2>
        </div>
    </div>

    <div class="slider" id="slider">
        <div class="slider__item">
            <img src="https://placeimg.com/960/540/animals" alt="">
            <h2 class="slider__item__title">Slide 1 Title</h2>
        </div>
        <div class="slider__item">
            <img src="https://placeimg.com/960/540/arch" alt="">
            <h2 class="slider__item__title">Slide 2 Title</h2>
        </div>
        <div class="slider__item">
            <img src="https://placeimg.com/960/540/nature" alt="">
            <h2 class="slider__item__title">Slide 3 Title</h2>
        </div>
        <div class="slider__item">
            <img src="https://placeimg.com/960/540/people" alt="">
            <h2 class="slider__item__title">Slide 4 Title</h2>
        </div>
        <div class="slider__item">
            <img src="https://placeimg.com/960/540/tech" alt="">
            <h2 class="slider__item__title">Slide 5 Title</h2>
        </div>
    </div>
</div>

    <div class="slider-nav">
        <div class="slider-nav__prev" id="prev"><i class="fa fa-angle-left"></i></div>
        <div class="slider-nav__next" id="next"><i class="fa fa-angle-right"></i></div>
        <div class="slider-nav__dots" id="dots"></div>
    </div>

Js:

(function($) {

'use strict';

var pluginName = 'slider',
    defaults = {
        next: '.slider-nav__next',
        prev: '.slider-nav__prev',
        item: '.slider__item',
        dots: false,
        dotClass: 'slider__dot',
    };

function slider(element, options) {
    this.$document = $(document);
    this.$window = $(window);
    this.$element = $(element);
    this.options = $.extend({}, defaults, options);
    this.init();
}

slider.prototype.init = function() {
    this.setup();
    this.attachEventHandlers();
    this.update();
}

slider.prototype.setup = function(argument) {
    this.$slides = this.$element.find(this.options.item);
    this.count = this.$slides.length;
    this.index = 0;

    this.$next = $(this.options.next);
    this.$prev = $(this.options.prev);

    this.$canvas = $(document.createElement('div'));
    this.$canvas.addClass('slider__canvas').appendTo(this.$element);
    this.$slides.appendTo(this.$canvas);

    this.$dots = $(this.options.dots);
    this.$dots.length && this.createDots();
};

slider.prototype.createDots = function() {
    var dots = [];
    for (var i = 0; i < this.count; i += 1) {
        dots[i] = '<span data-index="' + i + '" class="' + this.options.dotClass + '"></span>';
    }
    this.$dots.append(dots);
}

slider.prototype.attachEventHandlers = function() {
    this.$element.on('prev.slider', this.prev.bind(this));
    this.$document.on('click', this.options.prev, (function(e) {
        this.$element.trigger('prev.slider');
    }).bind(this));

    this.$element.on('next.slider', this.next.bind(this));
    this.$document.on('click', this.options.next, (function(e) {
        this.$element.trigger('next.slider');
    }).bind(this));

    this.$element.on('update.slider', this.update.bind(this));
    this.$window.on('resize load', (function(e) {
        this.$element.trigger('update.slider');
    }).bind(this));

    this.$element.on('jump.slider', this.jump.bind(this));
    this.$document.on('click', ('.' + this.options.dotClass), (function(e) {
        var index = parseInt($(e.target).attr('data-index'));
        this.$element.trigger('jump.slider', index);
    }).bind(this));
};

slider.prototype.next = function(e) {
    this.index = (this.index + 1) % this.count;
    this.slide();
};

slider.prototype.prev = function(e) {
    this.index = Math.abs(this.index - 1 + this.count) % this.count;
    this.slide();
};

slider.prototype.jump = function(e, index) {
    this.index = index % this.count;
    this.slide();
}

slider.prototype.slide = function(index) {
    undefined == index && (index = this.index);
    var position = index * this.width * -1;
    this.$canvas.css({
        'transform': 'translate3d(' + position + 'px, 0, 0)',
    });
    this.updateCssClass();
};

slider.prototype.update = function() {
    this.width = this.$element.width();
    this.$canvas.width(this.width * this.count);
    this.$slides.width(this.width);
    this.slide();
};

slider.prototype.updateCssClass = function() {
    this.$slides
        .removeClass('active')
        .eq(this.index)
        .addClass('active');

    this.$dots
        .find('.' + this.options.dotClass)
        .removeClass('active')
        .eq(this.index)
        .addClass('active');
}

$.fn[pluginName] = function(options) {
    return this.each(function() {
        !$.data(this, pluginName) && $.data(this, pluginName, new slider(this, options));
    });
};

})(window.jQuery);

$('#slider').slider({
    prev: '#prev',
    next: '#next',
    dots: '#dots',
    autoplay: true,
});

I'm a javascript noob, I understand what I'm reading/using, but not sure when it's time to write.

Here is my fiddle : https://jsfiddle.net/Fromager/zkgfzbcv/


Solution

  • 1) id should be unique, so replace both id="slider" with id="slider1" and id="slider2".

    2) Replace #slider with .slider at

    $('.slider').slider({
        prev: '#prev',
        next: '#next',
        dots: '#dots',
        autoplay: true,
    });
    

    to set the slider() to both slides you have.

    (function($) {
    
    'use strict';
    
    var pluginName = 'slider',
        defaults = {
            next: '.slider-nav__next',
            prev: '.slider-nav__prev',
            item: '.slider__item',
            dots: false,
            dotClass: 'slider__dot',
        };
    
    function slider(element, options) {
        this.$document = $(document);
        this.$window = $(window);
        this.$element = $(element);
        this.options = $.extend({}, defaults, options);
        this.init();
    }
    
    slider.prototype.init = function() {
        this.setup();
        this.attachEventHandlers();
        this.update();
    }
    
    slider.prototype.setup = function(argument) {
        this.$slides = this.$element.find(this.options.item);
        this.count = this.$slides.length;
        this.index = 0;
    
        this.$next = $(this.options.next);
        this.$prev = $(this.options.prev);
    
        this.$canvas = $(document.createElement('div'));
        this.$canvas.addClass('slider__canvas').appendTo(this.$element);
        this.$slides.appendTo(this.$canvas);
    
        this.$dots = $(this.options.dots);
        this.$dots.length && this.createDots();
    };
    
    let isInit = false; // check if the first slider is initialized
    
    slider.prototype.createDots = function() {
        if(isInit){
          return; // if the first slider is initialized, do nothing.
        }
        var dots = [];
        for (var i = 0; i < this.count; i += 1) {
            dots[i] = '<span data-index="' + i + '" class="' + this.options.dotClass + '">';
            
            // $(this.$slides[i]) is the slider__item div
            dots[i] += i + '/' + $(this.$slides[i]).find('img').attr('src') + '</span>';
        }
        this.$dots.append(dots);
        isInit = true; // after the first slider is initialized, set to true
    }
    
    slider.prototype.attachEventHandlers = function() {
        this.$element.on('prev.slider', this.prev.bind(this));
        this.$document.on('click', this.options.prev, (function(e) {
            this.$element.trigger('prev.slider');
        }).bind(this));
    
        this.$element.on('next.slider', this.next.bind(this));
        this.$document.on('click', this.options.next, (function(e) {
            this.$element.trigger('next.slider');
        }).bind(this));
    
        this.$element.on('update.slider', this.update.bind(this));
        this.$window.on('resize load', (function(e) {
            this.$element.trigger('update.slider');
        }).bind(this));
    
        this.$element.on('jump.slider', this.jump.bind(this));
        this.$document.on('click', ('.' + this.options.dotClass), (function(e) {
            var index = parseInt($(e.target).attr('data-index'));
            this.$element.trigger('jump.slider', index);
        }).bind(this));
    };
    
    slider.prototype.next = function(e) {
        this.index = (this.index + 1) % this.count;
        this.slide();
    };
    
    slider.prototype.prev = function(e) {
        this.index = Math.abs(this.index - 1 + this.count) % this.count;
        this.slide();
    };
    
    slider.prototype.jump = function(e, index) {
        this.index = index % this.count;
        this.slide();
    }
    
    slider.prototype.slide = function(index) {
        undefined == index && (index = this.index);
        var position = index * this.width * -1;
        this.$canvas.css({
            'transform': 'translate3d(' + position + 'px, 0, 0)',
        });
        this.updateCssClass();
    };
    
    slider.prototype.update = function() {
        this.width = this.$element.width();
        this.$canvas.width(this.width * this.count);
        this.$slides.width(this.width);
        this.slide();
    };
    
    slider.prototype.updateCssClass = function() {
        this.$slides
            .removeClass('active')
            .eq(this.index)
            .addClass('active');
    
        this.$dots
            .find('.' + this.options.dotClass)
            .removeClass('active')
            .eq(this.index)
            .addClass('active');
    }
    
    $.fn[pluginName] = function(options) {
        return this.each(function() {
            !$.data(this, pluginName) && $.data(this, pluginName, new slider(this, options));
        });
    };
    
    })(window.jQuery);
    
    let isInitialized = false;
    
    $('.slider').slider({
        prev: '#prev',
        next: '#next',
        dots: '#dots',
        autoplay: true,
    });
    img {
        max-width: 100%;
        height: auto;
    }
    
    .slider-box,
    .slider__item {
        position: relative;
    }
    
    .slider-box{
      display:flex;
    }
    
    .slider {
      width:40vw;
      display:inline-block;
        overflow: hidden;
    }
    
    .slider__canvas {
        transition: transform 0.5s;
    }
    
    .slider__item {
        float: left;
    }
    
    .slider__item__title {
        opacity: 0;
        position: absolute;
        top: 50px;
        left: 50px;
        /*transition: opacity 0.3s, transform 0.3s;
        transform: translate3d(-50%, -60%, 0);*/
    }
    
    .active .slider__item__title {
        opacity: 1;
        /*transition-delay: 0.5s;
        transform: translate3d(-50%, -50%, 0);*/
    }
    
    .slider-nav {
        color: #fff;
        text-align: center;
    }
    
    .slider-nav__dots {
        position: absolute;
        bottom: 20px;
        left: 20px;
        right: 20px;
    }
    
    .slider-nav__prev,
    .slider-nav__next,
    .slider__dot {
        background:green;
        /*backface-visibility: hidden;
        transition: transform 0.3s, box-shadow 0.3s;*/
    }
    
    .slider-nav__prev,
    .slider-nav__next {
        position: absolute;
        top: 50%;
        width: 3rem;
        height: 3rem;
        margin-top: -1.5rem;
        line-height: 3rem;
    }
    
    .slider-nav__prev {
        left: 7%;
    }
    
    .slider-nav__next {
        right: 7%;
    }
    
    .slider__dot {
        display: inline-block;
        width: 1rem;
        height: 1rem;
        margin: 0 1rem;
    }
    /*
    .slider-nav__prev:hover,
    .slider-nav__next:hover,
    .slider__dot.active,
    .slider__dot:hover {
        transform: scale3d(1.5, 1.5, 1);
    }*/
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div class="slider-box">
      <div class="slider" id="slider1">
        <div class="slider__item">
          <img src="https://placeimg.com/960/540/animals" alt="">
          <h2 class="slider__item__title">Slide 1 Title</h2>
        </div>
        <div class="slider__item">
          <img src="https://placeimg.com/960/540/arch" alt="">
          <h2 class="slider__item__title">Slide 2 Title</h2>
        </div>
        <div class="slider__item">
          <img src="https://placeimg.com/960/540/nature" alt="">
          <h2 class="slider__item__title">Slide 3 Title</h2>
        </div>
        <div class="slider__item">
          <img src="https://placeimg.com/960/540/people" alt="">
          <h2 class="slider__item__title">Slide 4 Title</h2>
        </div>
        <div class="slider__item">
          <img src="https://placeimg.com/960/540/tech" alt="">
          <h2 class="slider__item__title">Slide 5 Title</h2>
        </div>
      </div>
    
      <div class="slider" id="slider2">
        <div class="slider__item">
          <img src="https://placeimg.com/960/540/animals" alt="">
          <h2 class="slider__item__title">Slide 1 Title</h2>
        </div>
        <div class="slider__item">
          <img src="https://placeimg.com/960/540/arch" alt="">
          <h2 class="slider__item__title">Slide 2 Title</h2>
        </div>
        <div class="slider__item">
          <img src="https://placeimg.com/960/540/nature" alt="">
          <h2 class="slider__item__title">Slide 3 Title</h2>
        </div>
        <div class="slider__item">
          <img src="https://placeimg.com/960/540/people" alt="">
          <h2 class="slider__item__title">Slide 4 Title</h2>
        </div>
        <div class="slider__item">
          <img src="https://placeimg.com/960/540/tech" alt="">
          <h2 class="slider__item__title">Slide 5 Title</h2>
        </div>
      </div>
    </div>
    
    <div class="slider-nav">
      <div class="slider-nav__prev" id="prev"><i class="fa fa-angle-left"></i></div>
      <div class="slider-nav__next" id="next"><i class="fa fa-angle-right"></i></div>
      <div class="slider-nav__dots" id="dots"></div>
    </div>