I created a basic voting system for a comment ratings bar. I'm trying to access the previous Sibling Element to update the votes but it's not working properly. IAre you're supposed to use event.currentTarget or event.target? Where did I go wrong? Thank you.
https://jsfiddle.net/donfontaine12/bm9njcLt/46/#&togetherjs=qocecyJqyy
HTML
<div id="comment_ratings_bar">
<div id="comment_rating_sign">+</div>
<div id="comment_rating_num">0</div>
<div id="comment_rating_percentage">[100.00%] </div>
<div class="green_up_arrow"></div>
<div class="red_down_arrow"></div>
</div>
<div id="comment_ratings_bar">
<div id="comment_rating_sign">+</div>
<div id="comment_rating_num">0</div>
<div id="comment_rating_percentage">[100.00%] </div>
<div class="green_up_arrow"></div>
<div class="red_down_arrow"></div>
</div>
<div id="comment_ratings_bar">
<div id="comment_rating_sign">+</div>
<div id="comment_rating_num">0</div>
<div id="comment_rating_percentage">[100.00%] </div>
<div class="green_up_arrow"></div>
<div class="red_down_arrow"></div>
</div>
<div id="comment_ratings_bar">
<div id="comment_rating_sign">+</div>
<div id="comment_rating_num">0</div>
<div id="comment_rating_percentage">[100.00%] </div>
<div class="green_up_arrow"></div>
<div class="red_down_arrow"></div>
</div>
CSS
#comment_ratings_bar {
width: 30%;
margin: 0px 20px;
padding: 0px 20px;
font-size: 110%;
font-weight: bolder;
font-family: 'B612 Mono', monospace;
color: lime;
background-color: black;
border: 0px solid black;
display: flex;
flex-direction: row;
justify-content: center;
}
.green_up_arrow {
display: flex;
flex-direction: row;
width: 0;
height: 0;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-bottom: 10px solid lime;
cursor: pointer;
margin: 0em 0.25em;
}
.red_down_arrow {
display: flex;
flex-direction: row;
width: 0;
height: 0;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-top: 10px solid red;
cursor: pointer;
margin: 0em 0.25em;
}
JavaScript
window.onload = function() {
let commentUpvotes = 0;
let commentDownvotes = 0;
let totalCommentVotes = commentUpvotes + commentDownvotes;
let commentRatingsBarAll = document.querySelectorAll("#comment_ratings_bar");
for (let c of commentRatingsBarAll) {
c.lastElementChild.previousElementSibling.addEventListener("click", updateCommentVotes);
c.lastElementChild.addEventListener("click", updateCommentVotes);
}
function updateCommentVotes(e) {
let siblings = getSiblings(e);
let sign = siblings[0].textContent;
let number = siblings[1].textContent;
let percentage = siblings[2].textContent;
if (sign && number && percentage) {
let actualNumber = parseFloat(number.replace(/,/g, ''));
if (e.target.className == "green_up_arrow") {
actualNumber++; commentUpvotes++; totalCommentVotes++;
} else {
actualNumber--; commentDownvotes++; totalCommentVotes++;
}
if (actualNumber < 0) { sign.replace("+", ""); }
percentage = "["
+ parseFloat((commentUpvotes / totalCommentVotes) * 100).toFixed(2) +"%]";
number = actualNumber.toLocaleString();
}
}
function getSiblings(element) {
if (element) {
let siblings = [];
let sibling = element.parentNode.firstElementChild;
while(sibling) {
if (sibling.nodeType === 1 && sibling !== element) {
siblings.push(sibling);
sibling = sibling.nextElementSibling;
}
}
return siblings;
}
}
}
Everything's working but inside the updateCommentVotes function, I should have been referencing the actual divs containing the textContent instead of the local variables (sign, number & percentage).
EDIT: It's a partial fix, I need each individual comment bar to refer to its own sign, number and percentage. It seems they all share the same number values. Any tips are appreciated. Although, I believe its because I hard coded the values from siblings. Thank you.
Check the code here: https://jsfiddle.net/donfontaine12/bm9njcLt/46/#
JavaScript
window.onload = function() {
let commentUpvotes = 0;
let commentDownvotes = 0;
let totalCommentVotes = commentUpvotes + commentDownvotes;
let commentRatingsBarAll = document.querySelectorAll("#comment_ratings_bar");
for (let c of commentRatingsBarAll) {
c.lastElementChild.previousElementSibling.addEventListener("click", updateCommentVotes);
c.lastElementChild.addEventListener("click", updateCommentVotes);
}
function updateCommentVotes(e) {
let siblings = getSiblings(e);
let sign = siblings[0].textContent;
let number = siblings[1].textContent;
let percentage = siblings[2].textContent;
if (sign && number && percentage) {
let actualNumber = parseFloat(number.replace(/,/g, ''));
if (e.target.className == "green_up_arrow") {
actualNumber++; commentUpvotes++; totalCommentVotes++;
} else {
actualNumber--; commentDownvotes++; totalCommentVotes++;
}
if (actualNumber < 0) { siblings[0].textContent.replace("+", ""); }
siblings[2].textContent = "["
+ parseFloat((commentUpvotes / totalCommentVotes) * 100).toFixed(2) +"%]";
siblings[1].textContent = actualNumber.toLocaleString();
}
}
function getSiblings(element) {
let siblings = [];
let sibling = element.target.parentNode.firstElementChild;
while(sibling) {
if (sibling.nodeType === 1 && sibling !== element) {
siblings.push(sibling);
sibling = sibling.nextElementSibling;
}
}
return siblings;
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.