Skip to content

Instantly share code, notes, and snippets.

@pyrsmk
Last active March 15, 2022 10:33
Show Gist options
  • Save pyrsmk/b564c90714bf5a92fb53aecfa30c80eb to your computer and use it in GitHub Desktop.
Save pyrsmk/b564c90714bf5a92fb53aecfa30c80eb to your computer and use it in GitHub Desktop.
Because sometimes we don't understand what's going on with DOM events (even more on mobiles), here's an HTML page to test and understand things 🦄
<!doctype html>
<html>
<head>
<title>Event testing.</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css" integrity="sha512-NhSC1YmyruXifcj/KFRWoC561YpHpc5Jtzgvbuzx5VozKpWvQ+4nXhPdFgmx8xqexRcpAglTj9sIBWINXa8x5w==" crossorigin="anonymous" />
<script src="https://code.jquery.com/jquery-3.6.0.slim.min.js" integrity="sha256-u7e5khyithlIdTpu22PHhENmPcRdFiHRjhAuHcs05RI=" crossorigin="anonymous"></script>
<style>
* {
box-sizing: border-box;
}
html, body {
height: 100%;
}
body {
padding: 1em;
}
</style>
</head>
<body>
<input id="input" type="text" autofocus>
<script>
// https://stackoverflow.com/a/11616993/4112863
function safeStringify (obj, indent = 2)
{
let cache = []
const retVal = JSON.stringify(
obj,
(key, value) =>
typeof value === "object" && value !== null
? cache.includes(value)
? undefined // Duplicate reference found, discard key
: cache.push(value) && value // Store value in our collection
: value,
indent
);
cache = null
return retVal
}
// https://stackoverflow.com/a/7467863/4112863
function nl2br (str)
{
return (str + '').replace(
/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g,
'$1<br>$2'
)
}
// https://stackoverflow.com/a/10474157/4112863
function space2nbsp (str)
{
return str.replace(/ /g, '\u00a0')
}
/**
* @param {String, Object} message
* @returns {void}
*/
function debug (message)
{
if (typeof message != 'string') {
message = space2nbsp(
nl2br(
safeStringify(message)
)
)
}
$('#debugConsole').append(`${message}<br>`)
.scrollTop($('#debugConsole')[0].scrollHeight)
}
/**
* @param {Object} handlers
* @param {Array} bypass
* @returns {void}
*/
function initialize (handlers = {}, bypass = [])
{
$('<div>').attr('id', 'debugConsole')
.css({
width: '100%',
height: '50%',
backgroundColor: 'crimson',
color: 'white',
fontWeight: 'bold',
position: 'absolute',
left: 0,
bottom: 0,
border: '1em solid crimson',
overflowY: 'auto',
fontFamily: 'monospace',
})
.appendTo($('body'))
const createEventHandler = name => {
return event => {
debug(name)
if (name in handlers) {
handlers[name](name, event)
}
}
}
Object.keys(window).forEach(key => {
if (/^on/.test(key)) {
const name = key.slice(2)
if (bypass.includes(name)) {
return
}
$(window).on(name, createEventHandler(name))
$('#debugConsole').on(name, event => {
event.stopImmediatePropagation()
})
}
});
['focusin', 'focusout', 'focus', 'blur'].forEach(name => {
$('#input').on(name, createEventHandler(name))
})
}
// Change these values according to your needs. These events are bypassed by
// default because they generate a LOT of output.
const bypass = [
'devicemotion',
'deviceorientation',
'deviceorientationabsolute',
'gotpointercapture',
'load',
'lostpointercapture',
'mousemove',
'mouseout',
'mouseover',
'mousewheel',
'pageshow',
'pointerrawupdate',
'wheel',
]
const handlers = {
keydown: (name, event) => {
debug(`>>> ${event.code}`)
debug(`>>> ${event.keyCode}`)
},
input: (name, event) => {
debug(`>>> ${$('#input').val()}`)
}
}
initialize(handlers, bypass)
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment