Looping through removing and adding object attributes - javascript

I have a function passing me an instance in which im tryin to display 4 different html elements and only 1 can be visible at a time.
function(instance, context) {
var blank = $('#blank');
var good = $('#good');
var mediocre = $('#mediocre');
var bad = $('#bad');
instance.canvas.append(blank);
}
Then another function passing me updated values. But this loop only works for the very first iteration and I cannot figure out why
function(instance, properties, context) {
var strength = properties.strength;
var red = properties.red_shows_until;
var yellow = properties.yellow_shows_until
if (strength > 0 && strength < red) {
blank.remove();
instance.canvas.append(bad);
} else if (strength >= red && strength < yellow) {
bad.remove();
instance.canvas.append(mediocre);
} else if (strength >= yellow) {
yellow.remove();
instance.canvas.append(good);
} else {
good.remove();
instance.canvas.append(blank);
}
}

Related

Subtract an image that is representing a life in a game

Im try to code a mini game.
The game has two boxes you can click on. The boxes are assigned a random number between 1 and 2.
When the game starts, you have 5 lives. These lives are represented as 5 pictures of a small human.
When the player gets 3,5 and 7 correct points you get a extra life. Which i have achieved.
Now im trying to subtract a life everytime the player clicks on the wrong box.
function setRandomNumber() {
randomNumber = Math.floor(Math.random() * 2 + 1);
if (randomNumber === 1) {
numberOfRightAnswersSpan.innerHTML = `${++correctNumber}`;
outputDiv.innerHTML = `Det er riktig svar.`;
if (correctNumber === 3 || correctNumber === 5 || correctNumber === 7) {
numberOfLivesDiv.innerHTML += `<img src="images/person1.jpg"/>`
}
} else {
numberOfWrongAnswersSpan.innerHTML = `${++wrongNumber}`;
outputDiv.innerHTML = `Det er feil svar.`;
}
}
I made a few changes to your code, but tried to keep it fairly similar to your original. I changed your template literals to strings. I changed your .innerHTML modifications to .innerText modifications. I refactored some whitespace to make your if statement more readable. Instead of adding the img element by appending the html string, I used the .appendChild method and createElement method to make the img elements. I also added a class to the element to make it easier to grab later.
function setRandomNumber() {
randomNumber = Math.floor(Math.random() * 2 + 1);
if (randomNumber === 1) {
numberOfRightAnswersSpan.innerText = ++correctNumber;
outputDiv.innerText = "Det er riktig svar.";
if (
correctNumber === 3 ||
correctNumber === 5 ||
correctNumber === 7
) {
const newLife = document.createElement("img");
newLife.src = "images/person1.jpg";
newLife.classList.add("life");
numberOfLivesDiv.appendChild(newLife);
}
} else {
numberOfWrongAnswersSpan.innerText = ++wrongNumber;
outputDiv.innerText = "Det er feil svar.";
const aLife = document.querySelector(".life");
aLife.remove();
}
}
It is important to note at this point there is not logic to check for how many life exists, or what to do when lives run out. Eventually you may hit an error because there is not element with a class of life.
I would re-render the lives every time the number of lives changes.
let number_of_lives = 5;
const lives_container = document.getElementById("user-lives");
function draw_lives(){
lives_container.innerHTML = "";
for(let i = 0; i < number_of_lives; i++){
const img = document.createElement("img");
img.setAttribute("alt", "life.png");
const new_life = img;
lives_container.appendChild(new_life);
};
if(number_of_lives <= 0) lives_container.innerText = number_of_lives;
};
function remove_life() {
number_of_lives--;
draw_lives();
};
function add_life() {
number_of_lives++;
draw_lives();
};
draw_lives();
#user-lives > * {
margin: 10px;
background: #7f7;
}
<div id="user-lives"></div>
<button onclick="add_life();">Add life</button>
<button onclick="remove_life();">Remove life</button>

Compare array items with HTML dataset with pure Javascript?

Using Jquery you can do:
array[0].data('id') == array[1].data('id')
and compare 2 items in an same array by their HTML dataset (in this case it's data-id="1"). Is there a way to do it with pure Javascript???
This is HTML. It's a list of images.
<li class="card" data-id="1"><img src="images/labrys.svg" alt=""></li>
<li class="card" data-id="2"><img src="images/laurel.svg" alt=""></li>
....and so on
This is JS:
let cardArray = []; //Empty Array for selected cards
cards.addEventListener("click", function (e) {
e.preventDefault();
if (e.target.nodeName==="LI"){ // If a list element is hit...
const data = e.target.dataset.id; //checking
console.log(data);
cardArray.push(e.target); //Place current card into array...
var hit = cardArray[0].dataset.id;
var hot = cardArray[1].dataset.id;// throws error
console.log (hit);
console.log (hot);
}
I am trying to do this:
var match = cardArray[0].dataset.id=== cardArray[1].dataset.id;
This project is a memory game:
https://github.com/StamatisDeli/memory-game.github.io
You have to check how many items are in the array before accessing their index.
I believe that you are trying to avoid duplicating items when the user selects a particular card multiple times through click events. if that is what you are trying to achieve, You will be facing two scenerio.
first is to make sure that the listener function does not misbehave on multiple clicks.
second is to implement a binary search algorithm to help locate items easily rather than iterating through the items one after the other during searching. the id is a great stuff to use in sorting the list items.
var processing = false, //used to handle radical click event triggers
cardArray = [];
//note, it is better to add your event listener, to the card container `ul`
//since click events on the li items will will bubble up to it.
cardContainer.addEventListener('click', function(e){
e.preventDefault();
if (processing) {
return;
}
if (e.target.tagName.tolowerCase() !== 'li') {
return;
}
processing = true;
var cardlocation = searchCard(e.target.dataset.id);
if (cardlocation > -1) {
//card is already in array. do what you wish here
}
else {
//this is a new selection. do whatever you wish here
cardArray.push(e.target);
}
processing = false; //done processing.
});
Implement a search algorithm
/**
*This one will be slow if there loads of cards in the array
*#returns int returns the card index or -1 if not found
*/
var searchCard = function(id) {
var len = cardArray.length;
while (--len >= 0) {
if (id == cardArray[len].dataset.id) {
return len;
}
}
return -1;
}
Binary Search
/**
*used when sorting the cards
*/
var sortCard = function(card1, card2) {
var id1 = parseInt(card1.dataset.id),
id2 = parseInt(card2.dataset.id);
return id1 - id2;
};
/**
* used for checking the cards search
*/
var checkCard = function(id, card) {
return parseInt(id) - parseInt(card.dataset.id);
};
/**
*performs binary search
*/
var searchCard = function(id) {
if (cardArray.length === 0) {
return -1;
}
var low = 0,
high = cardArray.length - 1,
middle = parseInt((high + low + 1)/2, 10),
locationindex = -1,
searchindex = 0;
cardArray.sort(sortCard); //sort the card array
do {
searchindex = checkCard(id, cardArray[middle]);
if (searchindex === 0) {
locationindex = middle;
}
else {
//split and recalculate the middle
if (searchindex < 0) {
high = middle - 1;
}
else {
low = middle + 1;
}
middle = parseInt((high + low + 1) / 2, 10);
}
}
while (low <= high && locationindex === -1);
return locationindex;
}

Illustrator JavaScript only works once - won't toggle

I'm writing a script which changes the colours of a stick-man's arms and legs. Once "he" is selected, it effectively just mirrors the colours:
//Declare and initialize variables
var msgType = "";
var app;
var docRef = app.activeDocument;
var testColor = docRef.swatches.getByName("CMYK Green");
var leftColor = docRef.swatches.getByName("LeftColor");
var rightColor = docRef.swatches.getByName("RightColor");
function sameColor(CMYKColor1, CMYKColor2) {
"use strict";
var isTheSameColor;
if ((CMYKColor1.cyan === CMYKColor2.cyan) && (CMYKColor1.magenta === CMYKColor2.magenta) && (CMYKColor1.yellow === CMYKColor2.yellow) && (CMYKColor1.black === CMYKColor2.black)) {
isTheSameColor = true;
} else {
isTheSameColor = false;
}
return isTheSameColor;
}
// check if a document is open in Illustrator.
if (app.documents.length > 0) {
var mySelection = app.activeDocument.selection;
var index;
// Loop through all selected objects
for (index = 0; index < mySelection.length; index += 1) {
// Switch left and right colours
if (sameColor(mySelection[index].strokeColor, leftColor.color)) {
mySelection[index].strokeColor = rightColor.color;
}
if (sameColor(mySelection[index].strokeColor, rightColor.color)) {
mySelection[index].strokeColor = leftColor.color;
}
if (sameColor(mySelection[index].fillColor, leftColor.color)) {
mySelection[index].fillColor = rightColor.color;
}
if (sameColor(mySelection[index].fillColor, rightColor.color)) {
mySelection[index].fillColor = leftColor.color;
}
}
}
It works, but it only works once (i.e. I can't toggle the change again). If I undo the change and try again it works again. Why is this?
After a lot of head-scratching / debugging it turns out that it was changing the CMYK values to be not quite the same (by a tiny fraction).
Changed the following:
if ((CMYKColor1.cyan === CMYKColor2.cyan) ...
to:
if ((Math.round(CMYKColor1.cyan) === Math.round(CMYKColor2.cyan)) ...
and it works fine now.

Javascript decrement -- not working in my script

var backgroundImages = new Array(); // create an array holding the links of each image
backgroundImages[0] = "style/images/bg0.png";
backgroundImages[1] = "style/images/bg1.png";
backgroundImages[2] = "style/images/bg2.png";
backgroundImages[3] = "style/images/bg3.png";
backgroundImages[4] = "style/images/bg4.png";
backgroundImages[5] = "style/images/bg5.png";
backgroundImages[6] = "style/images/bg6.png";
var ImageCnt = 0;
function nextImage(direction) // this should take into account the current value (starts at 3) and determines whether a higher or lower value should be returned based on the direction
{
if(direction == "left")
{
ImageCnt-- ;
}
if(direction == "right")
{
ImageCnt++ ;
}
document.getElementById("body-1").style.background = 'url(' + backgroundImages[ImageCnt] + ')'; //put's the new background together for rendering by using the returned value from nextImage()
if(ImageCnt == 6)
{
ImageCnt = -1;
}
}
In this script, ImageCnt ++ is working fine, on the function "nextImage('right')" but on nextImage('left') which triggers ImageCnt-- , the function breaks. What am I doing wrong? (Newbie with js)
Well, your "wrap" code says to make it -1, but what if I then go left? It will try to access -2, which doesn't exist.
Try this instead:
ImageCnt = (ImageCnt + (direction == "left" ? backgroundImages.length-1 : 1)) % backgroundImages.length;
document.getElementById("body-1").style.background = "url('"+backgroundImages[ImageCnt]+"')";
Note also that it is very inefficient to build an array piece by piece like that. Try this:
var backgroundImages = [
"style/images/bg0.png",
"style/images/bg1.png",
"style/images/bg2.png",
"style/images/bg3.png",
"style/images/bg4.png",
"style/images/bg5.png",
"style/images/bg6.png",
];

Show/Hide & Mouseover Javascript

I been researching on Show/Hide javascript and pushed it further with a mouseover effect to achieve what I want. I've set up a Fiddle for better accessibility. However, I now want to push it by having up to 4 different text areas ("Click here for more information"), and each text area would have more hover text as I tried to show in the HTML code itself. The javascript that I used and edited now has "ID"s corresponding to "0" and "1" which wouldnt work for my current HTML code as it has funky names like "uu3308-10" (made with Adobe Muse). Now, I'm wonder what variables would I have to change within the Javascript to make it function properly and is there a way to compile this code so it works with at least 11 other "Click here for more information" points?
Note: The current javascript makes showMoreText2 appear under both showMoreText areas (would like to make only one hover text appear at a time).
CLICK HERE FOR THE FIDDLE -- > http://jsfiddle.net/TPLOR/vy6nS/
Thanks, I hope this was helpful enough. =)
kinda hackish: (see http://jsfiddle.net/vy6nS/30/ )
window.onload = function() {
var elems1 = document.getElementsByClassName("expander");
for (i = 0; i < elems1.length; i++) {
elems2 = elems1[i].childNodes;
for (x = 0; x < elems2.length; x++) {
if (elems2[x].className == "toggle") elems2[x].onclick = function() {
showMore(0, this);
};
else if (elems2[x].className == "showMoreText") {
elems2[x].onmouseover = function() {
showChilds("block", this);
};
elems2[x].onmouseout = function() {
showChilds("none", this);
};
}
}
}
};
function get_nextsibling(n) {
x = n.nextSibling;
while (x.nodeType != 1) {
x = x.nextSibling;
}
return x;
}
function showChilds(disp, elem) {
get_nextsibling(elem).style.display = disp;
}
function showMore(disp, elem) {
var children = elem.parentNode.childNodes;
for (i = 0; i < children.length; i++) {
if (disp == 0 && children[i].className == "showMoreText") {
children[i].style.display = children[i].style.display == "none" ? "block" : "none";
}
}
}​

Categories