2017-11-20 15 views
2

をしてくださいリアクト私は問題問題で状態を更新し、

がここにフィドル私のjsだ示されてきた私のjsフィドル表示: https://jsfiddle.net/jajabya/fb93f7b0/

マイゴードは、特別な言葉(のようなinputタグを取得することですが日付またはユーザーの名前をspanタグで囲むことでハイライト表示できます)

divに問題がなければなりません。代わりに入力フィールドを使用すると問題なく動作します。

私の問題は、私はonInput

onInput(event) { 
    this.setState({ 
     html: event.target.innerText.toUpperCase() 
    }); 

    } 

の状態更新はキャレットが先頭にロールバックしたときにキャレットが正しい場所 にすべての時間を表示させることができないということです私の考えがある

+0

簡単な質問ですが、なぜdiv要素でこれをやりたいのですか? –

+0

なぜ 'input'タグの代わりに' div'を使うのですか? –

+0

'input'タグでは他のhtmlタグを使用できないためです。特別な単語を 'span'タグで' class'属性でラップするようにします。 –

答えて

4

現在のキャレットの位置を状態に保存し、refでcomponentDidUpdate()を返します(refはコンポーネントを再レンダリングしないため)。

注:これはプロトタイプのアイデアであり、決して戦闘テストを行ったことがないので、慎重に使用してください。

キャレット位置コードは、この答えから取った:

  1. Code for getting the caret position

  2. Code for setting caret position

class Editable extends React.Component { 
 
    componentDidUpdate(prev) { 
 
    const { position } = this.props; 
 
    
 
    if(position !== prev.position && this.ce.childNodes.length) { 
 
     const range = document.createRange(); 
 
     const sel = window.getSelection(); 
 
     range.setStart(this.ce.childNodes[0], position); 
 
     range.collapse(true); 
 
     sel.removeAllRanges(); 
 
     sel.addRange(range); 
 
    } 
 
    } 
 
    
 
    render() { 
 
    return (
 
     <div 
 
     contentEditable 
 
     className={this.props.className} 
 
     onInput={this.props.onInput} 
 
     ref={ce => this.ce = ce} 
 
     suppressContentEditableWarning> 
 
     {this.props.html} 
 
     </div> 
 
    ); 
 
    } 
 
} 
 

 
class App extends React.Component { 
 
    state = { 
 
    html: 'Text', 
 
    caret: 0 
 
    }; 
 

 
    handleInput = (event) => this.setState({ 
 
    html: event.target.innerText.toUpperCase(), 
 
    position: window.getSelection().getRangeAt(0).startOffset 
 
    }); 
 
    
 
    render() { 
 
    return (
 
    <Editable 
 
     {...this.state} 
 
     className="Editable" 
 
     onInput={this.handleInput} /> 
 
    ); 
 
    } 
 
} 
 

 
ReactDOM.render(
 
    <App />, 
 
    demo 
 
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
 

 
<div id="demo"></div>

関連する問題