Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check for data-interval on the first slide of carousel #31818

Merged
merged 14 commits into from Nov 1, 2020
26 changes: 18 additions & 8 deletions js/src/carousel.js
Expand Up @@ -181,6 +181,8 @@ class Carousel {
}

if (this._config && this._config.interval && !this._isPaused) {
this._updateInterval()

this._interval = setInterval(
(document.visibilityState ? this.nextWhenVisible : this.next).bind(this),
this._config.interval
Expand Down Expand Up @@ -409,6 +411,21 @@ class Carousel {
}
}

_updateInterval() {
const element = this._activeElement || SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element)

if (element) {
XhmikosR marked this conversation as resolved.
Show resolved Hide resolved
const elementInterval = parseInt(element.getAttribute('data-interval'), 10)

if (elementInterval) {
this._config.defaultInterval = this._config.defaultInterval || this._config.interval
this._config.interval = elementInterval
} else {
this._config.interval = this._config.defaultInterval || this._config.interval
}
}
}

_slide(direction, element) {
const activeElement = SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element)
const activeElementIndex = this._getItemIndex(activeElement)
Expand Down Expand Up @@ -454,6 +471,7 @@ class Carousel {
}

this._setActiveIndicatorElement(nextElement)
this._activeElement = nextElement

if (this._element.classList.contains(CLASS_NAME_SLIDE)) {
nextElement.classList.add(orderClassName)
Expand All @@ -463,14 +481,6 @@ class Carousel {
activeElement.classList.add(directionalClassName)
nextElement.classList.add(directionalClassName)

const nextElementInterval = parseInt(nextElement.getAttribute('data-interval'), 10)
if (nextElementInterval) {
this._config.defaultInterval = this._config.defaultInterval || this._config.interval
this._config.interval = nextElementInterval
} else {
this._config.interval = this._config.defaultInterval || this._config.interval
}

const transitionDuration = getTransitionDurationFromElement(activeElement)

EventHandler.one(activeElement, TRANSITION_END, () => {
Expand Down
42 changes: 34 additions & 8 deletions js/tests/unit/carousel.spec.js
Expand Up @@ -636,27 +636,24 @@ describe('Carousel', () => {
carousel.next()
})

it('should get interval from data attribute in individual item', () => {
it('should update the active element to the next item before sliding', () => {
fixtureEl.innerHTML = [
'<div id="myCarousel" class="carousel slide">',
' <div class="carousel-inner">',
' <div class="carousel-item active">item 1</div>',
' <div class="carousel-item" data-interval="7">item 2</div>',
' <div id="secondItem" class="carousel-item">item 2</div>',
' <div class="carousel-item">item 3</div>',
' </div>',
'</div>'
].join('')

const carouselEl = fixtureEl.querySelector('#myCarousel')
const carousel = new Carousel(carouselEl, {
interval: 1814
})

expect(carousel._config.interval).toEqual(1814)
const secondItemEl = fixtureEl.querySelector('#secondItem')
const carousel = new Carousel(carouselEl)

carousel.next()

expect(carousel._config.interval).toEqual(7)
expect(carousel._activeElement).toEqual(secondItemEl)
})

it('should update indicators if present', done => {
Expand Down Expand Up @@ -876,6 +873,35 @@ describe('Carousel', () => {
expect(window.setInterval).toHaveBeenCalled()
expect(window.clearInterval).toHaveBeenCalled()
})

it('should get interval from data attribute on the active item element', () => {
fixtureEl.innerHTML = [
'<div id="myCarousel" class="carousel slide">',
' <div class="carousel-inner">',
' <div class="carousel-item active" data-interval="7">item 1</div>',
' <div id="secondItem" class="carousel-item" data-interval="9385">item 2</div>',
' <div class="carousel-item">item 3</div>',
' </div>',
'</div>'
].join('')

const carouselEl = fixtureEl.querySelector('#myCarousel')
const secondItemEl = fixtureEl.querySelector('#secondItem')
const carousel = new Carousel(carouselEl, {
interval: 1814
})

expect(carousel._config.interval).toEqual(1814)

carousel.cycle()

expect(carousel._config.interval).toEqual(7)

carousel._activeElement = secondItemEl
carousel.cycle()

expect(carousel._config.interval).toEqual(9385)
})
})

describe('to', () => {
Expand Down