使用Reactjs
和Firebase,我有一个小型投票应用,可以让您投票或下注。登录后,您可以对条目进行投票(目前它们只是名称),并且他们从大多数投票到最少投票的顺序。当您将鼠标悬停在投票图标上时,它们会改变颜色,如下所示:
正常:
悬停:
.downVote {
align-items: center;
font-size: 1.0em;
padding-top: 2px;
margin-right: 3px;
float: right;
color: #fb655a;
cursor: pointer;
}
.downVote:hover {
border-width: 0px;
background-color: #fb655a;
color: #000;
}
我希望找到一种方法,在投票完成后保持悬停属性处于活动状态 - 这是:active(?)
状态,并让Javascript或Firebase记住将该投票图标保持在该状态。因此,当用户对几个名字进行投票并稍后返回该页面时,他们将看到他们投票的内容以及他们的投票结果。
我正在寻找如何实现这一目标的想法。
目前,在firebase中,我将用户的身份验证ID(uid)保存在他们投票的每个人名中,作为1或-1表示向上或向下投票。我确定可以使用该变量,但我不确定如何将其与Javascript
或CSS
联系起来。
提前感谢任何想法。
修改
火力架布局:
所以对于这个用户vKl6r ...(在这种情况下我),当我登录时,我应该看到在名为Test的人旁边按下upvote按钮,因为存储了1。
以下是可以投票的每个人姓名的布局(带投票图标)
handleUpvote(id){
this.props.upvotePlayer(id)
}
handleDownvote(id){
this.props.downvotePlayer(id)
}
render(props){
return(
<div className="player fade-in">
<span className="vote up"
onClick={() => this.handleUpvote(this.playerId)}>
▲
</span>
<p className="playerContent">{this.playerContent}</p>
<span className="vote down"
onClick={() => this.handleDownvote(this.playerId)}>
▼
</span>
</div>
)
}
}
答案 0 :(得分:1)
一般的想法是创建一个CSS类,用于按钮在投票时的样子,然后如果您的数据库对象包含按钮中的名称,则有条件地将className应用于按钮。
CSS类选择器与您现在使用的悬停选择器相同:
.alreadyVotedOn {
border-width: 0px;
background-color: #fb655a;
color: #000;
}
有条件地将此类名称应用于按钮,具体取决于是否已对其进行投票:
<button className={{this.state.votedOn[name] === -1 ? 'alreadyVotedOn' : null}}>▼</button>
我使用this.state.votedOn[name] === -1
来检测某些内容是否已被投票,因为它听起来像是一个对象,其中包含用户在您的firebase中某个地方投票的所有人的名字。
为此,您需要将该对象加载到组件中,并将其存储在“votedOn”键下的状态。你可以在componentDidMount中使用数据库调用来执行此操作,或者如果您使用的是redux或mobx则传递数据。
建议这样做的最佳方法真的很难,因为我们不了解数据的形状,如何将其拉入组件或组件代码的外观。如果您可以共享数据库中相关块的屏幕截图和组件的代码,那么我们可以更有用。
答案 1 :(得分:1)
我不确定你是如何传递道具的,但是如果this.playerContent
对应于屏幕截图中的字符串'test',那么组件中的this.voters
应该与人物对应投了票。
如果这是正确的,那么我会用我的uid在这个对象中搜索一个键,并检查该值是否为1.
this.voters[myUid] === 1
你需要把你的uid作为道具。或者在componentDidmount中调用auth()以确保您可以访问您的uid。
如果密钥存在且值为1,那么我会在下面的其他帖子中添加一个.alreadyVotedOn
类。您可以使用三元运算符或简单&amp;&amp; amp;操作者...
this.voters[myUid] === 1 && 'alreadyVotedOn'
使用模板字符串将其弹出到upvote按钮的className中:
<span
className={{`vote up ${this.state.votedOn[name] === 1 && 'alreadyVotedOn'}`}}
onClick={() => this.handleUpvote(this.playerId)}>
▲
</span>
这应该可以解决问题。
对于downvote按钮重复-1。
您不必在className属性中执行此操作。您还可以添加自定义数据属性,例如早期评论中建议的@ doppl3r。这个过程是一样的,只是让你的className属性更清晰。
您可能希望使用按钮元素在语义上正确,而不是使用跨度。使用按钮还可以访问已禁用的属性。您可以将相同的逻辑弹出到disabled属性中,以阻止人们多次投票。
希望有所帮助。