<html>
<head>
<style>
#test-hover {
position: absolute;
left: 20px;
top: 40px;
width: 100px;
height: 30px;
background-color: red;
}
#test-hover:hover {
background-color: blue;
}
#test-button {
position: absolute;
left: 20px;
top: 100px;
width: 100px;
height: 30px;
}
#scrollable {
position: absolute;
left: 200px;
top: 30px;
width: 200px;
height: 200px;
overflow: scroll;
}
#scrolled {
width: 800px;
height: 800px;
}
</style>
</head>
<body>
<div id="test-hover">Hover me</div>
<button id="test-button">Click me</button>
<div id="scrollable"><div id="scrolled"></div></div>
<script>
var pendingListeners = {};
var pendingEvents = {};
var inflightEvents = null;
function onEvent(event)
{
if (inflightEvents) {
inflightEvents.push(event);
return;
}
inflightEvents = [event];
if (event.type === "mousemove")
document.body.style.backgroundColor = "#" + Math.floor(Math.random() * (1 << 24)).toString(16);
requestAnimationFrame(onEventAfterFrame);
}
function onEventAfterFrame()
{
for (event of inflightEvents) {
var type = event.type;
var listener = pendingListeners[type];
if (!listener) {
pendingEvents[type] = (pendingEvents[type] || 0) + 1;
continue;
}
delete pendingListeners[type];
listener();
}
inflightEvents = null;
}
function waitForEvent(eventType, callback)
{
if (pendingEvents[eventType]) {
pendingEvents[eventType]--;
callback();
return;
}
pendingListeners[eventType] = callback;
}
var eventTypes = [
"mousemove",
"mousedown",
"mouseup",
"wheel",
"gesturetap",
"click",
"keydown",
"keyup",
"touchstart",
"touchend",
"touchcancel",
"touchmove"
];
for (var e of eventTypes) {
window.addEventListener(e, onEvent, true);
}
</script>
</body>
</html>