用于记住用户投票的CSS样式(向上和向下)

时间:2018-01-29 21:03:12

标签: javascript css reactjs firebase firebase-realtime-database

使用Reactjs和Firebase,我有一个小型投票应用,可以让您投票或下注。登录后,您可以对条目进行投票(目前它们只是名称),并且他们从大多数投票到最少投票的顺序。当您将鼠标悬停在投票图标上时,它们会改变颜色,如下所示:
正常:
enter image description here
悬停:
enter image description here

.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表示向上或向下投票。我确定可以使用该变量,但我不确定如何将其与JavascriptCSS联系起来。

提前感谢任何想法。

修改

火力架布局:
enter image description here
所以对于这个用户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)}>
            &#9650;
            </span>
            <p className="playerContent">{this.playerContent}</p>
            <span className="vote down" 
            onClick={() => this.handleDownvote(this.playerId)}>
            &#9660;
            </span>

        </div>
    )
  }
}

2 个答案:

答案 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)}>
   &#9650;
</span>

这应该可以解决问题。

对于downvote按钮重复-1。

您不必在className属性中执行此操作。您还可以添加自定义数据属性,例如早期评论中建议的@ doppl3r。这个过程是一样的,只是让你的className属性更清晰。

您可能希望使用按钮元素在语义上正确,而不是使用跨度。使用按钮还可以访问已禁用的属性。您可以将相同的逻辑弹出到disabled属性中,以阻止人们多次投票。

希望有所帮助。