问题描述
我有一个弹出列表,它是一个 div
,其中包含子 div
的垂直列表.我添加了向上/向下键盘导航以更改当前突出显示的子项.
I have a popup list which is a div
that contains a vertical list of child div
s. I have added up/down keyboard navigation to change which child is currently highlighted.
现在,如果我按下向下键足够多的次数,突出显示的项目将不再可见.如果滚动视图,向上键也会发生同样的事情.
Right now, if I press the down key enough times, the highlighted item is no longer visible. The same thing also occurs with the up key if the view is scrolled.
React 中自动将子 div
滚动到视图中的正确方法是什么?
What is the right way in React to automatically scroll a child div
into view?
推荐答案
我假设您有某种 List
组件和某种 Item
组件.我在在一个项目中的做法是让项目知道它是否是活跃与否;如有必要,该项目会要求列表将其滚动到视图中.考虑以下伪代码:
I assume that you have some sort of List
component and some sort of Item
component. The way I did it in one project was to let the item know if it was active or not; the item would ask the list to scroll it into view if necessary. Consider the following pseudocode:
class List extends React.Component {
render() {
return <div>{this.props.items.map(this.renderItem)}</div>;
}
renderItem(item) {
return <Item key={item.id} item={item}
active={item.id === this.props.activeId}
scrollIntoView={this.scrollElementIntoViewIfNeeded} />
}
scrollElementIntoViewIfNeeded(domNode) {
var containerDomNode = React.findDOMNode(this);
// Determine if `domNode` fully fits inside `containerDomNode`.
// If not, set the container's scrollTop appropriately.
}
}
class Item extends React.Component {
render() {
return <div>something...</div>;
}
componentDidMount() {
this.ensureVisible();
}
componentDidUpdate() {
this.ensureVisible();
}
ensureVisible() {
if (this.props.active) {
this.props.scrollIntoView(React.findDOMNode(this));
}
}
}
更好的解决方案可能是让列表负责将项目滚动到视图中(项目不知道它甚至在列表中).为此,您可以将 ref
属性添加到某个项目并通过该属性找到它:
A better solution is probably to make the list responsible for scrolling the item into view (without the item being aware that it's even in a list). To do so, you could add a ref
attribute to a certain item and find it with that:
class List extends React.Component {
render() {
return <div>{this.props.items.map(this.renderItem)}</div>;
}
renderItem(item) {
var active = item.id === this.props.activeId;
var props = {
key: item.id,
item: item,
active: active
};
if (active) {
props.ref = "activeItem";
}
return <Item {...props} />
}
componentDidUpdate(prevProps) {
// only scroll into view if the active item changed last render
if (this.props.activeId !== prevProps.activeId) {
this.ensureActiveItemVisible();
}
}
ensureActiveItemVisible() {
var itemComponent = this.refs.activeItem;
if (itemComponent) {
var domNode = React.findDOMNode(itemComponent);
this.scrollElementIntoViewIfNeeded(domNode);
}
}
scrollElementIntoViewIfNeeded(domNode) {
var containerDomNode = React.findDOMNode(this);
// Determine if `domNode` fully fits inside `containerDomNode`.
// If not, set the container's scrollTop appropriately.
}
}
如果您不想通过数学运算来确定该项目是否在列表节点内可见,您可以使用 DOM 方法 scrollIntoView()
或特定于 Webkit 的 scrollIntoViewIfNeeded
,其中 有一个 polyfill 可用,所以你可以在非 Webkit 浏览器中使用它.
If you don't want to do the math to determine if the item is visible inside the list node, you could use the DOM method scrollIntoView()
or the Webkit-specific scrollIntoViewIfNeeded
, which has a polyfill available so you can use it in non-Webkit browsers.
这篇关于如何滚动 div 以在 ReactJS 中可见?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
更多推荐
[db:关键词]
发布评论