Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

208
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda