【问题标题】:React : Setting scrollTop on Div doesn't work in a specific case反应:在 Div 上设置 scrollTop 在特定情况下不起作用
【发布时间】:2018-11-12 18:05:36
【问题描述】:

从今天早上开始,我一直被困在这个问题上,我仍然无法弄清楚我哪里出错了。我想突出显示 textarea 输入类型中的文本。我知道这是不可能的,但我找到了一个聪明的解决方案来欺骗观众让他们这么想。 Here 是文章的链接,Here 是项目的 codeio pen 的链接。

我一直在尝试使用 react 和普通 javascript 重新创建相同的内容,但是带有 className highlight 的 div 的 scrollTop 属性不起作用。如果有人可以帮助我调试我做错了什么,那就太好了!

class CodeTextArea extends React.Component {
  constructor(props){
    super(props);
    this.state = {scrollTop: 0, 
                  scrollLeft: 0
                 };
    this.setScroll = this.setScroll.bind(this);
  }
  setScroll(top,left){
    this.setState({scrollTop: top, scrollLeft: left});
  }
  render(){
    return(
      <div class="container">
  <div class="backdrop">
    <Highlight scrollTop={this.state.scrollTop} scrollLeft={this.state.scrollLeft}/>
  </div>
  <Textarea setScrollTop={this.setScroll}/>
</div>
    );
  }
}
class Highlight extends React.Component {
    constructor(props){
    super(props);
    this.divRef = React.createRef();
  }
  componentDidUpdate(prevProps){
    if (this.props.scrollTop !== prevProps.scrollTop) {
      /*console.log(this.divRef.current);
      console.log(this.props.scrollTop);
      console.log(this.props.scrollLeft);*/
      this.divRef.current.scrollTop = this.props.scrollTop;
    }

  }
  render(){       
    return (
      <div class="highlights" ref={this.divRef}><mark>This</mark> demo shows how to highlight bits of text within a <mark>textarea</mark>. Alright, that's a lie. You can't actually render markup inside a textarea. However, you can fake it by carefully positioning a div behind the textarea and adding your highlight markup there. JavaScript takes care of syncing the content and scroll position from the textarea to the div, so everything lines up nicely. Hit the toggle button to peek behind the curtain. And feel free to edit this text. All capitalized words will be highlighted.
      </div>
    );
  }
}
class TogglePerspective extends React.Component {
  constructor(props){
    super(props);
    this.clickHandler = this.clickHandler.bind(this);
    this.buttonRef = React.createRef();
  }
  clickHandler(){

  }
  render(){
    return (
      <button onClick={this.clickHandler} ref={this.buttonRef}>Toggle Perspective</button>
    );
  }
}
class Textarea extends React.Component {
  constructor(props){
    super(props);
    this.handleScroll = this.handleScroll.bind(this);
    this.handleChange = this.handleChange.bind(this);
    this.applyHighlights = this.applyHighlights.bind(this);
    this.textareaRef = React.createRef();
    this.state = {value: 'This demo shows how to highlight bits of text within a textarea. Alright, that\'s a lie. You can\'t actually render markup inside a textarea. However, you can fake it by carefully positioning a div behind the textarea and adding your highlight markup there. JavaScript takes care of syncing the content and scroll position from the textarea to the div, so everything lines up nicely. Hit the toggle button to peek behind the curtain. And feel free to edit this text. All capitalized words will be highlighted.'};
  }

  applyHighlights(text){
    return text
        .replace(/\n$/g, '\n\n')
        .replace(/[A-Z].*?\b/g, '<mark>$&</mark>');
  }

  handleScroll(){
    let scrollTop = this.textareaRef.current.scrollTop;
    let scrollLeft = this.textareaRef.current.scrollLeft;
    this.props.setScrollTop(scrollTop,scrollLeft);
  }

  handleChange(event){
    let textareaValue = event.targrt.value;
    this.setState({value: textareaValue});
    let highlightedText = this.applyHighlights(textareaValue);
  }

  render(){
    return (
      <textarea ref={this.textareaRef} value={this.state.value} onChange={this.handleChange} onScroll={this.handleScroll}></textarea>
    );
  }
}
class Editor extends React.Component {
  render(){
    return (
     <div>
    <CodeTextArea />
<TogglePerspective />
</div>
    );
  }
}

ReactDOM.render(
 <Editor />,
 document.getElementById('root')
);

Here 是我娱乐的 codeIo 笔。请告诉我为什么 突出显示类 div scrollTop 属性不起作用。 除非我真的很沮丧,否则我通常不会在这里发布长代码,因此非常感谢任何帮助。

【问题讨论】:

    标签: javascript jquery html css reactjs


    【解决方案1】:

    看起来scrollTop 属性设置在div.highlights 上,而它应该设置在div.backdrop 上。

    div.backdrop 移动到 Highlight 组件中并将 ref 放在该元素上:

    <div class="backdrop" ref={this.divRef}>
    <div class="highlights">
        <mark>This</mark> demo shows how to highlight bits of text within a <mark>textarea</mark>.
        Alright, that's a lie. You can't actually render markup inside a textarea. However, you can 
        fake it by carefully positioning a div behind the textarea and adding your highlight markup there. 
        JavaScript takes care of syncing the content and scroll position from the textarea to the div, so everything lines up nicely. 
        Hit the toggle button to peek behind the curtain. And feel free to edit this text. All capitalized words will be highlighted.
    </div>
    

    【讨论】:

    • 我不知道你是谁,但我会找到你,我会拥抱你:) 伙计,犯这样一个愚蠢的错误感觉真尴尬。并且被困在这上面一整天!!!!!!!你为我解决了一个大问题!非常感谢!!!!!!!!!!!!!!!!!!
    猜你喜欢
    • 2019-04-15
    • 1970-01-01
    • 2018-02-27
    • 2013-09-26
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多