切换div的背景颜色

时间:2017-08-19 09:21:59

标签: javascript css reactjs

我正在映射一个div,所以它会根据我数据库中的数据量进行渲染。在我的情况下,我的div渲染了4次。 (这是一项有4个选项的民意调查。)

我会逐步解释我的问题。

1)我想设置div的背景颜色,与我得到的id相匹配 从页面加载时的数据库。我这样做了

    componentDidMount() {

            let sel3 = document.getElementById(this.props.voted_id);

            if (sel3) {

                sel3.style.backgroundColor = "#0b97c4";
                sel3.style.color = "#FFFFFF";
            }
        }

这里this.props.voted_id是我从数据库中获取的id。 (这是用户选择的轮询选项的ID。所以在componentDidMount上我通过设置背景颜色来显示所选选项)

2)如果用户想要更改他/她的选择,用户可以通过单击新选项进行更改。我想将背景颜色设置为所选的新选择用户,同时我想删除先前所选选项的背景颜色。 我这样做是

我的组件

render() {

        let {contents, submitvote, postId, voted_id} = this.props

        return (

            <div className="txt_vote_bar_div" id={this.props.contents.post_poll_content_id}>
                <p className="txt_vote_choice" id={this.props.contents.post_poll_content_id}
                   onClick={() => {
                       this.handleClick(this.props.contents.post_poll_content_id);
                   }}>
                    {contents.content}
                </p>
                <p className="txt_tot_votes"> {this.props.contents.votes_percentage}%
                    ({this.state.voteCount} Votes)</p>
            </div>
        );
    };

在handleClick函数上,我正在执行以下操作

 handleClick(id) {

        let sel = document.getElementById(this.props.voted_id);
    if (sel) {
        alert("1");
        sel.style.backgroundColor = "#FFFFFF";
        sel.style.color = "#6a6a6a";
    }

    let sel2 = document.getElementById(this.props.getVoteStatus);
    if (sel2) {
        alert("2");
        sel2.style.backgroundColor = "#FFFFFF";
        sel2.style.color = "#6a6a6a";
    }

    let el = document.getElementById(id);
    if (el) {
        alert("3");
        this.setState({

            active: false,

        })
        el.style.backgroundColor = "#0b97c4";
        el.style.color = "#FFFFFF";
    }



    let sel3 = document.getElementById(id);
    if (sel3.id == this.props.getVoteStatus && this.state.active == false) {
        alert("4");
        this.setState({
            active: true,
        })
        sel3.style.backgroundColor = "#FFFFFF";
        sel3.style.color = "#6a6a6a";
    }

    }

此处this.props.voted_id是我从数据库中获取的ID(我使用此ID在componentDidMount上设置背景)

此处this.props.getVoteStatus是我之前选择的ID选项,用于在用户选择新选项时删除背景颜色。

到目前为止,我成功地做到了这一点,没有任何问题。但我的问题是这个

当页面加载并且如果我从数据库中获取id时,具有id的特定div被着色。那没关系。但是当用户选择相同的选择(撤回他/她的选择)时

这段代码按原样运行(因为用户选择的div id与我从数据库中获取的id相同)

let sel = document.getElementById(this.props.voted_id);
        if (sel) {
            alert("2");
            sel.style.backgroundColor = "#FFFFFF";
            sel.style.color = "#6a6a6a";
        }

然后这段代码运行

let el = document.getElementById(id);
        if (el) {
            alert("1");
            this.setState({
                active: false,
            })
            el.style.backgroundColor = "#0b97c4";
            el.style.color = "#FFFFFF";
        }

此问题仅在页面加载后出现一次。在那种情况下,两部分代码都是有效的。因此它运行两者。我该如何解决这个问题?

更新

这就是我如何映射我的div元素

export const TextVoteList = ({postData, submitvote}) => {

    const dataUnavailable = (
        <div>
            <p>
                There are no voting options available available
            </p>
        </div>
    );

    const dataAvailable = (
        <div>
            {postData.post_poll_content.map(contents => <TextVoteOptions key={contents.post_poll_content_id} voted_id={postData.personal_vote}  contents={contents} submitvote = {submitvote} postId = {postData._id}/>)}
        </div>
    );

    return (

        <div>
            {postData.post_poll_content.length === 0 ? dataUnavailable : dataAvailable}
        </div>

    );
};

TextVoteOptions 代码

render() {

        alert(this.props.getVoteResponse);

        let {contents, submitvote, postId, voted_id} = this.props

        return (


            <div key={this.props.contents.post_poll_content_id} className= {(this.state.voted_id === this.props.contents.post_poll_content_id && this.state.active)  ? "txt_vote_bar_div active" :  "txt_vote_bar_div"}>
                <p className="txt_vote_choice" id={this.props.contents.post_poll_content_id}
                   onClick={() => {
                       this.handleClick(this.props.contents.post_poll_content_id);
                   }}>
                    {contents.content}
                </p>
                <p className="txt_tot_votes"> {this.props.contents.votes_percentage}%
                    ({this.state.voteCount} Votes)</p>
            </div>
        );
    };

我的点击处理程序

handleClick(id) {

        let vote_object = {
            voting_object: id,
            post_id: this.props.postId
        }

        this.setState({
            voted_id: id,
            active: (id != this.state.voted_id) ? true : !this.state.active
        });


        this.props.submitvote(vote_object);

    }

1 个答案:

答案 0 :(得分:1)

  

你应该自己避免实际的DOM操作。让React处理实际的DOM操作。据我了解,我的设计如下。请尝试和关联。希望这会有所帮助。

在你的问题中,我不明白状态'active'的用法,所以我没有在下面的代码片段中使用过。这是你想要实现的目标。

const contents = [
  {
    post_poll_content_id: 1,
    content: "Soccer",
    votes_percentage: 60
  },
  {
    post_poll_content_id: 2,
    content: "Cricket",
    votes_percentage: 20
  },
  {
    post_poll_content_id: 3,
    content: "Basketball",
    votes_percentage: 20
  }
];

const votedId = 3; // Assume this is coming from database;

class Demo extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      voteCount: 100,
      voted_id: props.voted_id,
      active:true
    };
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick(id) {
    this.setState({
        voted_id: id,
        active: (id != this.state.voted_id) ? true : !this.state.active
    });
    
  }

  render() {
   let {contents, voted_id} = this.props;
    return (
      <div>
        {contents.map((content, index) => {
          return (
            <div key={index} className= {(this.state.voted_id===content.post_poll_content_id && this.state.active)  ? "txt_vote_bar_div active" :  "txt_vote_bar_div"}
                 id={content.post_poll_content_id}
            >
              <p
                className="txt_vote_choice"
                id={content.post_poll_content_id}
                onClick={() => {
                  this.handleClick(content.post_poll_content_id);
                }}
              >
                {content.content}
              </p>
              <p className="txt_tot_votes">
                {content.votes_percentage % this.state.voteCount} Votes
              </p>
            </div>
          );
        })}
      </div>
    );
  }
}
ReactDOM.render(<Demo contents={contents} voted_id = {votedId}/>, document.getElementById("app"));
.txt_vote_bar_div {
   display:block;
   border:1px solid #eee;
   margin: 10px;
   width:20%;
   text-align:center;
}

.active {
  background-color:#0b97c4;
  color:#FFF;
}

.txt_vote_choice {
   color:'blue';
   cursor:pointer;
   text-decoration:underline;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="app"></div>