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);
})
I think a normalise is missing there:
https://github.com/smashingboxes/OwlCarousel2/blob/develop/src/js/owl.carousel.js#L1470
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);
}
});
Most helpful comment
plugin for true current item index with loop and others