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

Fix scroll lock for iOS devices #207

Merged
merged 5 commits into from
Jun 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 76 additions & 4 deletions examples/modal/bundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ enableBodyScrollButton.onclick = function() {
var documentListenerAdded = false;
var initialClientY = -1;
var previousBodyOverflowSetting = void 0;
var previousBodyPosition = void 0;
var previousBodyPaddingRight = void 0;

// returns true if `el` should be allowed to receive touchmove events.
Expand Down Expand Up @@ -126,8 +127,9 @@ enableBodyScrollButton.onclick = function() {
var scrollBarGap = window.innerWidth - document.documentElement.clientWidth;

if (_reserveScrollBarGap && scrollBarGap > 0) {
var computedBodyPaddingRight = parseInt(window.getComputedStyle(document.body).getPropertyValue('padding-right'), 10);
previousBodyPaddingRight = document.body.style.paddingRight;
document.body.style.paddingRight = scrollBarGap + 'px';
document.body.style.paddingRight = computedBodyPaddingRight + scrollBarGap + 'px';
}
}

Expand Down Expand Up @@ -156,6 +158,64 @@ enableBodyScrollButton.onclick = function() {
}
};

var setPositionFixed = function setPositionFixed() {
return window.requestAnimationFrame(function () {
// If previousBodyPosition is already set, don't set it again.
if (previousBodyPosition === undefined) {
previousBodyPosition = {
position: document.body.style.position,
top: document.body.style.top,
left: document.body.style.left
};

// Update the dom inside an animation frame
var _window = window,
scrollY = _window.scrollY,
scrollX = _window.scrollX,
innerHeight = _window.innerHeight;

document.body.style.position = 'fixed';
document.body.style.top = -scrollY;
document.body.style.left = -scrollX;

setTimeout(function () {
return window.requestAnimationFrame(function () {
// Attempt to check if the bottom bar appeared due to the position change
var bottomBarHeight = innerHeight - window.innerHeight;
// console.log({
// bottomBarHeight,
// innerHeight,
// innerHeightNew: window.innerHeight,
// scrollY
// })
if (bottomBarHeight && scrollY >= innerHeight) {
// Move the content further up so that the bottom bar doesn't hide it
document.body.style.top = -(scrollY + bottomBarHeight);
}
});
}, 300);
}
});
};

var restorePositionSetting = function restorePositionSetting() {
if (previousBodyPosition !== undefined) {
// Convert the position from "px" to Int
var y = -parseInt(document.body.style.top, 10);
var x = -parseInt(document.body.style.left, 10);

// Restore styles
document.body.style.position = previousBodyPosition.position;
document.body.style.top = previousBodyPosition.top;
document.body.style.left = previousBodyPosition.left;

// Restore scroll
window.scrollTo(x, y);

previousBodyPosition = undefined;
}
};

// https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight#Problems_and_solutions
var isTargetElementTotallyScrolled = function isTargetElementTotallyScrolled(targetElement) {
return targetElement ? targetElement.scrollHeight - targetElement.scrollTop <= targetElement.clientHeight : false;
Expand Down Expand Up @@ -204,6 +264,12 @@ enableBodyScrollButton.onclick = function() {

locks = [].concat(_toConsumableArray(locks), [lock]);

if (isIosDevice) {
setPositionFixed();
} else {
setOverflowHidden(options);
}

if (isIosDevice) {
targetElement.ontouchstart = function (event) {
if (event.targetTouches.length === 1) {
Expand All @@ -222,8 +288,6 @@ enableBodyScrollButton.onclick = function() {
document.addEventListener('touchmove', preventDefault, hasPassiveEvents ? { passive: false } : undefined);
documentListenerAdded = true;
}
} else {
setOverflowHidden(options);
}
};

Expand All @@ -242,6 +306,10 @@ enableBodyScrollButton.onclick = function() {

// Reset initial clientY.
initialClientY = -1;
}

if (isIosDevice) {
restorePositionSetting();
} else {
restoreOverflowSetting();
}
Expand All @@ -268,7 +336,11 @@ enableBodyScrollButton.onclick = function() {
document.removeEventListener('touchmove', preventDefault, hasPassiveEvents ? { passive: false } : undefined);
documentListenerAdded = false;
}
} else if (!locks.length) {
}

if (isIosDevice) {
restorePositionSetting();
} else {
restoreOverflowSetting();
}
};
Expand Down
114 changes: 95 additions & 19 deletions examples/vanilla/bundle.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,30 @@
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
const bodyScrollLock = require('../../lib/bodyScrollLock.js');

const disableBodyScrollButton = document.querySelector('.disableBodyScroll');
const enableBodyScrollButton = document.querySelector('.enableBodyScroll');
const statusElement = document.querySelector('.bodyScrollLockStatus');
function initialize(id) {
const disableBodyScrollButton = document.querySelector(`.disableBodyScroll.${id}`);
const enableBodyScrollButton = document.querySelector(`.enableBodyScroll.${id}`);
const statusElement = document.querySelector(`.bodyScrollLockStatus.${id}`);

disableBodyScrollButton.onclick = function() {
console.info('disableBodyScrollButton');
bodyScrollLock.disableBodyScroll(document.querySelector('.scrollTarget'));
disableBodyScrollButton.onclick = function() {
console.info(`disableBodyScrollButton ${id}`);
bodyScrollLock.disableBodyScroll(document.querySelector(`.scrollTarget.${id}`));

statusElement.innerHTML = ' &mdash; Scroll Locked';
statusElement.style.color = 'red';
};
statusElement.innerHTML = ' &mdash; Scroll Locked';
statusElement.style.color = 'red';
};

enableBodyScrollButton.onclick = function() {
console.info('enableBodyScrollButton');
bodyScrollLock.enableBodyScroll(document.querySelector('.scrollTarget'));
enableBodyScrollButton.onclick = function() {
console.info(`enableBodyScrollButton ${id}`);
bodyScrollLock.enableBodyScroll(document.querySelector(`.scrollTarget.${id}`));

statusElement.innerHTML = ' &mdash; Scroll Unlocked';
statusElement.style.color = '';
};
statusElement.innerHTML = ' &mdash; Scroll Unlocked';
statusElement.style.color = '';
};
}

initialize('top')
initialize('bottom')
},{"../../lib/bodyScrollLock.js":2}],2:[function(require,module,exports){
(function (global, factory) {
if (typeof define === "function" && define.amd) {
Expand Down Expand Up @@ -77,6 +81,7 @@ enableBodyScrollButton.onclick = function() {
var documentListenerAdded = false;
var initialClientY = -1;
var previousBodyOverflowSetting = void 0;
var previousBodyPosition = void 0;
var previousBodyPaddingRight = void 0;

// returns true if `el` should be allowed to receive touchmove events.
Expand Down Expand Up @@ -116,8 +121,9 @@ enableBodyScrollButton.onclick = function() {
var scrollBarGap = window.innerWidth - document.documentElement.clientWidth;

if (_reserveScrollBarGap && scrollBarGap > 0) {
var computedBodyPaddingRight = parseInt(window.getComputedStyle(document.body).getPropertyValue('padding-right'), 10);
previousBodyPaddingRight = document.body.style.paddingRight;
document.body.style.paddingRight = scrollBarGap + 'px';
document.body.style.paddingRight = computedBodyPaddingRight + scrollBarGap + 'px';
}
}

Expand Down Expand Up @@ -146,6 +152,64 @@ enableBodyScrollButton.onclick = function() {
}
};

var setPositionFixed = function setPositionFixed() {
return window.requestAnimationFrame(function () {
// If previousBodyPosition is already set, don't set it again.
if (previousBodyPosition === undefined) {
previousBodyPosition = {
position: document.body.style.position,
top: document.body.style.top,
left: document.body.style.left
};

// Update the dom inside an animation frame
var _window = window,
scrollY = _window.scrollY,
scrollX = _window.scrollX,
innerHeight = _window.innerHeight;

document.body.style.position = 'fixed';
document.body.style.top = -scrollY;
document.body.style.left = -scrollX;

setTimeout(function () {
return window.requestAnimationFrame(function () {
// Attempt to check if the bottom bar appeared due to the position change
var bottomBarHeight = innerHeight - window.innerHeight;
// console.log({
// bottomBarHeight,
// innerHeight,
// innerHeightNew: window.innerHeight,
// scrollY
// })
if (bottomBarHeight && scrollY >= innerHeight) {
// Move the content further up so that the bottom bar doesn't hide it
document.body.style.top = -(scrollY + bottomBarHeight);
}
});
}, 300);
}
});
};

var restorePositionSetting = function restorePositionSetting() {
if (previousBodyPosition !== undefined) {
// Convert the position from "px" to Int
var y = -parseInt(document.body.style.top, 10);
var x = -parseInt(document.body.style.left, 10);

// Restore styles
document.body.style.position = previousBodyPosition.position;
document.body.style.top = previousBodyPosition.top;
document.body.style.left = previousBodyPosition.left;

// Restore scroll
window.scrollTo(x, y);

previousBodyPosition = undefined;
}
};

// https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight#Problems_and_solutions
var isTargetElementTotallyScrolled = function isTargetElementTotallyScrolled(targetElement) {
return targetElement ? targetElement.scrollHeight - targetElement.scrollTop <= targetElement.clientHeight : false;
Expand Down Expand Up @@ -194,6 +258,12 @@ enableBodyScrollButton.onclick = function() {

locks = [].concat(_toConsumableArray(locks), [lock]);

if (isIosDevice) {
setPositionFixed();
} else {
setOverflowHidden(options);
}

if (isIosDevice) {
targetElement.ontouchstart = function (event) {
if (event.targetTouches.length === 1) {
Expand All @@ -212,8 +282,6 @@ enableBodyScrollButton.onclick = function() {
document.addEventListener('touchmove', preventDefault, hasPassiveEvents ? { passive: false } : undefined);
documentListenerAdded = true;
}
} else {
setOverflowHidden(options);
}
};

Expand All @@ -232,6 +300,10 @@ enableBodyScrollButton.onclick = function() {

// Reset initial clientY.
initialClientY = -1;
}

if (isIosDevice) {
restorePositionSetting();
} else {
restoreOverflowSetting();
}
Expand All @@ -258,7 +330,11 @@ enableBodyScrollButton.onclick = function() {
document.removeEventListener('touchmove', preventDefault, hasPassiveEvents ? { passive: false } : undefined);
documentListenerAdded = false;
}
} else if (!locks.length) {
}

if (isIosDevice) {
restorePositionSetting();
} else {
restoreOverflowSetting();
}
};
Expand Down
Loading