Jquery change when JS variable changes not working - javascript

I'm trying to make a game where you click a button to earn a point. Once you obtain X amount of points a div appears. I tired using jquery's .change to see if #pointCounter has changed in order to know if the new div should appear (by adding the new class). This isn't working though. Am I not using the change method correctly, or should I use something else? Is there a to check when the var points changes instead of checking if the html changes?
HTML
<p>You have <span id='pointCounter'>0</span> points.</p>
<button id='clickButton'>Click Me</button>
<div id='store'></div>
JS
$('#clickButton').click(function() {
points = points + addPoints;
$('#pointCounter').html(points);
});
$('#pointCounter').change(function() {
if (points >= 5) {
$('#store').addClass('showMe');
}
});

Is it not possible to display the div at this point:
$('#clickButton').click(function() {
points = points + addPoints;
if (points > 500) $('#someDIV').addClass('showme');
$('#pointCounter').html(points);
});

Change is just for selects or other form elements as j08691 said but you could do something like this, right now I just have points set as a global var but you could also pass a value into the function to increment the points value.
See it in action: http://jsfiddle.net/1j33tm0g/1/
var points = 0;
var addPoints = 1;
$('#clickButton').click(function() {
points += addPoints;
$('#pointCounter').html(points);
if(points >= 5) {
$('#store').addClass('showMe');
}
});

I would go with jQuery hide/show:
<p>You have <span id='pointCounter'>0</span> points.</p>
<button id='clickButton'>Click Me</button>
<div id='store'>Test</div>
And using the JS:
var points = 0;
var addPoints = 1;
$("#store").hide();
$('#clickButton').click(function() {
points = points + addPoints;
$('#pointCounter').html(points);
if (points >= 5) {
$('#store').show();
}
});
Here: http://jsfiddle.net/rnm9e5vh/

Related

onclick event in a for loop certain amount of times

I thought that this onClick event in a For loop would help me but when I tried it, it still didn't work.
I am making a simple Battleship game, and while I'm trying to have the user click on only 4 squares to place on ship, the loop keeps going and doesn't stop after 4 tries. I have my onclick even handler in a for loop, but after 4 tries it doesn't stop. I've tried adding a count variable after the end, and even tried adding a break statement but can't get it to work.
Here's my code:
function placeShips() {
var playerTable = document.getElementById("mainPlayer");
var playerCells = playerTable.getElementsByTagName("td");
var count = 1;
alert("Please place the first ship. Click on 4 squares.");
while (count <= 4) {
for (i = 0; i < playerCells.length; i++) {
playerCells[i].onclick = placeBattleship;
}
count++;
}
}
The placeBattleship function contains the code to change the grid square to a background color of red to mark it. My problem is that once the user clicks 4 squares, you can keep going and click on more and more. I can't get the above for loop that calls the placeBattleship function to stop after the user clicks on 4 squares. I've tried putting it in a while loop, and even the solution in the above link, as well as moving the assignment of count, but can't get it to stop after x amount of times (in this case, 4).
Any ideas on what I'm doing wrong, or a better way to do it?
Wouldn't you consider to use jQuery?
Look your function much shorter:
function placeShips() {
$("td:lt(4)").click(placeBattleship);
}
You can testify on the code below:
<table>
<tr>
<td>1.1</td><td>2.1</td>
</tr>
<tr>
<td>1.2</td><td>2.2</td>
</tr>
<tr>
<td>1.3</td><td>2.3</td>
</tr>
</table>
<div id="console"></div>
<script>
$("td:lt(4)").each(function(){
$("#console").append("Content of "+ $(this).html() + "<br/>");
});
$("td:lt(4)").click(function(){
$("#console").append("Clicking "+ $(this).html() + "<br/>");
});
</script>
...or on my Plunker: https://plnkr.co/edit/yNZw6ZhkNfA9E0NdQg7V
So, now we have a solution that stop for 4th click on the squares:
function placeBattleship() {
var $shipDisplay = $("#shipDisplay");
var counter = $shipDisplay.data("counter");
if(counter++ < 4) {
$(this).css("background-color", "red");
$shipDisplay.data("counter", counter);
}
}
function placeShips() {
$("td").click(placeBattleship);
}
$(document).ready(function(){
placeShips();
});
I use a div with id shipDisplay to store a data-attribute for count the clicks.
Look at the plunker: http://plnkr.co/edit/PEba15PSLv2LK6qjY7AD?p=preview
You should separate priorities in your logic and removeEventListener when counter hits 4 , hopefully this helps you :
//defined outside the function
var counter = 0;
playerCells.addEventListener("click" , placeShips );
Then
function placeShips() {
if(counter <= 4){
//Move ship
placeBattleship();
//add to counter
counter++
}else{
//Remove click event if counter reaches 4 .
playerCells.removeEventListener("click" , doSomethingElse)
}
}
You question needs a bit clarification. To my current understanding, you need to move the checking of count to placeBattleship.
What you are doing is binding click to same tds 4 times, not limiting the number of event triggering to 4 times.
// pseudo code
var count = 4; // this is global
var currentCount = 0;
initFunc() {
// bind click events ONCE
}
startPlacing() {
// accept user click and place ship
// set currentCount to zero
}
placeShip() {
// the callback of user `click`
// check for currentCount == count then move on (no more placement)
// increase currentCount by 1
// place ship
}
Note that after an event is triggered, the listener will not be removed. Until you removeEventListener() from it, it will always be listening.

Looping inside jQuery function only issue

I'm having some trouble with jQuery in Meteor - I'm just trying to learn so I hope someone could help.
So when #addButton is clicked it will append the div to the .formField and each div created on click will have an unique class, eg formField[1], formField[2] etc
The trouble is when the button is clicked instead of just changing the name of the div only, the div is also added 50 times. I know how dumb it sounds as its a loop, but how would I loop only the div's class on click so each have a different name?
My code is below:
Template.form.events({
'click #addButton': function(event) {
var i;
for (i = 0; i < 50; i++) {
$(".formField").append('<div class="formField['+i+']">.....</div>');
}
return false;
If I understand what you are doing here you don't need a loop. You just need a variable to increment every time the button is clicked. Take your append out of the loop and instead on click increment your variable by one then call an append. No loop necessary.
var i = 0;
Template.form.events({
'click #addButton': function(event) {
i += 1;
$(".formField").append('<div class="formField['+i+']">.....</div>');
}
});
return false;
Do it like this, (i.e. by creating a closure), click run to verify
var uuid = 0;
$('#addButton').on('click', function (event) {
uuid = uuid + 1;
$(".formField").append('<div class="formField[' + uuid + ']">Form' + uuid + '</div>');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="formField"></div>
<input type="button" value="Add New" id="addButton"></input>

Get total of all data attribute values

I am dynamically loading some of the content within my page and would like to get a total of all the data-attributes.
First the elements are cloned and appended
$('.chip').on('click', function () {
$(this).clone().appendTo('.chipPlacement');
});
Then I have written a function that should get the totals
function chipsBet() {
var redchip = $('.chipPlacement .chipValue.r').data() || 0;
var bluechip = $('.chipPlacement .chipValue.b').data() || 0;
var orangechip = $('.chipPlacement .chipValue.o').data() || 0;
var total = redchip.chipValue + bluechip.chipValue + orangechip.chipValue;
return total;
}
Before I append the elements the HTML looks like
<div class="chipPlacement"></div>
and once appended the HTML structure is
<div class="chipPlacement">
<div class="chip red">
<div class="chipValue r" data-chip-value="1">1</div>
</div>
</div>
I need to listen for the DOM structure the change and then fire the chipsBet() function, but I'm not sure how to get this to work. I can't use .on('change') as that only applies to input, textarea and select.
I have tried firing the chipsBet function within the .chip.on('click') but I get NaN returned.
How can I get the data-attribute-values for the new elements in the DOM?
If you don't have a blue or orange chip, you're effectively trying to get .chipValue from 0 which is undefined and adding it to another number gives you NaN.
You can simply iterate over all .chipValue elements within the placement element like so:
function chipsBet()
{
var total = 0;
$('.chipPlacement .chipValue').each(function() {
total += $(this).data('chipValue');
});
return total;
}
Nevermind, you altered your initial question.. carrying on.
<div class='chipPlacement'>
<div class='chip red'>
<div class='chipValue' data-chip-value='1'></div>
</div>
</div>
Then to read your data attributes, you could do something like this.
$('.chip').on('click', function () {
$(this).clone().appendTo('.chipPlacement');
chipsBet();
});
function chipsBet() {
var redchipVal = parseInt($('.chipValue .r').data('chip-value')) || 0;
var bluechipVal = parseInt($('.chipValue .b').data('chip-value')) || 0;
var orangechipVal = parseInt($('.chipValue .o').data('chip-value')) || 0;
var total = redchipVal + bluechipVal + orangechipVal;
return total;
}
I think you want something like bellow. It will call the function every time any change will in div .chipPlacement.
$('.chipPlacement').bind("DOMSubtreeModified",function(){
console.log('Div modified');
});
You can say for your problem
$('.chipPlacement').bind("DOMSubtreeModified",function(){
chipsBet();
});
DEMO

Create a child div accordingly if another child already exists at that location (x,y)

I am inserting a textarea to a side bar (exactly on the right to), wherever a click is made on the page. The code is:
$('#page_to_be_clicked').click(function(e){
var offset = $(this).offset();
var comment_box_y_coord = e.pageY - offset.top;
alert(comment_box_y_coord);
$("#sidebar").append('<textarea id="cmmnt" rows="4" cols="10" '+
'style="position:absolute;top:'+comment_box_y_coord +
'px;left:5px"></textarea>');
})
The problem with this is that, if a textarea is already present at the location, it will overlap the existing, i.e. if a click is made twice at the same point on the page, then two textareas are created on top of each other. Instead, it should be created one below the other.
Is there a way to check, if a child already exists at the required co-ordinates?
Any help will be appreciated. Thanks.
How exactly should the textareas appear on clicks in a sequence:
This needs to be tested properly, but I think you need to do this:
DEMO
In your function change this line:
var comment_box_y_coord = checkCoords(e.pageY - offset.top);
and then add this function:
function checkCoords(y) {
if ($("textarea").length>0) {
$ts = $("textarea");
for (var i = 0; i<$ts.length;i++) {
var $ti = $ts.eq(i),
tcoords = [$ti.offset().top, $ti.offset().top+$ti.height()]
if (y>=tcoords[0] && y <= tcoords[1]) {
y = tcoords[1]+3;
}
}
}
return y;
}

How to use jQuery event in sequence

I am trying to play around with learning jQuery and have made the following jsFiddle:
http://jsfiddle.net/jkNK3/
The idea is to have a div's color change on click. Fine, I got that but I am wondering if there is a way to have the div's color change through multiple classes changes, perhaps with some sort of array or loop. Let me explain.
I have created several CSS classes like so:
.color1 {..}
.color2 {..}
.color3 {..}
.color4 {..}
.color5 {..}
.color6 {..}
and am wondering if we can do something like
addClass("color" + i)
where i can be looped through 1 - 6.
Is there any way to accomplish this? Thanks for the help.
This is a good place to consider the danger of global javascript namespaces. Here's a simple example that takes advantage of closures to avoid that with jquery:
$(function() {
var numb = 1;
// this bit of managing the color state swap is another topic for discussion, so keeping it simple
var colors_len = 6;
$("div").click(function() {
// this closure has access to the numb variable
if (numb < colors_len) {
numb++;
$(this).addClass("color" + numb);
$(this).removeClass("color" + (numb-1));
} else {
numb = 1;
$(this).removeClass("color" + colors_len);
$(this).addClass("color" + numb);
}
});
});
http://jsfiddle.net/2taH5/
ps. Jquery ui also has a swap class method but that is more for animations
In my opinion the easiest would be to just store the color number in jQuery's handy data(), and then increment it from that:
function fnClick() {
var numb = $(this).data('color') || 2;
$(this).addClass("color" + numb).data('color', ++numb)
}
FIDDLE
To make it go back to the first color after the last color etc
function fnClick() {
var numb = $(this).data('color') || 2;
numb = numb == 7 ? 1 : numb;
$(this).removeClass().addClass("color" + numb).data('color', ++numb)
}
FIDDLE
How about using a random number to give a random color to the div.
var classCount = 6;
$(document).ready(function () {
$("div").on("click", fnClick);
});
function fnClick(e) {
// Get the currently clicked element
var $this = $(e.target),
className = 'color' + Math.floor((Math.random() * classCount )+1);
// Remove the exixting class/s
$this.removeClass();
// Add the class
$this.addClass(className);
}
Check Fiddle

Categories