Skip to content

Instantly share code, notes, and snippets.

@jh3y
Last active November 29, 2022 07:16
Show Gist options
  • Save jh3y/eaa2b133eb7250b06c52b681e70a8c0e to your computer and use it in GitHub Desktop.
Save jh3y/eaa2b133eb7250b06c52b681e70a8c0e to your computer and use it in GitHub Desktop.
show text cursor position marker
/**
* 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