1
0
mirror of https://github.com/twbs/bootstrap.git synced 2025-08-08 14:46:34 +02:00

swipe left/right without hammerjs

This commit is contained in:
Johann-S
2018-10-14 13:59:51 +02:00
committed by XhmikosR
parent caefd70463
commit c08652cfe8
16 changed files with 122 additions and 158 deletions

View File

@@ -1,7 +1,3 @@
import $ from 'jquery'
import Hammer from 'hammerjs'
import Util from './util'
/**
* --------------------------------------------------------------------------
* Bootstrap (v4.1.3): carousel.js
@@ -9,6 +5,9 @@ import Util from './util'
* --------------------------------------------------------------------------
*/
import $ from 'jquery'
import Util from './util'
/**
* ------------------------------------------------------------------------
* Constants
@@ -24,7 +23,7 @@ const JQUERY_NO_CONFLICT = $.fn[NAME]
const ARROW_LEFT_KEYCODE = 37 // KeyboardEvent.which value for left arrow key
const ARROW_RIGHT_KEYCODE = 39 // KeyboardEvent.which value for right arrow key
const TOUCHEVENT_COMPAT_WAIT = 500 // Time for mouse compat events to fire after touch
const HAMMER_ENABLED = typeof Hammer !== 'undefined'
const SWIPE_THRESHOLD = 40
const Default = {
interval : 5000,
@@ -58,10 +57,10 @@ const Event = {
MOUSEENTER : `mouseenter${EVENT_KEY}`,
MOUSELEAVE : `mouseleave${EVENT_KEY}`,
TOUCHEND : `touchend${EVENT_KEY}`,
TOUCHSTART : `touchstart${EVENT_KEY}`,
TOUCHMOVE : `touchmove${EVENT_KEY}`,
LOAD_DATA_API : `load${EVENT_KEY}${DATA_API_KEY}`,
CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`,
SWIPELEFT : 'swipeleft',
SWIPERIGHT : 'swiperight'
CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`
}
const ClassName = {
@@ -98,22 +97,13 @@ class Carousel {
this._isPaused = false
this._isSliding = false
this.touchTimeout = null
this.hammer = null
this.touchStartX = 0
this.touchDeltaX = 0
this._config = this._getConfig(config)
this._element = element
this._indicatorsElement = this._element.querySelector(Selector.INDICATORS)
this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0
if (HAMMER_ENABLED && this._touchSupported && this._config.touch) {
this.hammer = new Hammer(this._element, {
recognizers: [[
Hammer.Swipe, {
direction: Hammer.DIRECTION_HORIZONTAL
}
]]
})
}
this._touchSupported = 'ontouchstart' in document.documentElement
this._addEventListeners()
}
@@ -235,22 +225,65 @@ class Carousel {
return config
}
_handleSwipe() {
const absDeltax = Math.abs(this.touchDeltaX)
if (absDeltax <= SWIPE_THRESHOLD) {
return
}
const direction = absDeltax / this.touchDeltaX
// swipe left
if (direction > 0) {
this.prev()
}
// swipe right
if (direction < 0) {
this.next()
}
}
_addEventListeners() {
if (this._config.keyboard) {
$(this._element)
.on(Event.KEYDOWN, (event) => this._keydown(event))
}
if (this.hammer) {
this.hammer.on(Event.SWIPELEFT, () => this.next())
this.hammer.on(Event.SWIPERIGHT, () => this.prev())
}
if (this._config.pause === 'hover') {
$(this._element)
.on(Event.MOUSEENTER, (event) => this.pause(event))
.on(Event.MOUSELEAVE, (event) => this.cycle(event))
if (this._touchSupported) {
}
this._addTouchEventListeners()
}
_addTouchEventListeners() {
if (!this._touchSupported) {
return
}
$(this._element).on(Event.TOUCHSTART, (event) => {
this.touchStartX = event.originalEvent.touches[0].pageX
})
$(this._element).on(Event.TOUCHMOVE, (event) => {
event.preventDefault()
// ensure swiping with one touch and not pinching
if (event.originalEvent.touches.length > 1) {
return
}
this.touchDeltaX = event.originalEvent.touches[0].pageX - this.touchStartX
})
$(this._element).on(Event.TOUCHEND, () => {
this._handleSwipe()
if (this._config.pause === 'hover') {
// If it's a touch-enabled device, mouseenter/leave are fired as
// part of the mouse compatibility events on first tap - the carousel
// would stop cycling until user tapped out of it;
@@ -258,15 +291,14 @@ class Carousel {
// (as if it's the second time we tap on it, mouseenter compat event
// is NOT fired) and after a timeout (to allow for mouse compatibility
// events to fire) we explicitly restart cycling
$(this._element).on(Event.TOUCHEND, () => {
this.pause()
if (this.touchTimeout) {
clearTimeout(this.touchTimeout)
}
this.touchTimeout = setTimeout((event) => this.cycle(event), TOUCHEVENT_COMPAT_WAIT + this._config.interval)
})
this.pause()
if (this.touchTimeout) {
clearTimeout(this.touchTimeout)
}
this.touchTimeout = setTimeout((event) => this.cycle(event), TOUCHEVENT_COMPAT_WAIT + this._config.interval)
}
}
})
}
_keydown(event) {

View File

@@ -20,7 +20,6 @@
}())
</script>
<script src="../../node_modules/popper.js/dist/umd/popper.min.js"></script>
<script src="../../node_modules/hammerjs/hammer.min.js"></script>
<!-- QUnit -->
<link rel="stylesheet" href="../../node_modules/qunit/qunit/qunit.css" media="screen">

View File

@@ -12,16 +12,16 @@ const jqueryFile = process.env.USE_OLD_JQUERY ? 'https://code.jquery.com/jquery-
const bundle = process.env.BUNDLE === 'true'
const browserStack = process.env.BROWSER === 'true'
const plugins = [
'karma-qunit',
'karma-sinon'
]
const frameworks = [
'qunit',
'sinon'
]
const plugins = [
'karma-qunit',
'karma-sinon'
]
const reporters = ['dots']
const detectBrowsers = {
@@ -48,7 +48,6 @@ const customLaunchers = {
let files = [
'node_modules/popper.js/dist/umd/popper.min.js',
'node_modules/hammerjs/hammer.min.js',
'node_modules/hammer-simulator/index.js'
]

View File

@@ -3,8 +3,6 @@ $(function () {
window.Carousel = typeof bootstrap !== 'undefined' ? bootstrap.Carousel : Carousel
var touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0
QUnit.module('carousel plugin')
QUnit.test('should be defined on jQuery object', function (assert) {
@@ -1009,13 +1007,8 @@ $(function () {
})
QUnit.test('should allow swiperight and call prev', function (assert) {
if (!touchSupported) {
assert.expect(0)
return
}
assert.expect(2)
Simulator.setType('touch')
assert.expect(3)
var done = assert.async()
document.documentElement.ontouchstart = $.noop
@@ -1035,10 +1028,13 @@ $(function () {
$carousel.appendTo('#qunit-fixture')
var $item = $('#item')
$carousel.bootstrapCarousel()
var carousel = $carousel.data('bs.carousel')
var spy = sinon.spy(carousel, 'prev')
$carousel.one('slid.bs.carousel', function () {
assert.ok(true, 'slid event fired')
assert.ok($item.hasClass('active'))
assert.ok(spy.called)
delete document.documentElement.ontouchstart
done()
})
@@ -1049,40 +1045,10 @@ $(function () {
})
})
QUnit.test('should not use HammerJS when touch option is false', function (assert) {
assert.expect(1)
var $carousel = $('<div></div>').appendTo('#qunit-fixture')
$carousel.bootstrapCarousel({
touch: false
})
var carousel = $carousel.data('bs.carousel')
assert.strictEqual(carousel.hammer, null)
})
QUnit.test('should use HammerJS when touch option is true', function (assert) {
assert.expect(1)
document.documentElement.ontouchstart = $.noop
var $carousel = $('<div></div>').appendTo('#qunit-fixture')
$carousel.bootstrapCarousel()
var carousel = $carousel.data('bs.carousel')
assert.ok(carousel.hammer !== null)
})
QUnit.test('should allow swipeleft and call next', function (assert) {
if (!touchSupported) {
assert.expect(0)
assert.expect(3)
Simulator.setType('touch')
return
}
assert.expect(2)
var done = assert.async()
document.documentElement.ontouchstart = $.noop
@@ -1102,11 +1068,13 @@ $(function () {
$carousel.appendTo('#qunit-fixture')
var $item = $('#item')
$carousel.bootstrapCarousel()
var carousel = $carousel.data('bs.carousel')
var spy = sinon.spy(carousel, 'next')
$carousel.one('slid.bs.carousel', function () {
assert.ok(true, 'slid event fired')
assert.ok(!$item.hasClass('active'))
delete document.documentElement.ontouchstart
assert.ok(spy.called)
done()
})
@@ -1116,4 +1084,25 @@ $(function () {
deltaY: 0
})
})
QUnit.test('should not allow pinch', function (assert) {
assert.expect(0)
Simulator.setType('touch')
var done = assert.async()
document.documentElement.ontouchstart = $.noop
var carouselHTML = '<div class="carousel" data-interval="false"></div>'
var $carousel = $(carouselHTML)
$carousel.appendTo('#qunit-fixture')
$carousel.bootstrapCarousel()
Simulator.gestures.swipe($carousel[0], {
pos: [300, 10],
deltaX: -300,
deltaY: 0,
touches: 2
}, function () {
done()
})
})
})

View File

@@ -46,7 +46,6 @@
</div>
<script src="../../../site/docs/4.1/assets/js/vendor/jquery-slim.min.js"></script>
<script src="../../../node_modules/hammerjs/hammer.min.js"></script>
<script src="../../dist/util.js"></script>
<script src="../../dist/carousel.js"></script>
<script>