I'm just doing my final project for FreeCodeCamp's Front end certificate. I turned it into a fighting game, for which the button sequences initiate moves. The problem is that the animations are really buggy. Here are the details:
---Background---
-The codepen link and code are at the bottom
-When I coded it locally, everything worked great, and the player actions were were done using jquery-based animations. (I used the setTimeout(), animation(), css(), and attr() a lot to move the avatars around and switch pictures to show movement
--The problem---
-I put the code on codepen, and so I needed to host the sprite images to use them (I used dropbox). This change caused the animations to not work properly. Some of the images and sounds either load slowly or not at all. If you go to the codepen and try the buttons at the bottom you will quickly see what I mean.
---What I tried---
-I thought that maybe this might be a problem with the app taking too long to load the assets and cache them. (because some of the animations became more fluid after I repeated them) So I added a function near the top to load the photos at the beginning 'imageInit()'. But the problem persists.
Can anyone please help me figure out what is making my jquery animations so choppy and inconsistent? Am I using the wrong techniques perhaps? Please let me know if you need any more info about this. The code is below:
Thank you!
JK
The code is here: https://codepen.io/jonnnyk20/pen/XaPqrR, and here is some code form the project:
var playerSpace = $('.player-space');
var playerAvatar = $('#player-image');
var playerImages = {
"basic": "https://u57193820.dl.dropboxusercontent.com/u/57193820/saiyan-says/images/goku/goku-basic.png",
"attack": "https://u57193820.dl.dropboxusercontent.com/u/57193820/saiyan-says/images/goku/goku-attack.png",
"attack2": "https://u57193820.dl.dropboxusercontent.com/u/57193820/saiyan-says/images/goku/goku-attack2.png",
"attack3": "https://u57193820.dl.dropboxusercontent.com/u/57193820/saiyan-says/images/goku/goku-attack3.png" }
var tlp = new Audio('https://u57193820.dl.dropboxusercontent.com/u/57193820/saiyan-says/sounds/misc/instant-transmission.mp3');
var hitSound = new Audio('https://u57193820.dl.dropboxusercontent.com/u/57193820/saiyan-says/sounds/misc/hit.mp3');
function imageInit(obj){
for (image in obj){
$('<img/>')[0].src = console.log(obj[image]);
}
}
imageInit(miscImages);
imageInit(playerImages);
imageInit(enemyImages);
function attackAnimation(){
playerAvatar.attr("src", miscImages['blur']);
playerAvatar.fadeOut( 100, function() {
// Animation complete.
playerAvatar.fadeIn( 100, function() {
// Animation complete
playerAvatar.attr("src", playerImages['attack']);
enemyAvatar.attr("src", enemyImages['hurt']);
hitSound.play();
playerSpace.css({ left: "55%"});
setTimeout(function(){
playerAvatar.attr("src", miscImages['blur']);
playerAvatar.fadeOut( 100, function() {
playerAvatar.fadeIn( 100, function() {
playerAvatar.attr("src", playerImages['basic']);
enemyAvatar.attr("src", enemyImages['basic']);
playerSpace.css({ left: "20%"});
})
})
}, 200)
});
});
}
.container {
padding: 10px;
}
.row {
margin: 0;
}
.element {
display: inline-block;
background-color: white;
color: #0275d8;
border: solid 1px #0275d8;
border-radius: 50px;
min-width: 75px;
min-height: 75px;
text-align: center;
padding: 10px;
margin: 5px;
padding-top: 25px;
}
.progress {
margin: 5px;
}
.healthBar {
min-height: 20px;
width: 100%;
border-radius: 5px;
padding-left: 5px;
color: #023a6b;
}
.hb-label {
position: absolute;
margin-left: 5px;
font-size: small;
}
.healthBarContainer {
background-color: white;
border-radius: 5px;
margin: 5px;
border: solid 1px #3b66e6;
}
.gameInfo {
margin: 5px;
border: solid 1px gray;
padding: 5px;
/* background-color: #ececec; */
border-radius: 5px;
display: inline-block;
}
.game-screen {
background-color: #b2ebff;
border: solid 1px #0275d8;
height: 228px;
}
.game-control {
border: solid 1px #0275d8;
border-left: none;
text-align: center;
padding: 10px;
}
.button-group {
margin: auto;
}
.game-header {
border: solid 1px #0275d8;
border-bottom: none;
text-align: center;
z-index: 1;
background-color: white;
}
.game-settings {
border: solid 1px #0275d8;
border-top: none;
text-align: center;
}
.block {
margin-right: 40px;
}
.attack {
margin-bottom: -20px;
}
.dodge {
margin-top: -20px;
}
.fighter-space {
/* border: solid 1px #3b66e6; */
border-radius: 20px;
height: 100px;
width: 100px;
text-align: center;
}
.enemy-space {
position: absolute;
right: 20%;
top: 30px;
}
.player-space {
position: absolute;
left: 20%;
top: 30px;
z-index: 1;
}
.half {
float: left !important;
width: 50% !important;
z-index: 1;
}
.ki-space {
display:none;
position: absolute;
top: 30px;
left: 30%;
z-index: 1;
}
.lazer-space {
position: absolute;
top: 9px;
left: 27%;
display: none;
}
.test-actions {
margin: 10px;
}
.fighter-space.km-space {
position: absolute;
top: 25px;
left: 20%;
display:none;
z-index:1
}
.km-space {
z-index: 2
}
.fighter-space.db-space {
position: absolute;
top: -80px;
right: 20%;
display: none;
}
img#db-image {
margin-top: 40px;
}
#separate {
font-weight: bold;
margin: 10px;
font-size: large;
color: crimson
}
<div class="container">
<div class="row top-row">
<div class="col-md-12 game-header">
Title
</div>
</div>
<div class="row mid-row">
<div class="col-md-7 game-screen">
<div class="row health-bars">
<div class="col-md-6 half">
<div class="healthBarContainer">
<div class="hb-label"> Player Health: <span id="playerHealth">0</span> </div>
<div class="healthBar bg-success" id="playerHealthBar" data-p="100" >
</div>
</div>
</div>
<div class="col-md-6 half">
<div class="healthBarContainer">
<div class="hb-label"> Enemy Health: <span id="enemyHealth">0</span> </div>
<div class="healthBar bg-warning" id="enemyHealthBar" data-p="100" syle="min-width: 1em">
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12 fight-ring">
<div class="fighter-space player-space">
<img src="https://u57193820.dl.dropboxusercontent.com/u/57193820/saiyan-says/images/goku/goku-basic.png" id="player-image" height="100" width="100">
</div>
<div id="projectlie">
<div class="fighter-space ki-space">
<img src="https://u57193820.dl.dropboxusercontent.com/u/57193820/saiyan-says/images/misc/ki-blast.png" id="ki-image" height="100" width="100">
</div>
<div class="fighter-space lazer-space">
<img src="https://u57193820.dl.dropboxusercontent.com/u/57193820/saiyan-says/images/misc/ki-lazer.png" id="lazer-image" height="100" width="250">
</div>
<div class="fighter-space km-space">
<img src="https://u57193820.dl.dropboxusercontent.com/u/57193820/saiyan-says/images/misc/kamehameha1.png" id="km-image" height="100" width="400">
</div>
</div>
<div class="fighter-space enemy-space">
<img src="https://u57193820.dl.dropboxusercontent.com/u/57193820/saiyan-says/images/frieza/frieza-basic.png" id="enemy-image" height="100" width="100">
</div>
<div class="fighter-space db-space">
<img src="https://u57193820.dl.dropboxusercontent.com/u/57193820/saiyan-says/images/misc/frieza-ball.png" id="db-image" height="10" width="10">
</div>
</div>
</div>
</div>
<div class="col-md-5 game-control">
<div class="row">
<div class="button-group">
<div data-i=0 class="simon element attack">Attack</div>
</div>
</div>
<div class="row">
<div class="button-group">
<div data-i=1 class="simon element block">Block</div>
<div data-i=2 class="simon element blast">Blast</div>
</div>
</div>
<div class="button-group">
<div data-i=3 class="simon element dodge">Dodge</div>
</div>
</div>
</div>
<div class="row bottom-row">
<div class="col-md-12 game-settings">
<div class="gameInfo bg-primary" style="color: white" id="restart"> Start</div>
<div class="gameInfo"> Mode: <span id="mode">Easy</span> </div>
<div class="gameInfo"> Input Count: <span id="in-count">0</span> </div>
<div class="gameInfo"> Turn: <span id="turn">Demo</span> </div>
<div class="gameInfo" id="diff"> Change Mode</div>
</div>
<hr>
<div id="separate">--------The Buttons Below are For Testing Purposes---------</div>
<div class="col-md-12 test-actions">
<button class="btn btn-primary test-action" data-p="0" data-a="0">Attack</button>
<button class="btn btn-primary test-action" data-p="0" data-a="1">Block</button>
<button class="btn btn-primary test-action" data-p="0" data-a="2">Blast</button>
<button class="btn btn-primary test-action" data-p="0" data-a="3">Dodge</button>
<button class="btn btn-primary test-action" data-p="0" data-a="4">Finish</button>
<br>
<button class="btn btn-default test-action" data-p="1" data-a="0">E. Attack</button>
<button class="btn btn-default test-action" data-p="1" data-a="1">E. Block</button>
<button class="btn btn-default test-action" data-p="1" data-a="2">E. Blast</button>
<button class="btn btn-default test-action" data-p="1" data-a="3">E. Dodge</button>
<button class="btn btn-default test-action" data-p="1" data-a="4">E. Finish</button>
</div>
<button class="btn btn-default" id="testButton"> Test Controls</button>
</div>
enter code here
</div>
Related
I have a card element that can be dragged from one column to another column. This works, except the card has a transparent dropzone element inside it that becomes opaque on Chrome browsers when dragging. This problem is not the case on Firefox or Safari.
You can see the code here.
How can I fix this problem on Chrome browsers?
I tried by playing with opacity and rgb() in css, but with no success. See the code below.
#board {
display: flex;
padding: 8px;
width: 800px;
}
#board * {
font-family: sans-serif;
}
.board__column {
flex: 1;
background: #fcb51d;
padding: 10px;
border-radius: 5px;
}
.board__column:not(:last-child) {
margin-right: 10px;
}
.board__column-title {
margin-bottom: 20px;
font-size: 30px;
color: white;
user-select: none;
}
.board__item-card {
box-sizing: border-box;
cursor: pointer;
background: white;
padding: 8px;
border-radius: 8px;
}
.board__item-input {
background: white;
padding: 10px 15px;
border-radius: 5px;
}
.board__dropzone {
height: 10px;
transition: background 0.15s, height 0.15s;
}
.board__dropzone--active {
height: 20px;
background: rgba(0, 0, 0, 0.25);
}
.board__add-item {
width: 100%;
padding: 10px 0;
font-size: 16px;
color: white;
background: rgba(0, 0, 0, 0.1);
border: none;
border-radius: 5px;
cursor: pointer;
}
<div id="board">
<!-- Todo's tasks -->
<div class="board__column">
<div class="board__column-title">Todo</div>
<div class="board__column-items">
<div class="board__card" draggable="true">
<div class="board__item-card">
My first todo task 🤓
</div>
<div class="board__dropzone"></div>
</div>
<div class="board__card" draggable="true">
<div class="board__item-card">
My second todo task...
</div>
<div class="board__dropzone"></div>
</div>
</div>
<button class="board__add-item" type="button">+ Add card</button>
</div>
<!-- In progress tasks -->
<div class="board__column">
<div class="board__column-title">In Progress</div>
<div class="board__column-items">
<div class="board__card" draggable="true">
<div class="board__item-card">
I'm working on the task 😁
</div>
<div class="board__dropzone"></div>
</div>
</div>
<button class="board__add-item" type="button">+ Add card</button>
</div>
<!-- Done tasks -->
<div class="board__column">
<div class="board__column-title">Done</div>
<div class="board__column-items">
<div class="board__item-card" draggable="true">
<div class="board__item-card">
I finished the task 😇
</div>
<div class="board__dropzone"></div>
</div>
</div>
<button class="board__add-item" type="button">+ Add card</button>
</div>
</div>
I Believe it is not the dropzone div element that is turning opaque, I believe that the board__card element being draggable forces it somehow to inherit the color of its parent, please check the following link:
Why HTML draggable element drags with parent background?
This a project from school that I've been working on but I'm facing some obstacles in the Sidebar button at the top left corner. The button is opening and showing a blank white page can someone help me out?
function open() {
document.getElementById("sidebar").style.display = "relative";
}
function close() {
document.getElementById("sidebar").style.display = "none";
}
#sidebar {
display: none;
height: 100%;
width: 10%;
background-color: #3c1642;
justify-self: left;
}
<nav id="navBar" class="menuBar">
<button onclick="open()" style="border: 0px; background-color: #272640;">
<div class="menuBar" >
<div class="menu-inner">
<span class="bar bar-1" id="br1"></span>
<span class="bar bar-2" id="br2"></span>
<span class="bar bar-3" id="br3"></span>
</div>
</div>
</button>
<div class="menuOptions" style="flex-grow: 5; border-right: 0px; align-self: left;">
</div>
<div id="head" class="menuOptions" style="flex-grow: 3; border-left: 0px; border-right: 0px; align-self: center;
justify-content: center; position: relative;">
WD BOOTCAMP
</div>
<div class="menuOptions" style="flex-grow: 3; justify-content: end; border-left: 0px; align-self: right; ">
<a class="menuBut" style=" border: 3px solid #f72585; border-top: 0px; border-bottom: 0px;"></a>
<a class="menuBut"></a>
<form action="" style="display: flex; justify-self: end; height: 30%; margin-top: 30px;">
<input type="text" id="searchBar" placeholder="search">
</form>
</div>
</nav>
<div id="sidebar">
<button onclick="close()">Close X</button>
link1
link2
link3
</div>
You have several things that need attention, but the primary two are:
You aren't specifying type="button" on your button elements, so
they default to acting like type="submit" and cause your form to
submit, but your form doesn't have a path for the action, so you
just get a blank page.
Unless you will be submitting data to another location, you shouldn't
even have a form element in the first place.
Beyond that, you should avoid inline styles whenever possible because they are the hardest styles to override and they lead to duplication of code and clutter up the code in general.
Avoid inline event attributes as well and hook up your elements to events in JavaScript with .addEventListener().
const sidebar = document.getElementById("sidebar");
sidebar.querySelector("button").addEventListener("click", function(){
sidebar.classList.add("hidden");
});
document.querySelector("button.butStyle1").addEventListener("click", function(){
sidebar.classList.remove("hidden");
});
#sidebar {
height: 100%;
width: 10%;
background-color: #3c1642;
justify-self: left;
}
/* Put styles that might need to be added/removed
in separate classes so that just that property
can be adjusted as needed. */
.hidden { display: none; }
/* Avoid inline styles whenever possible */
.menuOptions {
flex-grow: 3;
border-left: 0px;
border-right: 0px;
position: relative;
}
.flexStyles1 {
align-self: center;
justify-content: center;
}
.flexStyles2 {
align-self: right;
justify-content: end;
}
.butStyle1 { border: 0px; background-color: #e0e0e0; }
.form { display: flex; justify-self: end; height: 30%; margin-top: 30px; }
<nav id="navBar" class="menuBar">
<button type="button" class="butStyle1">
<div class="menuBar" >
<div class="menu-inner">
<span class="bar bar-1" id="br1">x</span>
<span class="bar bar-2" id="br2">y</span>
<span class="bar bar-3" id="br3">z</span>
</div>
</div>
</button>
<div class="menuOptions" style="flex-grow: 5; border-right: 0px; align-self: left;">
</div>
<div id="head" class="menuOptions flexStyles1">
WD BOOTCAMP
</div>
<div class="menuOptions flexStyles2">
<a class="menuBut" style=" border: 3px solid #f72585; border-top: 0px; border-bottom: 0px;"></a>
<a class="menuBut"></a>
<input type="text" id="searchBar" placeholder="search">
</div>
</nav>
<div id="sidebar" class="hidden">
<button type="button">Close X</button>
link1
link2
link3
</div>
So, I have a posting system. When you type a post in the input field and click the submit button, the post displays with the help of PHP and AJAX.
Now on that post are stuff like a like button and comment button, and when you click the like button, it turns blue. Now, after making a post and the post displaying, clicking the like button will make it blue. However, let's say you make another post. For that post, everything works, except when you click the like button on the second or third post, it makes the like button on the first post only turn blue, similarly with the comment button. Also, the first post has a background color of silver (#C0C0C0), however any other post, like the second or third post, don't. They have no background color.
This stuff (turning blue on click) is accomplished using JavaScript. What I identified from this is that the JS isn't working for any other post besides the first post. To resolve this, I tried changing the position of the JS in the code because I thought it had something to do with the scope, but it didn't. Please help, with the JS and the background color issue.
PHP/HTML/CSS Code:
<style>
.textPost {
margin-top: 170px;
width: 650px;
height: 400px;
position: fixed;
background-color: #C0C0C0;
margin-left: 685px;
border-radius: 15px;
}
.textpostFormat {
margin-left: -640px;
position: fixed;
}
</style>
<div class="textPost">
<?php
$sql = "SELECT * FROM posts";
$result = mysqli_query($connection, $sql);
if (mysqli_num_rows($result) > 0) {
while ($row = mysqli_fetch_assoc($result)) {
?>
<div class="textpostFormat" id="textpostFormat">
<img src="img/pfp.png" alt="pfp" onclick="location.href='profile.php'" class="textpostPFP">
<b><div class="textinfo"><?php echo $firstname . " " . $lastname ?></div></b>
<img src="img/options.png" alt="textpostOptions" class="textpostOptions">
<hr style="margin-top: 85px; width: 600px; position: fixed; margin-left: 663px; border:1px solid black; border-radius: 10px">
<hr style="margin-top: 200px; width: 600px; position: fixed; margin-left: 663px; border:1px solid black; border-radius: 10px">
<div class="textfeedbackBar" style="position: fixed">
<hr style="margin-top: 250px; width: 600px; position: fixed; margin-left: 663px; border: 1px solid black; border-radius: 10px">
<div class="textratingBar">
<div style="float: left; margin: 10px; cursor: pointer">1</div>
<hr style="width: 0px; height: 43px; float: left; margin-top: -2px; border: 1px solid black">
<div style="float: left; margin: 10px; cursor: pointer">2</div>
<hr style="width: 0px; height: 43px; float: left; margin-top: -2px; border: 1px solid black">
<div style="float: left; margin: 10px; cursor: pointer">3</div>
<hr style="width: 0px; height: 43px; float: left; margin-top: -2px; border: 1px solid black">
<div style="float: left; margin: 10px; cursor: pointer">4</div>
<hr style="width: 0px; height: 43px; float: left; margin-top: -2px; border: 1px solid black">
<div style="float: left; margin: 10px; cursor: pointer">5</div>
<hr style="width: 0px; height: 43px; float: left; margin-top: -2px; border: 1px solid black">
<div style="float: left; margin: 10px; cursor: pointer">6</div>
<hr style="width: 0px; height: 43px; float: left; margin-top: -2px; border: 1px solid black">
<div style="float: left; margin: 10px; cursor: pointer">7</div>
<hr style="width: 0px; height: 43px; float: left; margin-top: -2px; border: 1px solid black">
<div style="float: left; margin: 10px; cursor: pointer">8</div>
<hr style="width: 0px; height: 43px; float: left; margin-top: -2px; border: 1px solid black">
<div style="float: left; margin: 10px; cursor: pointer">9</div>
<hr style="width: 0px; height: 43px; float: left; margin-top: -2px; border: 1px solid black">
<div style="float: left; margin-left: 275px; cursor: pointer; margin-top: 10px; position: fixed">10</div>
</div>
</div>
<hr style="margin-top: 320px; width: 600px; position: fixed; margin-left: 663px; border: 1px solid black; border-radius: 10px">
<img src="img/pfp.png" alt="commentpfp" onclick="location.href='profile.php'" class="textcommentPFP">
<input type="text" name="textComment" class="textComment" id="textComment" placeholder="Write a comment">
<p style="margin-left: 670px; margin-top: 95px; position: fixed; font-size: 45px; font-family: 'Rajdhani'"><?php echo $row["body"]; ?></p>
<div class="textPostData" style="position:fixed; font-family: 'Rajdhani'; margin-left: 820px; margin-top: 150px">
<h4 id="textDataLikes" style="cursor: pointer">0 Likes</h4>
<h4 id="textDataComments" style="margin-left: 102px; margin-top: -42px; cursor: pointer">0 Comments</h4>
<h4 id="textDataReactions" style="margin-left: 240px; margin-top: -42px; cursor: pointer">0 Reactions</h4>
</div>
<div style="margin-left: 715px; position: fixed; font-family: 'Rajdhani'">
<h2 style="margin-top: 206px; margin-left: -30px; cursor:pointer; padding: 5px; position: fixed" class="textLike" id="textLike" onclick="textLikeClick()"><i class="fa fa-thumbs-up"></i> Like</h2>
<h2 style="margin-left: 99px; margin-top: 206px; cursor:pointer; padding: 5px; position: fixed" class="makeComment" id="makeComment" onclick="textCommentClick()"><i class="fa fa-comment" style="margin-top: 2px;"></i> Comment</h2>
<h2 style="margin-left: 290px; margin-top: 206px; cursor:pointer; padding: 5px; position: fixed" class="textReact" id="textReact"><i class="fa fa-smile" style="margin-top: 2px;"></i> React</h2>
<h2 style="margin-left: 432px; margin-top: 206px; cursor:pointer; padding: 5px; position: fixed" class="textShare" id="textShare"><i class="fa fa-share" style="margin-top: 2px"></i> Share</h2>
</div>
</div>
<div style="margin-left: 398px; margin-top: 236px">
<img class="textupvote" id="textUpvoteImg" src="img/upvote.png" alt="upvote" onclick="changetextUpvote()" style="width: 100px; margin-bottom: 28px; cursor: pointer">
<img class="textdownvote" id="textDownvoteImg" src="img/downvote.png" alt="downvote" onclick="changetextDownvote()" style="width: 55px; margin-top: 32px; margin-left: 21px; position: fixed; cursor: pointer">
</div>
<?php
}
}
?>
</div>
<?php
}
}
?>
</div>
AJAX code (to display posts without page refresh):
function makePost() {
var postContent = $("#postContent").val();
if (postContent.length > 0) {
jQuery.ajax({
url:"yourposts.php",
data:{
postContent: postContent
},
type:"POST",
success:function(data){
if (data == "success") {
$("#textpostFormat").html(postContent);
}
}
});
}
}
Javascript code (for turning like button blue and stuff):
<script type="text/javascript">
function changetextUpvote() {
var textUpvoteImg = document.getElementById('textUpvoteImg');
if (textUpvoteImg.src.match("orangeupvote")) {
textUpvoteImg.src = "img/upvote.png";
} else {
textUpvoteImg.src = "img/orangeupvote.png";
textDownvoteImg.src = "img/downvote.png";
}
}
function changetextDownvote() {
var textDownvoteImg = document.getElementById('textDownvoteImg');
if (textDownvoteImg.src.match("orangedownvote")) {
textDownvoteImg.src = "img/downvote.png";
} else {
textDownvoteImg.src = "img/orangedownvote.png";
textUpvoteImg.src = "img/upvote.png";
}
}
function textLikeClick() {
document.getElementById('textLike').style.color = "blue";
}
function textCommentClick() {
document.getElementById('textComment').focus();
}
</script>
None of the elements here have an ID attribute. Identification of elements is done based upon inspecting the event.target and navigating around the DOM using querySelector, parentNode and perhaps other techniques such as nextElementSibling etc
The buttons all register a single eventlistener which forks logic based upon a data-set attibute.
document.querySelectorAll('[type="button"]').forEach(bttn=>bttn.addEventListener('click',function(e){
let img=this.parentNode.querySelector('img');
let text=this.parentNode.querySelector('textarea');
switch(this.dataset.action){
case 'upvote':
img.src='img/orangeupvote.png';
img.classList.toggle(this.dataset.action)
break;
case 'downvote':
img.src='img/orangedownvote.png';
img.classList.toggle(this.dataset.action)
break;
case 'comment':
text.focus();
let fd=new FormData();
fd.set('comment',text.value);
fetch('yourposts.php',{method:'post',body:fd})
.then(r=>r.text())
.then(text=>{alert(text)})
break;
case 'like':
this.classList.toggle('liked')
break;
}
}));
.liked{background:blue;color:white}
textarea:focus{background:pink}
.upvote{outline:2px solid green}
.downvote{outline:2px solid red}
<div class="textPost">
<!--
<?php
$sql = "SELECT * FROM posts";
$result = mysqli_query($connection, $sql);
if (mysqli_num_rows($result) > 0) {
while ($row = mysqli_fetch_assoc($result)) {
?>
-->
<h1>Example data</h1>
<div class="textpostFormat">
<p>Lorem ipsum dolor solit...etc #1</p>
<img />
<input type='button' class='usr-interaction' data-action='upvote' value='Upvote' />
<input type='button' class='usr-interaction' data-action='downvote' value='Downvote' />
<textarea cols=50 rows=5>This is simply a comment...</textarea>
<input type='button' class='usr-interaction' data-action='comment' value='Comment' />
<input type='button' class='usr-interaction' data-action='like' value='Like' />
</div>
<div class="textpostFormat">
<p>Lorem ipsum dolor solit...etc #2</p>
<img />
<input type='button' class='usr-interaction' data-action='upvote' value='Upvote' />
<input type='button' class='usr-interaction' data-action='downvote' value='Downvote' />
<textarea cols=50 rows=5>Also a simple comment...</textarea>
<input type='button' class='usr-interaction' data-action='comment' value='Comment' />
<input type='button' class='usr-interaction' data-action='like' value='Like' />
</div>
<div class="textpostFormat">
<p>Lorem ipsum dolor solit...etc #3</p>
<img />
<input type='button' class='usr-interaction' data-action='upvote' value='Upvote' />
<input type='button' class='usr-interaction' data-action='downvote' value='Downvote' />
<textarea cols=50 rows=5>Guess what this is...</textarea>
<input type='button' class='usr-interaction' data-action='comment' value='Comment' />
<input type='button' class='usr-interaction' data-action='like' value='Like' />
</div>
</div>
Stripping all the hideous inline styles and replacing ID attributes with, in this case, simply data-id attributes to yield some example rendered markup like this below. This is NOT intended to be a final solution for you - you need to understand how you fit your functions within this because quite frankly the code given is chaotic.
within the click handler function if you supply the event as an argument to the function you can access event.target within the function. That event.target points to the element that initiated the click. From that point you can use DOM navigation techniques to find other nodes of interest.
document.querySelectorAll('.textpostFormat *[data-id]').forEach(n=>n.addEventListener('click',function(e){
switch( this.dataset.id ){
case 'textUpvoteImg':
changetextUpvote(e);
break;
case 'textDownvoteImg':
changetextDownvote(e)
break;
case 'makeComment':
textCommentClick(e);
break;
case 'textLike':
textLikeClick(e);
break;
}
}));
function changetextUpvote(e) {
alert(e.target)
}
function changetextDownvote(e) {
alert(e.target)
}
function textLikeClick(e) {
alert(e.target)
}
function textCommentClick(e) {
alert(e.target)
}
<div class='textpostFormat'>
<a href='profile.php'><img src='img/pfp.png' alt='pfp' class='textpostPFP'></a>
<div class='textinfo'><b>FIRSTNAME LASTNAME #1</b></div>
<img src='img/options.png' class='textpostOptions' />
<div class='textfeedbackBar'>
<div class='textratingBar'>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
<div>10</div>
</div>
</div>
<a href='profile.php'><img src='img/pfp.png' alt='commentpfp' class='textcommentPFP' /></a>
<input type='text' name='textComment' class='textComment' data-id='textComment' placeholder='Write a comment' />
<p>PARAGRAPH - BODY CONTENT #1</p>
<div class='textPostData'>
<h4 data-id='textDataLikes'>0 Likes</h4>
<h4 data-id='textDataComments'>0 Comments</h4>
<h4 data-id='textDataReactions'>0 Reactions</h4>
</div>
<div>
<h2 class='textLike' data-id='textLike'><i class='fa fa-thumbs-up'></i> Like</h2>
<h2 class='makeComment' data-id='makeComment'><i class='fa fa-comment' style='margin-top: 2px;'></i> Comment</h2>
<h2 class='textReact' data-id='textReact'><i class='fa fa-smile' style='margin-top: 2px;'></i> React</h2>
<h2 class='textShare' data-id='textShare'><i class='fa fa-share' style='margin-top: 2px'></i> Share</h2>
</div>
<div>
<img class='textupvote' data-id='textUpvoteImg' src='img/upvote.png' alt='upvote' />
<img class='textdownvote' data-id='textDownvoteImg' src='img/downvote.png' alt='downvote' />
</div>
</div>
<div class='textpostFormat'>
<a href='profile.php'><img src='img/pfp.png' alt='pfp' class='textpostPFP'></a>
<div class='textinfo'><b>FIRSTNAME LASTNAME #2</b></div>
<img src='img/options.png' class='textpostOptions' />
<div class='textfeedbackBar'>
<div class='textratingBar'>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
<div>10</div>
</div>
</div>
<a href='profile.php'><img src='img/pfp.png' alt='commentpfp' class='textcommentPFP' /></a>
<input type='text' name='textComment' class='textComment' data-id='textComment' placeholder='Write a comment' />
<p>PARAGRAPH - BODY CONTENT #2</p>
<div class='textPostData'>
<h4 data-id='textDataLikes'>0 Likes</h4>
<h4 data-id='textDataComments'>0 Comments</h4>
<h4 data-id='textDataReactions'>0 Reactions</h4>
</div>
<div>
<h2 class='textLike' data-id='textLike'><i class='fa fa-thumbs-up'></i> Like</h2>
<h2 class='makeComment' data-id='makeComment'><i class='fa fa-comment' style='margin-top: 2px;'></i> Comment</h2>
<h2 class='textReact' data-id='textReact'><i class='fa fa-smile' style='margin-top: 2px;'></i> React</h2>
<h2 class='textShare' data-id='textShare'><i class='fa fa-share' style='margin-top: 2px'></i> Share</h2>
</div>
<div>
<img class='textupvote' data-id='textUpvoteImg' src='img/upvote.png' alt='upvote' />
<img class='textdownvote' data-id='textDownvoteImg' src='img/downvote.png' alt='downvote' />
</div>
</div>
I am trying to add a listener to a small button like div so I can eventually change the color once clicked without having to use an actual button for different reasons. I have seen multiple people on here say that it works or should work. Is there something I am missing or is it just not possible? Just looking for answers!
It's pretty simple and I have verified the button works with the same function.
//this is the entire js page at the moment
var WorkingOutManager = (function () {
this.setCounter = 1;
this.workoutCounter = 1;
this.workoutID = "workout" + workoutCounter + "_set" + setCounter;
this.changeState = () => {
//I will eventually add the code to change the state of the div
console.log(this.workoutID);
}
this.currentSetButton = document.getElementById(this.workoutID).
this.currentSetButton.addEventListener("click", this.changeState);
return {
changeState: changeState
}
})();
<body>
<div id="banner">
<a id="banner_text_link" href="../content/home.html">Work It Out</a>
</div>
<div id="wrapper">
<div>
<img id="page_image"
onclick="window.location.href='../content/home.html'"
src="../images/work_it_out_logo_workouts.png" alt="Work It
Out logo">
</div>
<!--Eventually, Display a Timer after pressing start -->
<div id="current_workout">
<div class="workout_exercise">
<div class="set_name">Pushups</div>
<div onclick="WorkingOutManager.changeState()"
class="set_exercise" id="workout1_set1">15</div>
<div class="set_exercise" id="workout1_set2">15</div>
<div class="set_exercise" id="workout1_set3">15</div>
<div class="set_exercise" id="workout1_set4">15</div>
</div>
<div class="workout_exercise">
<div class="set_name">Situps</div>
<div class="set_exercise" id="workout2_set1">TF</div>
<div class="set_exercise" id="workout2_set2">TF</div>
<div class="set_exercise" id="workout2_set3">TF</div>
<div class="set_exercise" id="workout2_set4">TF</div>
</div>
<div class="workout_exercise">
<div class="set_name">Pullups</div>
<div class="set_exercise" id="workout3_set1">TF</div>
<div class="set_exercise" id="workout3_set2">TF</div>
<div class="set_exercise" id="workout3_set3">TF</div>
<div class="set_exercise" id="workout3_set4">TF</div>
</div>
<button onclick="WorkingOutManager.changeState()"
id="add_exercise">COMPLETE WORKOUT</button>
</div>
</div>
<script src="../scripts/working_out.js"></script>
</body>
#current_workout {
color: rgb(48, 48, 48);
width: 100%;
height: auto;
}
.workout_exercise {
background-color: #c4c4c4;
height: 3rem;
width: auto;
align-content: center;
}
.set_name {
color: #fafafa;
float: left;
height: 100%;
padding: 0 0.2rem;
width: calc(30% - 0.4rem);
text-align: center;
vertical-align: center;
line-height: 3rem;
/* border-style: outset; */
background-color: #c4c4c4;
font-size: 1.6rem;
font-family: Impact, Haettenschweiler, "Arial Narrow Bold", sans-serif;
}
.set_exercise {
float: right;
width: calc(calc(70% / 4) - 0.2rem);
height: 100%;
padding: 0 0.1rem;
margin: 0 0.1rem;
border-radius: 50%;
/* transform: rotate(-25deg);
text-transform: rotate(25deg); */
text-align: center;
vertical-align: center;
line-height: 3rem;
/* border-style: outset; */
background-color: #fafafa;
}
I am not receiving any error messages when I click on the div with the onClick listener. Nothing happens at all, in fact. The button at the bottom of the "current_workout" div works properly and logs the correctly formatted "workoutID."
It works for me if I change the '.' at the end of this line to a semicolon:
this.currentSetButton = document.getElementById(this.workoutID).
Because you're using float: right on .set_exercise, the items are listed from right to left instead of left to right. The clickable item, workout1_set1 is at the right end of the row, not the left. My guess is that you've been clicking the wrong item. I've tweaked your css to highlight the clickable item in the snippet below.
(The handler is firing twice because you've also got an onclick attribute on the div.)
FWIW—I'm not going to tell you how to do your thing—but I see no good reason to use float here (or anywhere at all, ever, really). You could achieve this layout with flexbox, grid, or a table and avoid all of the headaches that come with floats. (I don't usually advocate for tables, but one could argue that this is a table.)
var WorkingOutManager = (function () {
this.setCounter = 1;
this.workoutCounter = 1;
this.workoutID = "workout" + workoutCounter + "_set" + setCounter;
this.changeState = () => {
//I will eventually add the code to change the state of the div
console.log(this.workoutID);
}
this.currentSetButton = document.getElementById(this.workoutID);
this.currentSetButton.addEventListener("click", this.changeState);
return {
changeState: changeState
}
})();
#current_workout {
color: rgb(48, 48, 48);
width: 100%;
height: auto;
}
.workout_exercise {
background-color: #c4c4c4;
height: 3rem;
width: auto;
align-content: center;
}
.set_name {
color: #fafafa;
float: left;
height: 100%;
padding: 0 0.2rem;
width: calc(30% - 0.4rem);
text-align: center;
vertical-align: center;
line-height: 3rem;
/* border-style: outset; */
background-color: #c4c4c4;
font-size: 1.6rem;
font-family: Impact, Haettenschweiler, "Arial Narrow Bold", sans-serif;
}
.set_exercise {
float: right;
width: calc(calc(70% / 4) - 0.2rem);
height: 100%;
padding: 0 0.1rem;
margin: 0 0.1rem;
border-radius: 50%;
/* transform: rotate(-25deg);
text-transform: rotate(25deg); */
text-align: center;
vertical-align: center;
line-height: 3rem;
/* border-style: outset; */
background-color: #fafafa;
}
#workout1_set1 {
background: red;
color: white;
font-weight: bold;
}
<div id="banner">
<a id="banner_text_link" href="../content/home.html">Work It Out</a>
</div>
<div id="wrapper">
<div>
<img id="page_image"
onclick="window.location.href='../content/home.html'"
src="../images/work_it_out_logo_workouts.png" alt="Work It
Out logo">
</div>
<!--Eventually, Display a Timer after pressing start -->
<div id="current_workout">
<div class="workout_exercise">
<div class="set_name">Pushups</div>
<div onclick="WorkingOutManager.changeState()"
class="set_exercise" id="workout1_set1">15</div>
<div class="set_exercise" id="workout1_set2">15</div>
<div class="set_exercise" id="workout1_set3">15</div>
<div class="set_exercise" id="workout1_set4">15</div>
</div>
<div class="workout_exercise">
<div class="set_name">Situps</div>
<div class="set_exercise" id="workout2_set1">TF</div>
<div class="set_exercise" id="workout2_set2">TF</div>
<div class="set_exercise" id="workout2_set3">TF</div>
<div class="set_exercise" id="workout2_set4">TF</div>
</div>
<div class="workout_exercise">
<div class="set_name">Pullups</div>
<div class="set_exercise" id="workout3_set1">TF</div>
<div class="set_exercise" id="workout3_set2">TF</div>
<div class="set_exercise" id="workout3_set3">TF</div>
<div class="set_exercise" id="workout3_set4">TF</div>
</div>
<button onclick="WorkingOutManager.changeState()"
id="add_exercise">COMPLETE WORKOUT</button>
</div>
</div>
#you {
background-color: rgba(65,64,61,0.5);
position: absolute;
top: 0px;
right: 200px;
padding: 7px;
border-radius: 0px 0px 3px 3px;
width: 165px;
border: 2px solid #41403d;
}
#exitb {
background: url(http://playneko.co.uk/exit.png);
height: 19px;
width: 19px;
border-radius: 3px;
}
#exitb:hover {
background: url(http://playneko.co.uk/exit_hover.png);
}
Thats my css code andd this is the box I have
<div id="you">
<div style="height: 110px; width: 57px; float: left; overflow: hidden;">
<img src="http://www.habbo.nl/habbo-imaging/avatarimage?figure='.$user['look'].'&direction=3&head_direction=3&action=wav,crr=667&size=m" alt="avatar" class="rotate" align="left">
</div>
<div style="position: absolute; z-index:1">'.$aanwezag.'</div>
<br/>
</td>
<div style="cursor:pointer;position:absolute;top:10px;left:65px;font-size:18px;font-family: Times;">%habboName%</div>
<div style="cursor:pointer;position:absolute;top:30px;left:65px;font-size:18px;font-family: Times;">' . $users->getRankName($user['rank']) . '</div>
<div style="cursor:pointer;position:absolute;top:50px;left:65px;font-size:18px;font-family: Times;"><font color="#FF0040">'. $user['age'] .' Years Old</font></div>
<div style="cursor:pointer;position:absolute;top:70px;left:65px;font-size:18px;font-family: Times;"><font color="#088A4B">'. $user2['AchievementScore'] .' Score</font></div>
<div style="cursor:pointer;position:absolute;top:90px;left:65px;font-size:18px;font-family: Times;"><font color="#01A9DB">'. $user2['Respect'] .' Respects</font></div>
<div style="cursor:pointer;position:absolute;top:81px;left:5px;font-size:20px;font-family: Times;"><img src="%www%/flags/'. $user['country'] .'.png"></div>
</div>
How would I add the exit image on the right of the box to be able to minimize and maximise the box? if you can help it would be greatly appreciated.
For example, you have to wrap a content which should toggle into a separate div and toggle this div instead of whole #you element
<div id="you">
<div id="exitb">-</div>
<div id=content>
...
</div>
</div>
$("#content").slideToggle();
https://jsfiddle.net/Qy6Sj/1602/
I'm not quite sure if this is what you wanted or not. I have moved the #exitb id out of the #you wrapper and positioned it as absolute as well in order to move it into the image. Moreover, I simplified the code a little bit to use just a text, + and -, instead of image icons.
HTML:
<div id="exitb">-</div>
<div id="you">
...
</div>
Javascript:
$("#exitb").click(function () {
if ($(this).html() == "-") {
$(this).html("+");
} else {
$(this).html("-");
}
$("#you").slideToggle();
});
CSS:
#exitb {
text-align: center;
color: #fff;
background-color: red;
height:19px;
width:19px;
border-radius:3px;
cursor: point;
position:absolute;
top:0px;
right:200px;
z-index: 10;
cursor: pointer;
}
JsFiddle.