首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >创建Javascript投票系统

创建Javascript投票系统
EN

Stack Overflow用户
提问于 2019-03-21 04:17:21
回答 3查看 7.5K关注 0票数 5

这是我对投票制度的尝试。如果只有一个,它就会像预期的那样工作。然而,当我试图扩大投票系统的数量超过一个,它并不像预期的那样工作。问题是投票系统依赖于upVotedownVote状态。因此,当我增加投票系统的数量时,它们都依赖于相同的两个变量,而不是每个变量都有自己的upVotedownVote变量。我认为有两种方法可以解决我的问题。

  1. 创建一个数组,以便每个投票系统都有自己的upVotedownVote变量。
  2. 用关闭。

第一个我认为过于繁琐和不切实际--我不知道如何实现这个解决方案。第二次,我试过了,但没能成功。

我想不出更简单的事了。我不一定要寻找一个使用闭包的解决方案。任何简单的香草Javascript解决方案都可以。

工作守则:

代码语言:javascript
复制
const up_vote_span = document.querySelector('.up-vote');
const down_vote_span = document.querySelector('.down-vote');
let count = document.querySelector('.number');

let upVote = false;
let downVote = false;

up_vote_span.addEventListener('click', function() {

  if (downVote === true) {

    up_vote_span.style.color = "#3CBC8D";
    down_vote_span.style.color = "dimgray";
    count.innerHTML = parseInt(count.innerHTML) + 2;
    upVote = true;
    downVote = false;

  } else if (upVote === false) {
    up_vote_span.style.color = "#3CBC8D";
    count.innerHTML = parseInt(count.innerHTML) + 1;
    upVote = true;
  } else if (upVote === true) {
    up_vote_span.style.color = "dimgray";
    count.innerHTML = parseInt(count.innerHTML) - 1;
    upVote = false;
  }
});

down_vote_span.addEventListener('click', function() {

  if (upVote === true) {
    up_vote_span.style.color = "dimgray";
    down_vote_span.style.color = "#3CBC8D";
    count.innerHTML = parseInt(count.innerHTML) - 2;
    downVote = true;
    upVote = false;
  } else if (downVote === false) {
    down_vote_span.style.color = "#3CBC8D";
    count.innerHTML = parseInt(count.innerHTML) - 1;
    downVote = true;
  } else if (downVote === true) {
    down_vote_span.style.color = "dimgray";
    count.innerHTML = parseInt(count.innerHTML) + 1;
    downVote = false;
  }
});
代码语言:javascript
复制
.number {
  display: inline-block;
  text-align: center;
}

.vote {
  display: flex;
  flex-direction: column;
  text-align: center;
}

.up-vote {
  color: dimgray;
  cursor: pointer;
}

.down-vote {
  cursor: pointer;
  color: dimgray;
}
代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en" dir="ltr">

<head>
  <meta charset="utf-8">
  <title></title>
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous">
</head>


  <div class="vote">
    <span class="up-vote"><i class="fas fa-angle-up"></i></span>
    <span class="number">990</span>
    <span class="down-vote"><i class="fas fa-angle-down"></i></span>
  </div>

有问题的代码:

代码语言:javascript
复制
const up_vote_span = document.getElementsByClassName('up-vote');
const down_vote_span = document.getElementsByClassName('down-vote');
const count = document.getElementsByClassName('number');

let upVote = false;
let downVote = false;

for (let i = 0; i < count.length; i++) {
  up_vote_span[i].addEventListener('click', function() {

    if (downVote === true) {
      up_vote_span[i].style.color = "#3CBC8D";
      down_vote_span[i].style.color = "dimgray";
      count[i].innerHTML = parseInt(count[i].innerHTML) + 2;
      upVote = true;
      downVote = false;

    } else if (upVote === false) {
      up_vote_span[i].style.color = "#3CBC8D";
      count[i].innerHTML = parseInt(count[i].innerHTML) + 1;
      upVote = true;
    } else if (upVote === true) {
      up_vote_span[i].style.color = "dimgray";
      count[i].innerHTML = parseInt(count[i].innerHTML) - 1;
      upVote = false;
    }
  });

  down_vote_span[i].addEventListener('click', function() {

    if (upVote === true) {
      up_vote_span[i].style.color = "dimgray";
      down_vote_span[i].style.color = "#3CBC8D";
      count[i].innerHTML = parseInt(count[i].innerHTML) - 2;
      downVote = true;
      upVote = false;
    } else if (downVote === false) {
      down_vote_span[i].style.color = "#3CBC8D";
      count[i].innerHTML = parseInt(count[i].innerHTML) - 1;
      downVote = true;
    } else if (downVote === true) {
      down_vote_span[i].style.color = "dimgray";
      count[i].innerHTML = parseInt(count[i].innerHTML) + 1;
      downVote = false;
    }
  });
}
代码语言:javascript
复制
.number {
  display: inline-block;
  text-align: center;
}

.vote {
  display: flex;
  flex-direction: column;
  text-align: center;
}

.up-vote {
  color: dimgray;
  cursor: pointer;
}

.down-vote {
  cursor: pointer;
  color: dimgray;
}
代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en" dir="ltr">

<head>
  <meta charset="utf-8">
  <title></title>
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous">
</head>

<body>

  <div class="vote">
    <span class="up-vote"><i class="fas fa-angle-up"></i></span>
    <span class="number">990</span>
    <span class="down-vote"><i class="fas fa-angle-down"></i></span>
  </div>
  <div class="vote">
    <span class="up-vote"><i class="fas fa-angle-up"></i></span>
    <span class="number">990</span>
    <span class="down-vote"><i class="fas fa-angle-down"></i></span>
  </div>
  <div class="vote">
    <span class="up-vote"><i class="fas fa-angle-up"></i></span>
    <span class="number">990</span>
    <span class="down-vote"><i class="fas fa-angle-down"></i></span>
  </div>
  <div class="vote">
    <span class="up-vote"><i class="fas fa-angle-up"></i></span>
    <span class="number">990</span>
    <span class="down-vote"><i class="fas fa-angle-down"></i></span>
  </div>

</body>

</html>

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-03-21 05:15:30

我认为您会发现这更容易控制,如果您使用您提到的数组方法作为选项1,然后创建一个用于向上的函数和一个用于下垂的函数,而不是像现在这样为每个向上和向下箭头创建单独的函数。

现在有四个组,所以在for循环中我们可以初始化一个数组,如下所示:

代码语言:javascript
复制
const votes = [
  0: { up: false, down: false },
  1: { up: false, down: false },
  2: { up: false, down: false },
  3: { up: false, down: false },
];

然后,您只需调用您的向上和向下投票函数,并检查该数组中对象的值,该对象对应于您单击的箭头的组号。

另一件我认为有助于可读性的事情是把投票总数和颜色变化分开。

你的投票逻辑包括三种不同的可能性。2.箭头已被选中)对箭头进行检查,3.)两个箭头都没有被检查。但是,更改颜色的逻辑和更改每个箭头的检查值的逻辑实际上只有两种可能性:要么之前检查箭头,要么没有检查箭头。

所以我继续在下面的片段中做了这个改变。

希望这能有所帮助。

代码语言:javascript
复制
const up_vote_spans = document.getElementsByClassName('up-vote');
const down_vote_spans = document.getElementsByClassName('down-vote');
const count = document.getElementsByClassName('number');

let votes = [];

for (let i = 0; i < count.length; i += 1) {
  const thisUpVoteSpan = up_vote_spans[i];
  const thisDownVoteSpan = down_vote_spans[i];
  votes[i] = { up: false, down: false };

  thisUpVoteSpan.addEventListener('click', handleUpvote.bind(null, i), false);
  thisDownVoteSpan.addEventListener('click', handleDownvote.bind(null, i), false);
}

function handleUpvote(i) {
  const currentVote = votes[i];
  const matchingUpSpan = up_vote_spans[i];
  const matchingDownSpan = down_vote_spans[i];
  const matchingCount = count[i];
  const currentCount = parseInt(matchingCount.innerHTML);

  if (currentVote.down) {
    matchingCount.innerHTML = currentCount + 2;
  } else if (currentVote.up === false) {
    matchingCount.innerHTML = currentCount + 1;
  } else {
    matchingCount.innerHTML = currentCount - 1;
  }
  if (!currentVote.up) {
    matchingUpSpan.style.color = "#3CBC8D";
    matchingDownSpan.style.color = 'dimgray';
    currentVote.up = true;
    currentVote.down = false;
  } else {
    matchingUpSpan.style.color = 'dimgray';
    currentVote.up = false;
  }
}

function handleDownvote(i) {
  const currentVote = votes[i];
  const matchingUpSpan = up_vote_spans[i];
  const matchingDownSpan = down_vote_spans[i];
  const matchingCount = count[i];
  const currentCount = parseInt(matchingCount.innerHTML);

  if (currentVote.up) {
    matchingCount.innerHTML = currentCount - 2;
  } else if (currentVote.down === false) {
    matchingCount.innerHTML = currentCount - 1;
  } else {
    matchingCount.innerHTML = currentCount + 1;
  }
  if (!currentVote.down) {
    matchingDownSpan.style.color = "#3CBC8D";
    matchingUpSpan.style.color = 'dimgray';
    currentVote.down = true;
    currentVote.up = false;
  } else {
    matchingDownSpan.style.color = 'dimgray';
    currentVote.down = false;
  }
}
代码语言:javascript
复制
.number {
  display: inline-block;
  text-align: center;
}

.vote {
  display: flex;
  flex-direction: column;
  text-align: center;
}

.up-vote {
  color: dimgray;
  cursor: pointer;
}

.down-vote {
  cursor: pointer;
  color: dimgray;
}
代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en" dir="ltr">

<head>
  <meta charset="utf-8">
  <title></title>
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous">
</head>

<body>

  <div class="vote">
    <span class="up-vote"><i class="fas fa-angle-up"></i></span>
    <span class="number">990</span>
    <span class="down-vote"><i class="fas fa-angle-down"></i></span>
  </div>
  <div class="vote">
    <span class="up-vote"><i class="fas fa-angle-up"></i></span>
    <span class="number">990</span>
    <span class="down-vote"><i class="fas fa-angle-down"></i></span>
  </div>
  <div class="vote">
    <span class="up-vote"><i class="fas fa-angle-up"></i></span>
    <span class="number">990</span>
    <span class="down-vote"><i class="fas fa-angle-down"></i></span>
  </div>
  <div class="vote">
    <span class="up-vote"><i class="fas fa-angle-up"></i></span>
    <span class="number">990</span>
    <span class="down-vote"><i class="fas fa-angle-down"></i></span>
  </div>

</body>

</html>

票数 3
EN

Stack Overflow用户

发布于 2019-03-21 05:26:45

我正在使用原型模式来组织代码。

这将适用于n .vote类在HTML中。例如,给定以下HTML,将创建两个投票对象,并将其与各自的UI相关联。

代码语言:javascript
复制
<div class="vote">
  <span class="up-vote"><i class="fas fa-angle-up"></i></span>
  <span class="number">0</span>
  <span class="down-vote"><i class="fas fa-angle-down"></i></span>
</div>
<div class="vote">
  <span class="up-vote"><i class="fas fa-angle-up"></i></span>
  <span class="number">0</span>
  <span class="down-vote"><i class="fas fa-angle-down"></i></span>
</div>

您可能已经注意到,在上面的id中没有HTMLidforEach循环中动态创建,并在每个对象的init上分配。我使用myVotePrototype作为模板,将其prototype复制到在myVote中创建的每个新对象中。myVote需要一个id来初始化,这就是每个投票都知道在哪里找到其关联的UI部分的方式。

颜色呢?

JavaScript.vote父容器中设置投票方向。因此,在进行了向上投票之后,该投票对象的HTML将如下所示:

代码语言:javascript
复制
<div class="vote vote-up">
  <span class="up-vote"><i class="fas fa-angle-up"></i></span>
  <span class="number">0</span>
  <span class="down-vote"><i class="fas fa-angle-down"></i></span>
</div>

我添加了一个小的CSS,这样每个按钮都知道什么时候应该使用活动的颜色。我发现这比将十六进制代码直接写到style属性要麻烦得多。

代码语言:javascript
复制
.vote.vote-up .up-vote,
.vote.vote-down .down-vote {
  color: #3CBC8D;
}

演示

代码语言:javascript
复制
const myVotePrototype = {
  init: function(id) {
    this.voteId = id;
    // Prepare for voting clicks
    this.bindEvents();
  },
  votes: 0,
  upVote: function() {
    this.votes++;
    this.setVoteDirection('up');
  },
  downVote: function() {
    this.votes--;
    this.setVoteDirection('down');
  },
  setVoteDirection: function(direction) {
    let voteObj = document.getElementById(this.voteId);
    if (direction === 'up') {
      voteObj.classList.add('vote-up');
      if (voteObj.classList.contains('vote-down')) {
        voteObj.classList.remove('vote-down');
      }
    } else if (direction === 'down') {
      voteObj.classList.add('vote-down');
      if (voteObj.classList.contains('vote-up')) {
        voteObj.classList.remove('vote-up');
      }      
    }
  },
  updateUI: function() {
    document.querySelector(`#${this.voteId} .number`).innerHTML = Number(this.votes);
  },
  bindEvents: function() {
    document
      .querySelector(`#${this.voteId} .up-vote`)
      .addEventListener('click', () => {
        this.upVote();
        this.updateUI();
      });
    document
      .querySelector(`#${this.voteId} .down-vote`)
      .addEventListener('click', () => {
        this.downVote();
        this.updateUI();
      })
  }
};

function myVote(id) {
  function V() {};
  V.prototype = myVotePrototype;

  let v = new V();

  v.init(id);
  return v;
}

// Loop through all votes in the UI
const votes = document.querySelectorAll('.vote');
votes.forEach((vote, index) => {
  // Create an id
  let voteId = `vote_${index}`;
  // Set the id in the UI so we can find it later for updating
  vote.setAttribute('id', voteId);
  // Create a new vote object, passing in the vote id
  myVote(voteId);
});
代码语言:javascript
复制
.number {
  display: inline-block;
  text-align: center;
}

.vote {
  display: flex;
  flex-direction: column;
  text-align: center;
}

.up-vote,
.down-vote {
  color: dimgray;
  cursor: pointer;
}

.vote.vote-up .up-vote,
.vote.vote-down .down-vote {
  color: #3CBC8D;
}
代码语言:javascript
复制
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous">

<div class="vote">
  <span class="up-vote"><i class="fas fa-angle-up"></i></span>
  <span class="number">0</span>
  <span class="down-vote"><i class="fas fa-angle-down"></i></span>
</div>
<div class="vote">
  <span class="up-vote"><i class="fas fa-angle-up"></i></span>
  <span class="number">0</span>
  <span class="down-vote"><i class="fas fa-angle-down"></i></span>
</div>
<div class="vote">
  <span class="up-vote"><i class="fas fa-angle-up"></i></span>
  <span class="number">0</span>
  <span class="down-vote"><i class="fas fa-angle-down"></i></span>
</div>

改进的思路

  • 语义的、可访问的HTML (<button>而不是<span>)
  • 使用阿里亚buttonnumber输出相关联
  • localStorage来记住页面加载之间的投票状态(或者使用真正的DB:)
票数 6
EN

Stack Overflow用户

发布于 2019-03-21 05:27:07

就我个人而言,我认为一系列投票的布尔人并不坏。但是,如果您想要一种不同的方法,您可以使用类操作来保持它们的分离。

JSFiddle:https://jsfiddle.net/0uw83a17/

代码语言:javascript
复制
// From https://plainjs.com/javascript/traversing/get-siblings-of-an-element-40/
function getSiblings(el, filter) {
    var siblings = [];
    el = el.parentNode.firstChild;
    do { if (!filter || filter(el)) siblings.push(el); } while (el = el.nextSibling);
    return siblings;
}

function classFilter(el) {
    return el.classList && el.classList.contains('active-vote');
}

function handleVote(type, el) {
    let siblings = getSiblings(el, classFilter);

    if (el.classList.contains('active-vote')) {
        el.style.color = "dimgray";
        el.classList.remove('active-vote');
        return -1 * type;
    } else if (siblings.length === 1) {
        el.style.color = "#3CBC8D";
        siblings[0].style.color = "dimgray";
        siblings[0].classList.remove('active-vote');
        el.classList.add('active-vote');

        return 2 * type;
    } else if (!el.classList.contains('active-vote')) {
        el.style.color = "#3CBC8D";
        el.classList.add('active-vote');
        return type;
    }

    return 0;
}

const up_vote_span = document.getElementsByClassName('up-vote');
const down_vote_span = document.getElementsByClassName('down-vote');
const count = document.getElementsByClassName('number');

for (let i = 0; i < count.length; i++) {
  up_vote_span[i].addEventListener('click', function(e) {
      count[i].innerHTML = parseInt(count[i].innerHTML) + handleVote(1, up_vote_span[i]);
    });

  down_vote_span[i].addEventListener('click', function() {
      count[i].innerHTML = parseInt(count[i].innerHTML) + handleVote(-1, down_vote_span[i]);
  });
};
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55273716

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档