2017-11-13 99 views
5

başlangıcına atlar Boş çalışma sayfasındaki bir dolguyu düzenlemeyi etkinleştirmek için react-simple-contenteditable modülünü kullanıyorum. Girdi öğesi yerine içerikte düzenlenebilir bir öğe kullanmamın nedeni, sorunun metninin sarılmasını istiyorum. Örneğin, bir sorun bir boşluk içeriyorsa, metni boş bırakılan bölümden, boşluktan ve bölümden önceki bölümü üç bölüme ayırır. Eğer dış ikisini ayrı div s (veya giriş alanları) olarak temsil etseydim, metin bir paragraf gibi sarılmazdı. Bunun yerine, her iki taraftaki boş ve boş metinler için bir giriş alanı içeren tek bir tartışmalı div olmalıdır.Dikkat edilemez imleç,

Metin, istediğim gibi sarılıyor, ancak içeriğe yazılabilir alanda metin yazdığımda, imleç en başa kadar atlar. Neden anlamıyorum, çünkü module's github site örneğini denedim ve mükemmel çalışıyor ve uygulamaum biraz daha karmaşık olsa da, aslında aynı şekilde çalışıyor.

: Sadece net bir şey yapmak için,

handleProblemChange(event, problemIdx) { 
    const problems = cloneDeep(this.state.problems); 
    event.target.children[0].childNodes.forEach((textPieceNode, idx) => { 
     if (textPieceNode.constructor === Text) { 
     problems[problemIdx].textPieces[idx].text = textPieceNode.wholeText; 
     } else { 
     problems[problemIdx].textPieces[idx].text = textPieceNode.childNodes[0].value; 
     } 
    }); 
    this.setState({ problems }); 
    } 

Ve işte atıfta durumdur:

İşte
render() { 
    const textPieces = 
     <div className='new-form-text-pieces'> 
     { 
      this.props.problem.textPieces.map((textPiece, idx) => { 
      if (textPiece.blank) { 
       return (
        <div data-blank={true} className='blank' key={ textPiece.id } style={{display: 'inline'}}> 
        <input 
         placeholder="Answer blank" 
         className='new-form-answer-input' 
         value={ this.props.problem.textPieces[idx].text } 
         onChange={ (event) => this.props.handleTextPiecesInput(this.props.problemIdx, idx, event.target.value) } 
        /> 
        <button className='modify-blank remove-blank' onClick={ (event) => this.props.removeBlank(this.props.problemIdx, idx) }>-</button> 

        </div> 
      ); 
      } else { 
       let text = this.props.problem.textPieces[idx].text; 
       const placeholder = idx === 0 ? 'Problem text' : '...continue text'; 
       // text = text === '' ? placeholder : text; 
       if (text === '') { 
       text = <span style={{color:'gray'}}>{placeholder}</span>; 
       } else { 

       } 
       return (
       this.props.isTextSplit ? 
        <TextPiece 
        key={ textPiece.id } 
        problemIdx={this.props.problemIdx} 
        textPieceIdx={idx} 
        dropBlank={this.props.dropBlank} 
        moveBlank={this.props.moveBlank} 
        > 
        <div style={{display: 'inline-block', }}>{text}</div> 
        </TextPiece> 
       : text 

      ); 
      } 
      }) 
     } 
     </div>; 



    return (
     this.props.isTextSplit ? textPieces : 
     <ContentEditable 
      html={ReactDOMServer.renderToStaticMarkup(textPieces)} 
      className="my-class" 
      tagName="div" 
      onChange={ (event, value) => this.props.handleProblemChange(event, this.props.problemIdx, value) } 
      contentEditable='plaintext-only' 
     /> 
    ); 

    } 

onChange fonksiyonudur: Burada

<ContentEditable /> kullanan benim hale işlevidir
this.state = { 
    problems: [ 
    { 
     id: shortid.generate(), 
     textPieces: [ 
     { 
      text : "Three days was simply not a(n)", 
      blank : false, 
      id: shortid.generate(), 
     }, 
     { 
      text : "acceptable", 
      blank : true, 
      id: shortid.generate(), 
     }, 
     { 
      text : "amount of time to complete such a lot of work.", 
      blank : false, 
      id: shortid.generate(), 
     } 
     ] 
    } 

Çok teşekkürler

cevap

1

Uzun lafın kısası, bunu yapmanın kolay bir yolu yok. Bunu kendim denedim ve günlerce denemeye çalıştım. Temel olarak, imleç konumunu kaydetmeli ve güncellemeden sonra yeniden konumlandırmalısınız. Tüm bu window.getSelection ile elde edilebilir()

https://developer.mozilla.org/en-US/docs/Web/API/Window/getSelection

Ama içerik ne kadar değiştiğini bağlı gerçekten zor alabilirsiniz.

Bunun yerine draftJS kullanarak bitti. Hangi facebook tarafından contenteditable div üzerinden bir soyutlama.

https://draftjs.org/docs/overview.html#content

A almaya artık bit ama Cevabınız için çok daha fazla

+0

Teşekkür yapmak mümkün olacak! DraftJS'ye yeni bir bakacağım, oldukça karmaşık görünüyordu. Yaptığım şey gibi sadece basit alanlar için uygulanabilir mi, yoksa sadece reklamı yapılan gibi zengin metin düzenlemeleri mi? –

+0

Her ikisini de yapabilir. Basit olmamakla birlikte, imleç durumunu kendiniz yönetmekten daha basit olduğundan bahse girerim. – klugjo

+0

Buraya geri geliyorum ... DraftJS'in dokümanlarını taradım ve başka bir sorunun cevabını bulamıyorum, o zaman belki biliyorsunuzdur: iç içerik html öğelerini yapabilir miyim? İçeriği düzenlenebilir metne ek olarak, etrafına bir kutu içeren bir metne ihtiyacım var. –