Zac*_*iro 29 html javascript css reactjs
我有ul一个max-height和overflow-y: auto.
当用户输入足够的li元素,将ul开始滚动,但我想最后li与form中它始终存在并显示给用户.
我试过实现一个如下所示的scrollToBottom函数:
scrollToBottom() {
this.formLi.scrollIntoView({ behavior: 'smooth' });
}
Run Code Online (Sandbox Code Playgroud)
但这只是ul跳转到屏幕顶部并显示li其中的表单作为唯一可见的东西.
有没有更好的方法来实现这一目标?我发现的答案往往有点旧并使用ReactDOM.谢谢!
CSS:
.prompt-box .options-holder {
list-style: none;
padding: 0;
width: 95%;
margin: 12px auto;
max-height: 600px;
overflow-y: auto;
}
Run Code Online (Sandbox Code Playgroud)
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>
Run Code Online (Sandbox Code Playgroud)
Jon*_*lez 21
我有一个填充页面高度的容器。此容器具有显示 flex 和 flex 方向列。然后我有一个Messages组件,它是ul 一个li每条消息加上一个特殊AlwaysScrollToBottom组件作为最后一个子组件,它在 的帮助下useEffect滚动到列表的底部。
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>
)
Run Code Online (Sandbox Code Playgroud)
CSS是
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>
)
Run Code Online (Sandbox Code Playgroud)
MessageComposer 为简洁起见已省略,它包含用于发送消息的表单、输入字段等。
使用反应滚动库.但是,您必须明确设置您的ID ul.
import { animateScroll } from "react-scroll";
scrollToBottom() {
animateScroll.scrollToBottom({
containerId: "options-holder"
});
}
Run Code Online (Sandbox Code Playgroud)
您可以调用scrollToBottomsetState回调.
例如
this.setState({ items: newItems}, this.scrollToBottom);
Run Code Online (Sandbox Code Playgroud)
或者使用setTimeout.
或者,你甚至可以设置Element从react-scroll和滚动到一定的li.
似乎您正在构建一个类似聊天的界面。您可以尝试将<ul>和包装div.circle-form在一个单独的 div 中,如下所示:
ul{
border:1px solid red;
height:13em;
overflow-y:auto;
position:relative;
}
ul li{
border-bottom:1px solid #ddd;
list-style:none;
margin-left:0;
padding:6px;
}
.wrapper{
background:#eee;
height:15em;
position:relative;
}
.circle-form{
background:#ddd;
height:2em;
padding:3px;
position:absolute;
bottom:0;
left:0;
right:0;
z-index:2;
}
.circle-form input[type=text]{
padding:8px;
width:50%;
}Run Code Online (Sandbox Code Playgroud)
<div class="wrapper">
<ul id="list">
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
</ul>
<div class="circle-form">
<input type="text" name="type_here" placeholder="Enter something..." autofocus/>
</div>
</div>Run Code Online (Sandbox Code Playgroud)
编辑
并使用 javascript 滚动到列表底部
var list = document.getElementById("list");
list.scrollTop = list.offsetHeight;
Run Code Online (Sandbox Code Playgroud)
小智 6
在渲染来自用户导入的组件数组时,我遇到了类似的问题。我最终使用 componentDidUpdate() 函数来让我的工作。
componentDidUpdate() {
// I was not using an li but may work to keep your div scrolled to the bottom as li's are getting pushed to the div
const objDiv = document.getElementById('div');
objDiv.scrollTop = objDiv.scrollHeight;
}
Run Code Online (Sandbox Code Playgroud)
我有一个脚本,我在我的一个项目中使用它来平滑地滚动顶部,我做了一些重构来滚动 div 的高度(滚动底部)我希望它有所帮助。
滚动.js
function currentYPosition() {
if (self.pageYOffset) return self.pageYOffset;
if (document.documentElement && document.documentElement.scrollHeight) return document.documentElement.scrollHeight;
if (document.body.scrollHeight) return document.body.scrollHeight;
return 0;
}
function elmYPosition(eID) {
let elm = document.getElementById(eID);
let y = elm.offsetHeight;
let node = elm;
while (node.offsetParent && node.offsetParent != document.body) {
node = node.offsetParent;
y += node.offsetHeight;
}
return y;
}
export default function smoothScroll(eID, string) {
let startY = currentYPosition();
let stopY = elmYPosition(eID);
let distance = stopY > startY ? stopY - startY : startY - stopY;
let speed = Math.round(distance / 10);
let speedTimeout = 250;
if (speed >= 100) speed = 100;
if (string) speed = 1;
let step = Math.round(distance / 25);
let leapY = stopY > startY ? startY + step : startY - step;
let timer = 0;
if (stopY > startY) {
for (let i = startY; i < stopY; i += step) {
setTimeout('window.scrollTo(0, ' + leapY + ')', timer * speed);
leapY += step;
if (leapY > stopY) leapY = stopY;
timer++;
}
return;
}
for (let i = startY; i > stopY; i -= step) {
setTimeout('window.scrollTo(0, ' + (leapY) + ')', timer * speed);
leapY -= step;
if (leapY < stopY){
leapY = stopY;
}
timer++;
}
}
Run Code Online (Sandbox Code Playgroud)
你应该将其导入到你的组件中,有两个参数(你的元素的ID,在这种情况下,你可以使用ref。第二个是我用来处理滚动速度的字符串。
import scroll from './your-path/scroll.js';
.
.
.
<ul className='options-holder'>
{
this.state.items.map((item, index) => (
<li key={item.id} className={`option ${index === 0 ? 'first' : ''}`} ref={el => (this.formLi = el)}>
<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>
Run Code Online (Sandbox Code Playgroud)
我不知道如何在渲染中映射此 LI,但您应该进行验证,如果存在属性“溢出”,您应该运行滚动。
对于您的组件来说,一个合理的答案是跳转到第一个元素,您将点击第一个元素的引用,而不是最后一个元素。
可能的解决方法:
scroll(this.state.items[this.state.items.length - 1]);
Run Code Online (Sandbox Code Playgroud)
更新1:原始scroll.js的要点,滚动到顶部
| 归档时间: |
|
| 查看次数: |
9691 次 |
| 最近记录: |