有条件地显示带有悬停和超时的反应组件
我遇到了一个棘手的反应布局问题。这是一个很简单的问题,只是很难解释,所以我试着尽可能地明确。我有一些映射单个组件的数据,如下所示:
map => <TableRow name={props.name} actionOne={props.someAction} />
名称 | 类型 | 显示/隐藏控件 | 按钮(默认情况下隐藏) |
---|---|---|---|
John Deere | 拖拉机 | 显示/隐藏 | <;div样式=&隐藏&t;&>按钮id=";actionOneButton";>;<;/div>; |
约翰·史密斯 | 人员 | 显示/隐藏 | <;div样式=&隐藏&t;&>按钮id=";actionOneButton";>;<;/div>; |
我们需要做两件事:
进入表格并将鼠标悬停在一行上时,会有500毫秒的延迟,之后只会显示该行的操作按钮。如果在此之后,我们将光标向上或向下移动到中的不同行,则没有延迟,新悬停的行会立即显示其对应的按钮,而上一行中先前显示的按钮会立即隐藏
当用户将光标移动到表外时,会有500毫秒的倒计时。在此期间,最后一行显示的按钮将保持显示状态。一旦计时器启动,上次显示按钮的那一行现在将其隐藏。将其视为悬停时显示(&Q;),但进入和退出表格时有500毫秒的延迟。
快完成了!
- 警告:单击
show
链接将永久显示该行中的按钮,而隐藏链接通过隐藏按钮将按钮返回到原始状态。(我们又回到了第一名) 手动显示的按钮将永久保持不变,直到关闭,此时它们的行为与开始时相同。
重要说明: 如果游标退出表格,然后在";退出计时器计时器停止计时之前在表格内部徘徊:
- 当光标位于表外时,以前突出显示的显示按钮的行保持可见;然后在达到500毫秒的退出超时时将其隐藏。
- 同时,由于上述内容即将超时并即将消失,现在再次进入表格的光标将启动500ms计数,以显示其重新进入的行的隐藏按钮。此时,#1超时并隐藏,如果从表格内部悬停,将按照开头的第一组条件立即显示:如果通过了500毫秒的入口,则会立即显示一行中的任何隐藏按钮。
问题
我有一些松散的想法,但是在设计这样的东西时,我想到了什么,以便将所有的状态和超时(这是不是最多的方式)封装在最多两个组件中-类似于表和行的东西?
如何设计此组件功能?我是不是找错地方了?能用聪明的css来显示/隐藏吗?
解决方案
我相信这可能是一种可行的解决方案。经过进一步调整,我认为它可以实现您概述的所需行为。
通过使用离开表点的鼠标坐标,从行列表中捕获游标离开表的最后一个元素。在该示例中,退出的元素将保持可见,但您可以决定如何处理它。
[...table.children[0].children].forEach(tr => {
tr.classList.remove('exited');
if(evt.offsetY >= tr.offsetTop
&& evt.offsetY <= tr.offsetTop + tr.clientHeight
){
tr.classList.add('exited'); // in react you could instead set this element to state.
}
});
希望这不会成为转换到JSX的问题。您可以使用refObject
保留对表的DOM元素的引用。
const table = document.getElementById("table");
let hoverTimer = 0;
table.addEventListener("mouseenter", () => {
clearTimeout(hoverTimer);
hoverTimer = setTimeout(() =>
table.classList.add('active'),
500
);
});
table.addEventListener("mouseleave", (evt) => {
[...table.children[0].children].forEach(tr => {
tr.classList.remove('exited');
if(evt.offsetY >= tr.offsetTop
&& evt.offsetY <= tr.offsetTop + tr.clientHeight
){
tr.classList.add('exited');
}
});
clearTimeout(hoverTimer);
hoverTimer = setTimeout(() =>
table.classList.remove('active'),
500
);
});
tr.table-row button.action-btn {
pointer-events: none;
}
table.active tr.table-row:hover button.action-btn {
pointer-events: auto;
}
tr.table-row {
opacity: 0;
transition: opacity 0.5s;
}
table.active tr.table-row:hover {
opacity: 1;
}
tr.exited {
opacity: 1;
}
<table id="table">
<tr class="table-row"><td><button class="action-btn">click me!</button></td></tr>
<tr class="table-row"><td><button class="action-btn">click me!</button></td></tr>
<tr class="table-row"><td><button class="action-btn">click me!</button></td></tr>
<tr class="table-row"><td><button class="action-btn">click me!</button></td></tr>
<tr class="table-row"><td><button class="action-btn">click me!</button></td></tr>
<tr class="table-row"><td><button class="action-btn">click me!</button></td></tr>
<tr class="table-row"><td><button class="action-btn">click me!</button></td></tr>
<tr class="table-row"><td><button class="action-btn">click me!</button></td></tr>
<tr class="table-row"><td><button class="action-btn">click me!</button></td></tr>
<tr class="table-row"><td><button class="action-btn">click me!</button></td></tr>
</table>
相关文章