Owlcarousel2: Wrong index in event.item

Created on 7 Sep 2015  Â·  23Comments  Â·  Source: OwlCarousel2/OwlCarousel2

Hello,
I think events dont give the right item.index in loop mode.
When the loop is true, index have a _clones.lenght / 2 offset.

               .on('changed.owl.carousel', function (e) {
                    console.log('index  ', e.item.index - e.relatedTarget._clones.length / 2);
                })

Most helpful comment

plugin for true current item index with loop and others

/**
 * TrueCurrent for Owl Carousel
 * @since 2.0.2
 */
;(function($, window, document, undefined) {
    'use strict';

    var TrueCurrent = function(carousel) {

        var current    = 0;
        var itemsCount = 0;

        /**
         * Reference to the core.
         * @protected
         * @type {Owl}
         */
        this._core = carousel;

        /**
         * The carousel element.
         * @type {jQuery}
         */
        this.$element = this._core.$element;

        /**
         * The carousel true current index.
         * @type {Number}
         */
        this._trueCurrent = 0;

        /**
         * Changed event handler.
         * @protected
         * @type {Object}
         */
        this._handlers = {
            'changed.owl.carousel': $.proxy(function (e) {

                current = (e.item.index + 1) - e.relatedTarget._clones.length / 2;
                itemsCount = e.item.count;

                if (current > itemsCount || current == 0) {
                    current = itemsCount - (current % itemsCount);
                }

                this._trueCurrent = current;
                e.item._trueCurrent = current;

            }, this)
        };

        // register event handlers
        this.$element.on(this._handlers);
    };

    /**
     * Destroys the plugin.
     * @protected
     */
    TrueCurrent.prototype.destroy = function() {
        var handler, control, property, override;

        for (handler in this._handlers) {
            this.$element.off(handler, this._handlers[handler]);
        }
        for (control in this._controls) {
            this._controls[control].remove();
        }
        for (override in this.overides) {
            this._core[override] = this._overrides[override];
        }
        for (property in Object.getOwnPropertyNames(this)) {
            typeof this[property] != 'function' && (this[property] = null);
        }
    };

    $.fn.owlCarousel.Constructor.Plugins.TrueCurrent = TrueCurrent;

})(window.Zepto || window.jQuery, window, document);

All 23 comments

I'm seeing the same thing. Your suggested fix almost corrected it for me, but I had to further modulo the result with the number of items in the carousel like this:
console.log('index ', event.item.index - event.relatedTarget._clones.length / 2 % event.item.count);
I'm really not sure how a bug like this persisted into a released version. But maybe I'm just using it incorrectly.

I had the same problem... In order to create an x / y pager info item I used this:

.on('changed.owl.carousel',function(event) {
      //current will now return current slide #
      var current = (event.item.index + 1) - event.relatedTarget._clones.length / 2;
      var allItems = event.item.count;
      if (current > allItems || current == 0) {
        current = allItems - (current % allItems);
      }

    });

Also have this problem. Neither of the solutions above worked for me though.

If you have a loop: true, and click to view the previous slide after it's loaded then e.item.index returns -1 instead of the index of the last slide.

In the short term I've been able to get around this by using e.page.index instead. This only works in this instance because the slider in question has 1 item per page.

Not sure if anybody is still struggling with this, but i found event.item.index was reporting was different item values based on drag or click, here's the code that created a normalised counter for me.

  // set a flag to alert if previous slide from click
  var prevFlag = false;

  // call event listeners before carousel so it knows its initiated.
  owl.on('prev.owl.carousel', function(event) {
    prevFlag = true
  });

  owl.on('changed.owl.carousel initialized.owl.carousel', function(event) {
    var owlItems  = event.item.count;   // Total number of items (consistent and accurate)
    var item      = event.item.index;   // Owl reported position of the current item (inconsistent and inaccurate)
    var calcItem  = Math.floor(item - (owlItems / 2) + 1); // slightly more logical position of the current item (if not from previous click)

    // if from previous click
    if(prevFlag) {
      if (calcItem === 0) {  // reports 0 instead of last value
        calcItem = owlItems; // solve that problem
      }
    }

    // handle values that fall outside of logical min/max bounds
    if(prevFlag === false && calcItem === 0 || calcItem > owlItems) {
      calcItem = 1;
    }

    // update counter
    console.log(calcItem + '/' + owlItems);

    // reset previous flag
    prevFlag = false
  });

// build carousel
  owl.owlCarousel({
    // autoHeight: true,
    nav: false,
    dots: false,
    items: 1,
    loop: true,
    smartSpeed: 750,
  });

$('.next').click(function() { owl.trigger('next.owl.carousel'); });
$('.prev').click(function() { owl.trigger('prev.owl.carousel'); });

Using event.page (which depends on Navigation plugin) instead of event.item is a fine workaround

event.page.index worked for me

Is someone maintaining that ?

i don't think so :(

small note about using event.page.index: this only works if you have dots navigation enabled. If you disable the dots, you'll allways get -1

More than 1 year to fix an issue like this one?!

plugin for true current item index with loop and others

/**
 * TrueCurrent for Owl Carousel
 * @since 2.0.2
 */
;(function($, window, document, undefined) {
    'use strict';

    var TrueCurrent = function(carousel) {

        var current    = 0;
        var itemsCount = 0;

        /**
         * Reference to the core.
         * @protected
         * @type {Owl}
         */
        this._core = carousel;

        /**
         * The carousel element.
         * @type {jQuery}
         */
        this.$element = this._core.$element;

        /**
         * The carousel true current index.
         * @type {Number}
         */
        this._trueCurrent = 0;

        /**
         * Changed event handler.
         * @protected
         * @type {Object}
         */
        this._handlers = {
            'changed.owl.carousel': $.proxy(function (e) {

                current = (e.item.index + 1) - e.relatedTarget._clones.length / 2;
                itemsCount = e.item.count;

                if (current > itemsCount || current == 0) {
                    current = itemsCount - (current % itemsCount);
                }

                this._trueCurrent = current;
                e.item._trueCurrent = current;

            }, this)
        };

        // register event handlers
        this.$element.on(this._handlers);
    };

    /**
     * Destroys the plugin.
     * @protected
     */
    TrueCurrent.prototype.destroy = function() {
        var handler, control, property, override;

        for (handler in this._handlers) {
            this.$element.off(handler, this._handlers[handler]);
        }
        for (control in this._controls) {
            this._controls[control].remove();
        }
        for (override in this.overides) {
            this._core[override] = this._overrides[override];
        }
        for (property in Object.getOwnPropertyNames(this)) {
            typeof this[property] != 'function' && (this[property] = null);
        }
    };

    $.fn.owlCarousel.Constructor.Plugins.TrueCurrent = TrueCurrent;

})(window.Zepto || window.jQuery, window, document);

This plugin worked for me; kind of a bummer the default behavior doesn't work. The only catch is it is off by 1 but I just fixed that where I use the value. When it's the first item, _trueCurrent should be 0 but it is 1.

Will this ever be fixed? It's setting the active class to the wrong item in my case :( Furthermore I'm using the NG2 Wrapper version of this... so doing this inside the Component class would be much more preferable:

can someone help me finish this:

if (this.homeCarousel.options.loop)
????

Still not fixed

Still open. Weird.

@ThomDigizijn Owl is No longer supported. https://github.com/OwlCarousel2/OwlCarousel2#yeah-so-this-is-pretty-much-dead-do-yourself-a-favor-and-switch-to-tiny-slider

Have got index by using event.page.index. Just enabled dots and set display:none to dots container

This seems to solve issue

let current = (event.item.index + 1) - event.relatedTarget._clones.length / 2;
let itemsCount = event.item.count;

    if (current > itemsCount) {
      current = 1;
    }

    if(current === 0) {
      current = event.item.count;
    }

return current;

Hello , i added this code and fixed this

$(document).on('click', '.owl-dot', function () {
    var owl = $('.owl-carousel');
    owl.trigger('to.owl.carousel', [$(this).index(), 300]);
    $('.owl-dot').removeClass('active');
    $(this).addClass('active');
})

这似乎解决了问题

let current = (event.item.index + 1) - event.relatedTarget._clones.length / 2;
let itemsCount = event.item.count;

    if (current > itemsCount) {
      current = 1;
    }

    if(current === 0) {
      current = event.item.count;
    }

return current;

This code correctly solves Wrong index if loop-option is enabled

Complete project:
$(function(){
var owl = $('.owl-carousel');
owl.owlCarousel({
autoplay: 2000,
items:1,
loop: true,
onInitialized : counter, //When the plugin has initialized.
onTranslated : counter //When the translation of the stage has finished.
});

function counter(event) {
    var items = event.item.count;   
    let  item = (event.item.index + 1) - event.relatedTarget._clones.length / 2;
    let itemsCount = event.item.count;
    if ( item > itemsCount) {
       item = 1;
    }
    if( item === 0) {
       item = event.item.count;
    }
    $('#counter').html( item + '/' + items);
}

});

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Dipak-Chandran picture Dipak-Chandran  Â·  3Comments

JezCheese picture JezCheese  Â·  3Comments

jhig85 picture jhig85  Â·  3Comments

Uranbold picture Uranbold  Â·  3Comments

hopea114y picture hopea114y  Â·  3Comments