Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
283 views
in Technique[技术] by (71.8m points)

javascript - Scroll to bottom of an overflowing div in React

I have a ul with a max-height and overflow-y: auto.

When the user enters enough li elements, the ul starts to scroll, but I want the last li with the form in it to always be present and viewable to the user.

I've tried implementing a scrollToBottom function that looks like this:

scrollToBottom() {
    this.formLi.scrollIntoView({ behavior: 'smooth' });
}

But that just makes the ul jump to the top of the screen and show the li with the form in it as the only visible thing.

Is there a better way to accomplish this? Answers I find tend to be a bit older and use ReactDOM. Thanks!

CSS:

.prompt-box .options-holder {
    list-style: none;
    padding: 0;
    width: 95%;
    margin: 12px auto;
    max-height: 600px;
    overflow-y: auto;
}

HTML:

<ul className='options-holder'>
    {
        this.state.items.map((item, index) => (
            <li key={item.id} className={`option ${index === 0 ? 'first' : ''}`}>
                <div className='circle' onClick={this.removeItem} />

                <p className='item-text'>{ item.text }</p>
            </li>
        ))
    }

    <li key={0} className={`option form ${this.state.items.length === 0 ? 'only' : ''}`} ref={el => (this.formLi = el)}>
        <div className='circle form' />

        <form className='new-item-form' onSubmit={this.handleSubmit}>
            <input 
                autoFocus 
                className='new-item-input' 
                placeholder='Type something and press return...' 
                onChange={this.handleChange} 
                value={this.state.text}
                ref={(input) => (this.formInput = input)} />
        </form>
    </li> 
</ul>
question from:https://stackoverflow.com/questions/45719909/scroll-to-bottom-of-an-overflowing-div-in-react

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I have a container that fills the height of the page. This container has display flex and flex direction column. Then I have a Messages component which is a ul with one li per message plus a special AlwaysScrollToBottom component as the last child that, with the help of useEffect, scrolls to the bottom of the list.

const AlwaysScrollToBottom = () => {
  const elementRef = useRef();
  useEffect(() => elementRef.current.scrollIntoView());
  return <div ref={elementRef} />;

};

const Messages = ({ items }) => (
  <ul>
    {items.map(({id, text}) => <li key={id}>{text}</li>)}
    <AlwaysScrollToBottom />
  </ul>
)

const App = () => (
  <div className="container">
    <Messages items={[...]}>
    <MessageComposer />
  </div>
)

The CSS is

.container {
  display: flex;
  height: 100vh;
  flex-direction: column;
}

ul {
  flex-grow: 1;
  overflow-y: auto;
}

MessageComposer has been omitted for brevity, it contains the form, the input field, etc. to send messages.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...