diff options
| author | Johann-S <[email protected]> | 2018-10-14 13:59:51 +0200 |
|---|---|---|
| committer | XhmikosR <[email protected]> | 2018-10-20 15:32:09 +0300 |
| commit | c08652cfe84051184570d704d3a0904e8d01358c (patch) | |
| tree | 789d1a191cfd9fbc6632b564d756eae42cf9cd40 /js | |
| parent | caefd7046372e954d21550bbdadcabf98b2a86f0 (diff) | |
| download | bootstrap-c08652cfe84051184570d704d3a0904e8d01358c.tar.xz bootstrap-c08652cfe84051184570d704d3a0904e8d01358c.zip | |
swipe left/right without hammerjs
Diffstat (limited to 'js')
| -rw-r--r-- | js/src/carousel.js | 100 | ||||
| -rw-r--r-- | js/tests/index.html | 1 | ||||
| -rw-r--r-- | js/tests/karma.conf.js | 11 | ||||
| -rw-r--r-- | js/tests/unit/carousel.js | 73 | ||||
| -rw-r--r-- | js/tests/visual/carousel.html | 1 |
5 files changed, 102 insertions, 84 deletions
diff --git a/js/src/carousel.js b/js/src/carousel.js index b2765ac5a..5b6209460 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -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) { diff --git a/js/tests/index.html b/js/tests/index.html index 201e15f2a..1bcdc5380 100644 --- a/js/tests/index.html +++ b/js/tests/index.html @@ -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"> diff --git a/js/tests/karma.conf.js b/js/tests/karma.conf.js index c3c64e885..807f977d9 100644 --- a/js/tests/karma.conf.js +++ b/js/tests/karma.conf.js @@ -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' ] diff --git a/js/tests/unit/carousel.js b/js/tests/unit/carousel.js index 0bc52219e..e416ab20e 100644 --- a/js/tests/unit/carousel.js +++ b/js/tests/unit/carousel.js @@ -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) - - return - } + assert.expect(3) + Simulator.setType('touch') - 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() + }) + }) }) diff --git a/js/tests/visual/carousel.html b/js/tests/visual/carousel.html index cd917caa6..630f870cf 100644 --- a/js/tests/visual/carousel.html +++ b/js/tests/visual/carousel.html @@ -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> |
