简体   繁体   中英

How do I prevent Element.focus() change cursor position in contenteditable div?

I do not wish to move the cursor, anywhere but when I call the function focus, it moves the cursor to the beginning. I wish to keep the cursor where it is. I am doing this in ReactJS using Typescript.

const element = document.getElementById('editable-div');
element.focus();   // sets cursor to beginning here
// rest of my code is here

I want to call focus because I need to append stuff in the contenteditable div and in some cases insert stuff. But as soon as I do focus() , it moves the cursor at the wrong place. How do I fix this?

With the help of document.createRange and Window.getSelection it is possible

 const { useState, useEffect, useRef } = React; const random = (from, to) => Math.floor(Math.random() * (to - from) + from); const randomText = () => Array(random(5, 10)).fill(0).map((pr, index) => String.fromCharCode(index + 50)).join('') const setCaretToTheEnd = (element) => { const position = element.textContent.length; const [childNode] = element.childNodes; const range = document.createRange(); const selection = window.getSelection(); range.setStart(childNode, position); range.setEnd(childNode, position); range.collapse(true); selection.removeAllRanges(); selection.addRange(range); } const App = () => { const [text, setText] = useState(''); const inputRef = useRef(null); useEffect(() => { if(inputRef && inputRef.current && text) { const element = inputRef.current; setCaretToTheEnd(element); element.focus(); } }, [text]); useEffect(() => { let isUnmounted = false; let handle = null; const changeText = () => { setText(randomText()); handle = setTimeout(changeText, 4000); } handle = setTimeout(changeText, 500); return () => { isUnmounted = true; clearTimeout(handle); } }, []) const onChange = ({target: {value}}) => setText(value); return <div> <div ref={inputRef} suppressContentEditableWarning={true} className="contentEditable" onChange={onChange} contentEditable>{text}</div> </div> } ReactDOM.render( <App />, document.getElementById('root') );
 .contentEditable { padding: 1rem; border: 1px solid black; }
 <script src="https://unpkg.com/react/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom/umd/react-dom.development.js"></script> <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script> <script src="https://unpkg.com/@material-ui/core@latest/umd/material-ui.development.js"></script> <div id="root"></div> <script src="https://unpkg.com/material-ui-lab-umd@4.0.0-alpha.32/material-ui-lab.development.js"></script> <div id="root"></div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM