JSFiddle - React, Tailwind, and code Playground

by joplomacedo

HTML

<input type="text">

<p contenteditable>edit</p>

JavaScript

const onDoubleKeydown = (function () {
	//methods

	const isFocusInInputOrContenteditable = ( () => {
		const fieldElTypes = ['INPUT', 'SELECT', 'TEXTAREA'];
	
		return () => {
			const activeEl = document.activeElement;
			const focusedElType = activeEl.tagName;

			if ( fieldElTypes.includes(focusedElType) ) {
				return true;
			}

			let contenteditableValue = activeEl.getAttribute('contenteditable');

			if ( contenteditableValue === '' || contenteditableValue === 'true' ) {
				return true;
			}

			return false;
		};

	})();

	//constants
	const timeoutDuration = 300;

	//state
	const cbs = [];
	let lastPressedKey;
	let timeout;
	
	//evt attachments
	window.addEventListener('keydown', function ( e ) {
		if ( isFocusInInputOrContenteditable() ) {
			return;
		}

		const pressedKey = e.code;
		const cb = cbs[pressedKey];

		if ( !cb ) {
			lastPressedKey = null;
			clearTimeout(timeout);
			return;
		}

		if ( pressedKey === lastPressedKey ) {
			cb();
			lastPressedKey = null;

		} else {
			lastPressedKey = pressedKey;

			timeout = setTimeout( _ => {
				lastPressedKey = null;
			}, timeoutDuration);
		}
	});


	//returned
	return function ( key, cb ) {
		cbs[key] = cb;

		//returns ubsubscribe fuc
		return function () {
			delete cbs[key];
		}
	};
})();

x = onDoubleKeydown('KeyT', function () {
alert('double t');
})

x = onDoubleKeydown('KeyW', function () {
alert('double w');
})