diff --git a/lib/components/FullPage.js b/lib/components/FullPage.js index dcaccbc..90f4807 100644 --- a/lib/components/FullPage.js +++ b/lib/components/FullPage.js @@ -106,22 +106,69 @@ var FullPage = /*#__PURE__*/function (_React$Component) { _this.onTouchStart = function (evt) { _this._touchStart = evt.touches[0].clientY; + _this._touchStartX = evt.touches[0].clientX; _this._isScrolledAlready = false; }; + _this.isVerticalScrollIntent = function (changedTouches) { + var diffX = Math.abs(_this._touchStartX - changedTouches.clientX); + var diffY = Math.abs(_this._touchStart - changedTouches.clientY); + return diffY - _this.props.touchSensitivity > 0 && diffY >= diffX; + }; + + _this.isScrollHappensInMainContainer = function (element) { + var el = element; + + while (el) { + if (el == _this.mainContainerRef.current) { + return true; + } + + el = el.parentElement; + } + }; + _this.onTouchMove = function (evt) { - if (_this.props.scrollMode !== scrollMode.FULL_PAGE) { + if (_this.props.scrollMode !== scrollMode.FULL_PAGE || !_this.isScrollHappensInMainContainer(evt.target)) { return; } - evt.preventDefault(); + if (!_this.isVerticalScrollIntent(evt.changedTouches[0])) { + evt.preventDefault(); + return; + } + + var touchSensitivity = _this.props.touchSensitivity; var touchEnd = evt.changedTouches[0].clientY; + var childHasVerticalScroll = false; + var element = evt.target; + + while (element) { + if (element == _this.mainContainerRef.current) { + break; + } else { + var overFlowY = window.getComputedStyle(element)['overflow-y']; + + if ((overFlowY == 'auto' || overFlowY == 'scroll') && element.scrollHeight > element.clientHeight) { + if (_this._touchStart > touchEnd + touchSensitivity && element.scrollHeight > element.scrollTop + element.clientHeight || _this._touchStart < touchEnd - touchSensitivity && element.scrollTop > 0) { + childHasVerticalScroll = true; + break; + } + } + } + + element = element.parentElement; + } + + if (!childHasVerticalScroll) { + evt.preventDefault(); - if (!_this._isScrollPending && !_this._isScrolledAlready) { - if (_this._touchStart > touchEnd + _this._touchSensitivity) { - _this.scrollToSlide(_this.state.activeSlide + 1); - } else if (_this._touchStart < touchEnd - _this._touchSensitivity) { - _this.scrollToSlide(_this.state.activeSlide - 1); + if (!_this._isScrollPending && !_this._isScrolledAlready) { + if (_this._touchStart > touchEnd + touchSensitivity) { + _this.scrollToSlide(_this.state.activeSlide + 1); + } else if (_this._touchStart < touchEnd - touchSensitivity) { + _this.scrollToSlide(_this.state.activeSlide - 1); + } } } }; @@ -194,9 +241,9 @@ var FullPage = /*#__PURE__*/function (_React$Component) { _this._isScrollPending = false; _this._isScrolledAlready = false; _this._slides = []; - _this._touchSensitivity = 5; _this._touchStart = 0; _this._isMobile = null; + _this.mainContainerRef = /*#__PURE__*/_react.default.createRef(); _this.state = { activeSlide: props.initialSlide, slidesCount: FullPage.getChildrenCount(_this.props.children) @@ -289,6 +336,7 @@ var FullPage = /*#__PURE__*/function (_React$Component) { key: "render", value: function render() { return /*#__PURE__*/_react.default.createElement("div", { + ref: this.mainContainerRef, style: { height: this.state.height } @@ -328,5 +376,6 @@ FullPage.defaultProps = { controlsProps: {}, duration: 700, initialSlide: 0, - scrollMode: scrollMode.FULL_PAGE + scrollMode: scrollMode.FULL_PAGE, + touchSensitivity: 5 }; \ No newline at end of file diff --git a/src/components/FullPage.jsx b/src/components/FullPage.jsx index 4b00886..1eb4f8d 100644 --- a/src/components/FullPage.jsx +++ b/src/components/FullPage.jsx @@ -24,9 +24,9 @@ export default class FullPage extends React.Component { this._isScrollPending = false; this._isScrolledAlready = false; this._slides = []; - this._touchSensitivity = 5; this._touchStart = 0; this._isMobile = null; + this.mainContainerRef = React.createRef(); this.state = { activeSlide: props.initialSlide, @@ -96,22 +96,78 @@ export default class FullPage extends React.Component { onTouchStart = (evt) => { this._touchStart = evt.touches[0].clientY; + this._touchStartX = evt.touches[0].clientX; this._isScrolledAlready = false; } + isVerticalScrollIntent = (changedTouches) => { + const diffX = Math.abs(this._touchStartX - changedTouches.clientX) + const diffY = Math.abs(this._touchStart - changedTouches.clientY); + + return diffY - this.props.touchSensitivity > 0 && diffY >= diffX; + } + + isScrollHappensInMainContainer = (element) => { + var el = element; + while(el) { + if (el == this.mainContainerRef.current) { + return true; + } + el = el.parentElement; + } + + } + onTouchMove = (evt) => { - if (this.props.scrollMode !== scrollMode.FULL_PAGE) { + if (this.props.scrollMode !== scrollMode.FULL_PAGE || !this.isScrollHappensInMainContainer(evt.target) ) { return; } - evt.preventDefault(); + if (!this.isVerticalScrollIntent(evt.changedTouches[0])) { + evt.preventDefault(); + return; + } + + + const {touchSensitivity} = this.props; const touchEnd = evt.changedTouches[0].clientY; - if (!this._isScrollPending && !this._isScrolledAlready) { - if (this._touchStart > touchEnd + this._touchSensitivity) { - this.scrollToSlide(this.state.activeSlide + 1); - } else if (this._touchStart < touchEnd - this._touchSensitivity) { - this.scrollToSlide(this.state.activeSlide - 1); + var childHasVerticalScroll = false; + var element = evt.target; + while(element) { + if (element == this.mainContainerRef.current) { + break; + } else { + var overFlowY = window.getComputedStyle(element)['overflow-y'] + if ( (overFlowY == 'auto' || overFlowY == 'scroll') && element.scrollHeight > element.clientHeight) { + if ( (this._touchStart > touchEnd + touchSensitivity && element.scrollHeight > (element.scrollTop+element.clientHeight) ) || + (this._touchStart < touchEnd - touchSensitivity && element.scrollTop > 0) + + ) { + childHasVerticalScroll = true; + break; + } + + } + } + element = element.parentElement; + } + + + + + if (!childHasVerticalScroll) { + + evt.preventDefault(); + + + + if (!this._isScrollPending && !this._isScrolledAlready) { + if (this._touchStart > touchEnd + touchSensitivity) { + this.scrollToSlide(this.state.activeSlide + 1); + } else if (this._touchStart < touchEnd - touchSensitivity) { + this.scrollToSlide(this.state.activeSlide - 1); + } } } } @@ -201,7 +257,7 @@ export default class FullPage extends React.Component { render() { return ( -