Last active
March 16, 2018 22:36
-
-
Save sounisi5011/5c3b5c914d8663111b6a0d8f30bb1bf7 to your computer and use it in GitHub Desktop.
端までスクロールしたらコンソールに出力するテストコード
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<meta charset=utf-8> | |
<meta name=viewport content="width=device-width,initial-scale=1"> | |
<meta name=format-detection content="telephone=no,email=no,address=no"> | |
<title>端までスクロールしたらコンソールに出力するテストコード</title> | |
<link href="main.css" rel=stylesheet> | |
<h1>端までスクロールしたらコンソールに出力するテストコード</h1> | |
<h2>Gist</h2> | |
<p><a href="https://gist.github.com/sounisi5011/5c3b5c914d8663111b6a0d8f30bb1bf7">https://gist.github.com/sounisi5011/5c3b5c914d8663111b6a0d8f30bb1bf7</a> | |
<script src="https://cdn.rawgit.com/sounisi5011/6d0be09d2f2a2853974bfe9a20d229bc/raw/constants.min.js"></script> | |
<script src="main.js"></script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
html { | |
width: 200%; | |
height: 200%; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @see https://www.w3.org/TR/cssom-view-1/#extensions-to-the-window-interface | |
* @see https://www.w3.org/TR/cssom-view-1/#extensions-to-the-document-interface | |
* @see https://www.w3.org/TR/cssom-view-1/#extension-to-the-element-interface | |
*/ | |
/** | |
* ウィンドウのスクロール量を取得する | |
* @see https://dev.opera.com/articles/fixing-the-scrolltop-bug/ | |
* @see https://qiita.com/rryu/items/c83e54cff15755b37426 | |
*/ | |
class ScrollData { | |
/** | |
* @param {!Window} targetWindow ウィンドウに対応するwindowオブジェクト | |
*/ | |
constructor(targetWindow = window) { | |
const targetDocument = targetWindow.document; | |
const scrollingElem = targetDocument.scrollingElement || ( | |
targetWindow.navigator.userAgent.includes('WebKit') ? | |
targetDocument.body : | |
targetDocument.documentElement | |
); | |
/** @type {number} */ | |
this.x; | |
/** @type {number} */ | |
this.y; | |
/** @type {number} */ | |
this.maxX; | |
/** @type {number} */ | |
this.maxY; | |
Object.defineProperties(this, { | |
x: { | |
value: ( | |
//targetWindow.scrollX | |
scrollingElem.scrollLeft | |
), | |
enumerable: true, | |
}, | |
y: { | |
value: ( | |
//targetWindow.scrollY | |
scrollingElem.scrollTop | |
), | |
enumerable: true, | |
}, | |
maxX: { | |
value: ( | |
//scrollingElem.scrollWidth + (targetWindow.innerWidth - scrollingElem.clientWidth) - targetWindow.innerWidth | |
scrollingElem.scrollWidth - scrollingElem.clientWidth | |
), | |
enumerable: true, | |
}, | |
maxY: { | |
value: ( | |
//scrollingElem.scrollHeight + (targetWindow.innerHeight - scrollingElem.clientHeight) - targetWindow.innerHeight | |
scrollingElem.scrollHeight - scrollingElem.clientHeight | |
), | |
enumerable: true, | |
}, | |
}); | |
} | |
} | |
/** | |
* いずれかの修飾キーが押下されているか判定する | |
* @param {!KeyboardEvent} keyEvent | |
* @return {boolean} | |
*/ | |
function isActivatedAnyModifierKey(keyEvent) { | |
if (keyEvent.ctrlKey || keyEvent.altKey || keyEvent.shiftKey || keyEvent.metaKey) { | |
return true; | |
} | |
if (typeof keyEvent.getModifierState === 'function') { | |
for (const key of MODIFIER_KEYS_SET) { | |
if (keyEvent.getModifierState(key)) { | |
return true; | |
} | |
} | |
} | |
return false; | |
} | |
const topWallElem = document.createElement('div'); | |
topWallElem.style.position = 'fixed'; | |
const leftWallElem = topWallElem.cloneNode(false); | |
topWallElem.style.cssText += 'left: 0px; right: 0px; height: 2em;'; | |
leftWallElem.style.cssText += 'top: 0px; bottom: 0px; width: 2em;'; | |
const bottomWallElem = topWallElem.cloneNode(false); | |
const rightWallElem = leftWallElem.cloneNode(false); | |
topWallElem.style.cssText += 'top: 0px; background-image: linear-gradient(red, transparent);'; | |
bottomWallElem.style.cssText += 'bottom: 0px; background-image: linear-gradient(transparent, red);'; | |
leftWallElem.style.cssText += 'left: 0px; background-image: linear-gradient(90deg, red, transparent);'; | |
rightWallElem.style.cssText += 'right: 0px; background-image: linear-gradient(90deg, transparent, red);'; | |
/** | |
* @type {!WeakMap.<Element, number>} | |
*/ | |
const timeoutIdMap = new WeakMap; | |
function showWallElem(targetWallElem) { | |
if (!targetWallElem.parentNode) { | |
document.body.appendChild(targetWallElem); | |
} | |
if (timeoutIdMap.has(targetWallElem)) { | |
clearTimeout(timeoutIdMap.get(targetWallElem)); | |
} | |
timeoutIdMap.set( | |
targetWallElem, | |
setTimeout(() => { | |
const parentElem = targetWallElem.parentNode; | |
if (parentElem) { | |
parentElem.removeChild(targetWallElem); | |
} | |
}, 500) | |
); | |
} | |
/** | |
* @type {!Map.<string, ScrollData>} | |
*/ | |
const keyMap = new Map; | |
const keyListener = e => { | |
const key = e.key; | |
/* | |
* 矢印キーのイベントであれば、以降の処理を実行する | |
*/ | |
if (/^Arrow/.test(key)) { | |
/* | |
* 修飾キーが押下されていなければ、以降の処理を実行する | |
*/ | |
if (!isActivatedAnyModifierKey(e)) { | |
const type = e.type; | |
const scroll = new ScrollData; | |
if (type === 'keydown') { | |
if (!keyMap.has(key)) { | |
keyMap.set(key, scroll); | |
} | |
} else if (type === 'keyup') { | |
if (keyMap.has(key)) { | |
const prevScroll = keyMap.get(key); | |
if (/^Arrow(?:Left|Right)$/.test(key) && prevScroll.x === scroll.x) { | |
if (0 < scroll.x) { | |
showWallElem(rightWallElem); | |
console.log(`Max scroll X`); | |
} else { | |
showWallElem(leftWallElem); | |
console.log(`Min scroll X`); | |
} | |
console.log(key, prevScroll, scroll); | |
} | |
if (/^Arrow(?:Up|Down)$/.test(key) && prevScroll.y === scroll.y) { | |
if (0 < scroll.y) { | |
showWallElem(bottomWallElem); | |
console.log(`Max scroll Y`); | |
} else { | |
showWallElem(topWallElem); | |
console.log(`Min scroll Y`); | |
} | |
console.log(key, prevScroll, scroll); | |
} | |
keyMap.delete(key); | |
} | |
} | |
} | |
} | |
}; | |
window.addEventListener('keydown', keyListener, {passive: true}); | |
window.addEventListener('keyup', keyListener, {passive: true}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment