有条件地显示带有悬停和超时的反应组件 [英] Conditionally displaying React components with hover and timeouts

查看:23
本文介绍了有条件地显示带有悬停和超时的反应组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了一个棘手的反应布局问题。这是一个很简单的问题,只是很难解释,所以我试着尽可能地明确。我有一些映射单个组件的数据,如下所示:

map => <TableRow name={props.name} actionOne={props.someAction} />

名称 类型 显示/隐藏控件 按钮(默认情况下隐藏)
John Deere 拖拉机 显示/隐藏 <;div样式=&隐藏&t;&>按钮id=";actionOneButton";>;<;/div>;
约翰·史密斯 人员 显示/隐藏 <;div样式=&隐藏&t;&>按钮id=";actionOneButton";>;<;/div>;
默认情况下,控件按钮处于隐藏状态。这里的想法是仅在用户停留在特定行或用户决定让某些控件按钮在特定行上永久可见时才显示按钮工具

我们需要做两件事:

  1. 进入表格并将鼠标悬停在一行上时,会有500毫秒的延迟,之后只会显示该行的操作按钮。如果在此之后,我们将光标向上或向下移动到中的不同行,则没有延迟,新悬停的行会立即显示其对应的按钮,而上一行中先前显示的按钮会立即隐藏

  2. 当用户将光标移动到表外时,会有500毫秒的倒计时。在此期间,最后一行显示的按钮将保持显示状态。一旦计时器启动,上次显示按钮的那一行现在将其隐藏。将其视为悬停时显示(&Q;),但进入和退出表格时有500毫秒的延迟。

快完成了!

  1. 警告:单击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>

这篇关于有条件地显示带有悬停和超时的反应组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆