Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

206
Views
element.focus () no funciona en el elemento div editable contenido vuelto a renderizar

Editar pequeña-plataforma-3291w

 import React, { useEffect, useState } from "react"; import "./styles.css"; const RichText = () => { const [value, setValue] = useState(""); useEffect(() => { const div = document.getElementById("textarea"); if (div) { setTimeout(() => { div.focus(); }, 0); } }); return ( <div className="rich-text" onInput={(e) => { setValue(e.target.innerText); }} contentEditable id="textarea" dangerouslySetInnerHTML={{ __html: value }} /> ); }; export default RichText;

Quiero implementar un componente de texto enriquecido, la idea es que puede escribir texto dentro de algún campo, puede diseñar este texto (ponerlo en negrita, cursiva, subrayado, etc.). Quiero el mismo valor de texto dentro de la variable de estado de value , y luego envolverlo de alguna manera dentro de las etiquetas html <p>Hello <b> Andrew</b></p> , y mostrarlo en tiempo real dentro del mismo campo, con estilo . Para mostrar etiquetas html dentro de div , campo contentEditable , necesito usar dangerouslySetInnerHTML SetInnerHTML, y este es el problema principal. Que en cada botón presionado, actualizo el valor, el componente luego se vuelve a representar, el foco va al comienzo del campo, pero quiero que esté al final en el momento en que escribe el texto nuevo. Intenté hacerlo con ref => ref.current.focus() , no funciona, en el código anterior puedes ver que también intento hacerlo con vanilla js usando timeout , tampoco funciona work, autoFocus : solo se puede usar en input, textarea, etc , div se puede usar con esta propiedad. Lo guardé en ref , pero luego no puedo mostrar html envuelto dentro de div . Intenté muchos casos, pero es parecido. ¿Alguna idea de cómo hacerlo?

about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

El problema es cuando se usa el gancho useState con contentEditable y dangerouslySetInnerHTML SetInnerHTML para sincronizar el valor. Cuando escribe algo en el div, se vuelve a representar y devuelve el cursor al inicio.

Puede usar variables de instancia en el componente de la función ( useRef para actualizar el valor) para deshacerse del problema.

Y debe usar innerHTML en lugar de innerText para guardar la cadena HTML

Prueba como a continuación

 import React, { useRef } from "react"; import "./styles.css"; const RichText = () => { const editableRef = useRef(null); const { current: value } = useRef( '<div style="color:green">my initial content</div>' ); const setValue = (e) => { value.current = e.target.innerHTML; }; const keepFocus = () => { const { current } = editableRef; if (current) { current.focus(); } }; return ( <div className="rich-text" onInput={setValue} contentEditable id="textarea" ref={editableRef} onBlur={keepFocus} dangerouslySetInnerHTML={{ __html: value }} /> ); }; export default RichText;

Zona de pruebas de código

about 4 years ago · Juan Pablo Isaza Report

0

import React from "react"; import "./styles.css"; class TextInput extends React.Component { constructor(props) { super(); this.state = { value: "" }; } shouldComponentUpdate() { return true; } componentDidUpdate() { const el = document.getElementById("textarea"); if (el) { console.log(el.selectionStart, el.selectionEnd); var range, selection; if (document.createRange) { //Firefox, Chrome, Opera, Safari, IE 9+ range = document.createRange(); //Create a range (a range is a like the selection but invisible) range.selectNodeContents(el); //Select the entire contents of the element with the range range.collapse(false); //collapse the range to the end point. false means collapse to end rather than the start selection = window.getSelection(); //get the selection object (allows you to change selection) selection.removeAllRanges(); //remove any selections already made selection.addRange(range); //make the range you have just created the visible selection } else if (document.selection) { //IE 8 and lower range = document.body.createTextRange(); //Create a range (a range is a like the selection but invisible) range.moveToElementText(el); //Select the entire contents of the element with the range range.collapse(false); //collapse the range to the end point. false means collapse to end rather than the start range.select(); //Select the range (make it the visible selection } } } update(value) { this.setState({ value }); } render() { console.log(this.state.value); return ( <div className="rich-text" onInput={(e) => { this.update(e.target.innerText); }} contentEditable id="textarea" dangerouslySetInnerHTML={{ __html: `<b>${this.state.value}</b>` }} /> ); } } export default TextInput;
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!