Last active
November 29, 2022 07:16
-
-
Save jh3y/eaa2b133eb7250b06c52b681e70a8c0e to your computer and use it in GitHub Desktop.
show text cursor position marker
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
/** | |
* shows a position marker that highlights where the cursor is | |
* @param {object} e - the input or click event that has been fired | |
*/ | |
const showPositionMarker = e => { | |
// grab the input element | |
const { currentTarget: input } = e | |
// create a function that will handle clicking off of the input and hide the marker | |
const processClick = evt => { | |
if (e !== evt && evt.target !== e.target) { | |
toggleMarker() | |
} | |
} | |
// create a function that will toggle the showing of the marker | |
const toggleMarker = () => { | |
input.__IS_SHOWING_MARKER = !input.__IS_SHOWING_MARKER | |
if (input.__IS_SHOWING_MARKER && !input.__MARKER) { | |
// assign a created marker to input | |
input.__MARKER = createMarker('Here I am! 😜', 'position') | |
// append it to the body | |
document.body.appendChild(input.__MARKER) | |
document.addEventListener('click', processClick) | |
} else { | |
document.body.removeChild(input.__MARKER) | |
document.removeEventListener('click', processClick) | |
input.__MARKER = null | |
} | |
} | |
// if the marker isn't showing, show it | |
if (!input.__IS_SHOWING_MARKER) toggleMarker() | |
// if the marker is showing, update its position | |
if (input.__IS_SHOWING_MARKER) { | |
// grab the properties from the input that we are interested in | |
const { | |
offsetLeft, | |
offsetTop, | |
offsetHeight, | |
offsetWidth, | |
scrollLeft, | |
scrollTop, | |
selectionEnd, | |
} = input | |
// get style property values that we are interested in | |
const { lineHeight, paddingRight } = getComputedStyle(input) | |
// get the cursor X and Y from our helper function | |
const { x, y } = getCursorXY(input, selectionEnd) | |
// set the marker positioning | |
// for the left positioning we ensure that the maximum left position is the width of the input minus the right padding using Math.min | |
// we also account for current scroll position of the input | |
const newLeft = Math.min( | |
x - scrollLeft, | |
(offsetLeft + offsetWidth) - parseInt(paddingRight, 10) | |
) | |
// for the top positioning we ensure that the maximum top position is the height of the input minus line height | |
// we also account for current scroll position of the input | |
const newTop = Math.min( | |
y - scrollTop, | |
(offsetTop + offsetHeight) - parseInt(lineHeight, 10) | |
) | |
input.__MARKER.setAttribute('style', `left: ${newLeft}px; top: ${newTop}px`) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment