Tiles dont turn right - javascript

I am making a website, http://phaidonasgialis.xyz. I want to make the tiles to turn and every other tile back. Until now it works except one small bug, the tile that you pressed does not turn back until you click second time.Any help would be thankful.
Here is the code:
$(document).ready(function() {
var previous = [];
$('.flip-card').each(function(i, obj) {
$(this).click(function() {
if ($(this).find('.flip-card-inner').hasClass('flip-card-transform')) {
$(this).find('.flip-card-inner').removeClass('flip-card-transform');
} else {
$(this).find('.flip-card-inner').addClass('flip-card-transform');
previous.push(this);
if (previous.length >= 2 && previous[previous.length - 2] != previous[previous.length - 1]) {
for (var i = 0; i < previous.length; i++) {
if ($(this).find('.flip-card-inner').hasClass('flip-card-transform')) {
$(previous[i - 1]).find('.flip-card-inner').removeClass('flip-card-transform');
console.log("2")
} else {
$(this).find('.flip-card-inner').addClass('flip-card-transform');
console.log("3")
}
}
}
}
});
});

If I understand your question correctly, you would like a card to flip back automatically after a certain period of time? If so then you just should set a Timeout and remove the class flip-card-transform from .flip-card-inner.
Aside note: you should definitely optimize your code by using a variable instead of doing $(this).find('.flip-card-inner')– converting this to jQuery object and searching trough its children every time when you need your flip-card-inner. Also instead of $('.flip-card').each(...) you could directly use $('.flip-card').click(...). And also as Harun Yilmaz suggested in his comment you don't need previous as an array...
So something like this should work:
$(document).ready(function () {
var previous
var timeout
$('.flip-card').click(function () {
var cardInner = $(this).find('.flip-card-inner')
if (cardInner.hasClass('flip-card-transform')) {
cardInner.removeClass('flip-card-transform')
clearTimeout(timeout)
} else {
cardInner.addClass('flip-card-transform')
// Set a Timeout
timeout = setTimeout(function () {
cardInner.removeClass('flip-card-transform')
}, 2000) // set whatever time sutable for you
// Also as Harun Yilmaz suggested in his comment you don't need previous as an array
if (previous && previous.hasClass('flip-card-transform')) {
previous.removeClass('flip-card-transform')
}
previous = cardInner
}
})
})

Related

LocalStorage drag previous saved array

I'm coding a currency converter that save every conversion that the user make and displayed. When i make the first conversion is fine. When i make the second it show the first one and the second, instead of only the second, like a to do list. Also i tried to use a constructor but i dont think that is the problem. If anyone can give me any help, that would be awesome!. Thx.
function calculo(){
resultado=(cantidad/monedaVal1)*monedaVal2;
$('#res').html('Obteniendo conversion...');
$('#res').fadeOut(500)
.fadeIn(500)
.fadeOut(500)
.fadeIn(500,function(){
$('#res').html(cantidad+' '+monedaText1+' = '+resultado.toFixed(2)+' '+monedaText2);
});
almacen();
}
class conversion {
constructor(monto, origen, destino, final) {
this.monto = monto;
this.origen = origen;
this.destino = destino;
this.final = final;
}
}
function almacen(){
cambios.push(new conversion(cantidad,monedaText1,monedaText2,resultado));
guardarCambio(cambios);
listarCambio(cambios);
}
function guardarCambio(cambios) {
let cambio = cargarCambio();
cambio.push(cambios);
localStorage.setItem('test', JSON.stringify(cambios));
}
function cargarCambio() {
if (localStorage.getItem('test')) {
return JSON.parse(localStorage.getItem('test'));
}
return [];
}
function listarCambio(cambios){
$.each(cambios, function (i) {
$('#conversiones').append('<tr><td>'+cambios[i].monto+'</td><td>'+cambios[i].origen+'</td><td>'+cambios[i].destino+'</td><td>'+cambios[i].final+'</td></tr>');
})
}

How to convert javascript code for Angular

I'm trying to implement something like the following into an Angular project: https://codepen.io/vincentorback/pen/NGXjda
The code compiles just fine in VS code, but when I try and preview in the browser, I get the following two errors:
Uncaught (in promise): TypeError undefined is not an object (evaluating 'this.context.addEventListener')
TypeError undefined is not an object (evaluating 'this.getScrollPos')
Stackblitz: https://stackblitz.com/edit/ionic-rv4ju7
home.page.ts
export class HomePage implements OnInit {
context = document.getElementsByClassName('loop')[0];
startElement = document.getElementsByClassName('is-start')[0];
clones = document.getElementsByClassName('is-clone');
disableScroll = false;
scrollWidth;
scrollPos;
clonesWidth;
i;
constructor() {
window.requestAnimationFrame(this.reCalc);
this.context.addEventListener('scroll', function () {
window.requestAnimationFrame(this.scrollUpdate);
}, false);
window.addEventListener('resize', function () {
window.requestAnimationFrame(this.reCalc);
}, false);
}
getScrollPos() {
return (this.context.pageXOffset || this.context.scrollLeft) - (this.context.clientLeft || 0);
}
setScrollPos(pos) {
this.context.scrollLeft = pos;
}
getClonesWidth() {
this.clonesWidth = 0;
this.i = 0;
for (this.i; this.i < this.clones.length; this.i += 1) {
this.clonesWidth = this.clonesWidth + this.clones[this.i].clientWidth;
}
return this.clonesWidth;
}
reCalc() {
this.scrollPos = this.getScrollPos();
this.scrollWidth = this.context.scrollWidth;
this.clonesWidth = this.getClonesWidth();
if (this.scrollPos <= 0) {
this.setScrollPos(1);
}
}
scrollUpdate() {
if (this.disableScroll === false) {
this.scrollPos = this.getScrollPos();
if (this.clonesWidth + this.scrollPos >= this.scrollWidth) {
// Scroll to the left when you’ve reached the far right
this.setScrollPos(1); // Scroll 1 pixel to allow scrolling backwards.
this.disableScroll = true;
} else if (this.scrollPos <= 0) {
// Scroll to the right when you reach the far left.
this.setScrollPos(this.scrollWidth - this.clonesWidth);
this.disableScroll = true;
}
if (this.disableScroll) {
// Disable scroll-jumping for a short time to avoid flickering.
window.setTimeout(function () {
this.disableScroll = false;
}, 40);
}
}
}
}
You need to move your code from the constructor to AfterViewInit, where DOM elements are available. As a further recommendation, I would recommend that keep what you can out of the constructor. Constructor is mainly used for initializing variables, not doing any logic.
Furthermore, you have issues with this, this doesn't point to what you think it does. Take a read: How to access the correct `this` inside a callback? Very useful reading! So I would recommend to use arrow functions instead of function to keep the context of this.
So change things like:
this.context.addEventListener('scroll', function () {
to:
this.context.addEventListener('scroll', () => {
Here's a fork of your StackBlitz
PS: where you can, make use of Angular tools instead of accessing the DOM like .getElementById. Just as a future hint. Many times angular has own set of tools, and accessing and manipulating the DOM from the component should be a last resort.

setting variables to be used in another function

Using edge animate, I don't seem to have the control over orders of operations that I am looking for. I have a function that operates a switch and another that tests the conditions of one or many switches. The problem I am running into is edge keeps wanting to run the test before the switch.
I can have the switch launch the test but run into the issue that I load the objects in an array inside of edge. What I am thinking is I need a way of pre-loading variables that the function can use but they don't need to be global since they are only used in this one function.
Here is what I have so far.
Inside Edge Animate:
twoPhaseSwitch('.btn1','on'); //sets up switch 1
twoPhaseSwitch('.swtch1','off'); //sets up switch 2
conditionsArray(['.btn1','.swtch1']); // tells the test script what the buttons are
In JavaScript file:
function twoPhaseSwitch(object,state)
{
var obj = $(object);
stage.getSymbol(obj).stop(state);
obj.data('state',state);
obj.mousedown(function(e)
{
if(obj.state == 'off')
{
stage.getSymbol(obj).stop('on');
obj.state = 'on';
obj.data('state','on');
}else{
stage.getSymbol(obj).stop('off');
obj.state = 'off';
obj.data('state','off');
};
});
};
function conditionsArray(obj)
{
var answers = ['on','on'];
// compare lengths
if (obj.length != answers.length)
return 'Argument Miscount';
var challengResults = challangeArray();
if (challengResults == true)
{
lightOn('.LED1','on');
}else if(challengResults == false)
{
lightOn('.LED1','off');
};
console.log(challengResults);
function challangeArray()
{
for (var i = 0, l=obj.length; i < l; i++)
{
if ($(obj[i]).data('state') != answers[i]) {
return false;
}
}
return true;
};
};
function lightOn(lightOBJ,state)
{
lightOBJ = $(lightOBJ);
stage.getSymbol(lightOBJ).stop(state);
};
I use mousedown and mouseup currently to fake the order of operations but it brings some pretty unacceptable issues so I am trying to do this right.
did you try wrapping your code in
$( document ).ready(){
your code here
}
to prevent any javascript from running until the page loads?

An approach for tracking and using sequential clicks

I'd like to define a relationship between two dom elements (in my particular case, draw lines between to nodes) by clicking on the first followed by a click on the second. The following is my approach. I don't think it's particularly elegant or clean. Is there a better way to do this?
$(function() {
var State = {
initialClick: false, // tracks clicks status for drawing lines
initialID: undefined // remember data gotten from the first click
};
...
$map.on('click', '.node', function() {
var $this = $(this),
currentID = $this.attr('data-id');
if (State.initialClick) {
if (State.initialID === currentID) {
// process first click
} else {
// process second click
}
resetClickTracking();
} else {
setState(currentID);
}
});
...
function setState(id) {
State.initialClick = true;
State.initialID = id;
}
function resetState() {
State.initialClick = false;
State.initialID = undefined;
}
});
I would probably go for a delegate pattern:
var lastNodeClicked = null;
$map.on('click', '.node', function() {
if (lastNodeClicked && lastNodeClicked !== this) {
// draw line
lastNodeClicked = null; // reset
} else {
lastNodeClicked = this;
}
});
Instead of resetting the last clicked node, you can also unconditionally update it with the clicked node; that way you can draw lines with less clicks ;-)

javascript keeping count on how many times a picture is deleted

I never used javascript in this way, but I would like to keep track of how many times a delete button is pressed. When the page originally loads I want to set the "value" to 0 and as they press delete keep track. Here is what I have is what obviously does not work, I didnt want to go the route of making a hidden variable and keep track that way. Thanks for any help.
Script
var deletePictureCount;
function MenuAction() {
}
MenuAction.prototype = {
GetDeletePictureCount: function () {
if (deletePictureCount == null || deletePictureCount < 0) { return 0; }
return deletePictureCount;
},
SetDeletePictureCount: function () {
deletePictureCount++;
}
};
usage on delete
var incement = new MenuAction().SetDeletePictureCount();
usage when trying to get value back
var deletedPiccount = new MenuAction().GetDeletePictureCount();
Looks a little odd to me - you aren't setting an initial value to the variable, and you are creating two instances of an object to get/set the value? And you are setting a return value to increment but aren't returning a value in that function.
Why not just use deletePictureCount++ and be done with it?
Let's take a look at your script:
var deletePictureCount; - Better set it's initial value if you gon'na use "set" before "get" before ;
if (deletePictureCount == null || deletePictureCount < 0) { return 0; } - this term is needless: I didn't see how exactly your deletePictureCount can get a negative value through your script.
Use if( deletePictureCount ) return deletePictureCount; instead.
It should look like
var deletePictureCount = 0;
function MenuAction() {
}
MenuAction.prototype = {
GetDeletePictureCount: function () {
if ( deletePictureCount ) return deletePictureCount; //if deletePictureCount is not null or 0 - return it's value;
return 0; // else return 0;
},
SetDeletePictureCount: function () {
deletePictureCount++;
}
};
You need to initialize the deletePictureCount to 0 like here,
http://jsbin.com/axeyiq/2/edit#javascript,html

Categories