Adding auto play to Javascript image slider - javascript

I have a slider and I want to add auto play every 3 seconds. I tried to use SetInterval but nothing happened.
Also I would like to remove the code for removing elements from the slider. I want to remove all the controls also and have only the slider changing image every 3 seconds.
this is the slider code
const galleryContainer = document.querySelector('.gallery-container');
const galleryControlsContainer = document.querySelector('.gallery-controls');
const galleryControls = ['Предидущий', '', 'Следующий'];
const galleryItems = document.querySelectorAll('.gallery-item');
class Carousel {
constructor(container, items, controls) {
this.carouselContainer = container;
this.carouselControls = controls;
this.carouselArray = [...items];
}
updateGallery() {
this.carouselArray.forEach(el => {
el.classList.remove('gallery-item-1');
el.classList.remove('gallery-item-2');
el.classList.remove('gallery-item-3');
el.classList.remove('gallery-item-4');
el.classList.remove('gallery-item-5');
});
this.carouselArray.slice(0, 5).forEach((el, i) => {
el.classList.add(`gallery-item-${i+1}`);
});
}
setCurrentState(direction) {
if (direction.className == 'gallery-controls-previous') {
this.carouselArray.unshift(this.carouselArray.pop());
} else {
this.carouselArray.push(this.carouselArray.shift());
}
this.updateGallery();
}
setControls() {
this.carouselControls.forEach(control => {
galleryControlsContainer.appendChild(document.createElement('button')).className = `gallery-controls-${control}`;
document.querySelector(`.gallery-controls-${control}`).innerText = control;
});
}
useControls() {
const triggers = [...galleryControlsContainer.childNodes];
triggers.forEach(control => {
control.addEventListener('click', e => {
e.preventDefault();
if (control.className == 'gallery-controls-add') {
const newItem = document.createElement('img');
const latestItem = this.carouselArray.length;
const latestIndex = this.carouselArray.findIndex(item => item.getAttribute('data-index') == this.carouselArray.length)+1;
Object.assign(newItem,{
className: 'gallery-item',
src: `http://fakeimg.pl/300/?text=${this.carouselArray.length+1}`
});
newItem.setAttribute('data-index', this.carouselArray.length+1);
this.carouselArray.splice(latestIndex, 0, newItem);
document.querySelector(`[data-index="${latestItem}"]`).after(newItem);
this.updateGallery();
} else {
this.setCurrentState(control);
}
});
});
}
}
const exampleCarousel = new Carousel(galleryContainer, galleryItems, galleryControls);
exampleCarousel.setControls();
exampleCarousel.useControls();

See the below code, I have added auto slide functionality with interval time 5 seconds.
If you want to change the interval, Please update the setInterval time in the "constructor" and "setCurrentState" functions.
I have removed the controls. To remove the controls, we need to comment the last 2 lines
//exampleCarousel.setControls();
//exampleCarousel.useControls();
const galleryContainer = document.querySelector('.gallery-container');
const galleryControlsContainer = document.querySelector('.gallery-controls');
const galleryControls = ['Предидущий', '', 'Следующий'];
const galleryItems = document.querySelectorAll('.gallery-item');
class Carousel {
constructor(container, items, controls) {
this.carouselContainer = container;
this.carouselControls = controls;
this.carouselArray = [...items];
this.mySlideInterval = null;
this.mySlideInterval = setInterval(
this.autoSlide.bind(this),
5000
);
}
autoSlide() {
this.carouselArray.push(this.carouselArray.shift());
this.updateGallery();
}
updateGallery() {
this.carouselArray.forEach(el => {
el.classList.remove('gallery-item-1');
el.classList.remove('gallery-item-2');
el.classList.remove('gallery-item-3');
el.classList.remove('gallery-item-4');
el.classList.remove('gallery-item-5');
});
this.carouselArray.slice(0, 5).forEach((el, i) => {
el.classList.add(`gallery-item-${i+1}`);
});
}
setCurrentState(direction) {
if (direction.className == 'gallery-controls-previous') {
this.carouselArray.unshift(this.carouselArray.pop());
} else {
this.carouselArray.push(this.carouselArray.shift());
}
clearInterval(this.mySlideInterval);
this.updateGallery();
this.mySlideInterval = setInterval(
this.autoSlide.bind(this),
5000
);
}
setControls() {
this.carouselControls.forEach(control => {
galleryControlsContainer.appendChild(document.createElement('button')).className = `gallery-controls-${control}`;
document.querySelector(`.gallery-controls-${control}`).innerText = control;
});
}
useControls() {
const triggers = [...galleryControlsContainer.childNodes];
triggers.forEach(control => {
control.addEventListener('click', e => {
e.preventDefault();
if (control.className == 'gallery-controls-add') {
const newItem = document.createElement('img');
const latestItem = this.carouselArray.length;
const latestIndex = this.carouselArray.findIndex(item => item.getAttribute('data-index') == this.carouselArray.length)+1;
Object.assign(newItem,{
className: 'gallery-item',
src: `http://fakeimg.pl/300/?text=${this.carouselArray.length+1}`
});
newItem.setAttribute('data-index', this.carouselArray.length+1);
this.carouselArray.splice(latestIndex, 0, newItem);
document.querySelector(`[data-index="${latestItem}"]`).after(newItem);
this.updateGallery();
} else {
this.setCurrentState(control);
}
});
});
}
}
const exampleCarousel = new Carousel(galleryContainer, galleryItems, galleryControls);
//exampleCarousel.setControls();
//exampleCarousel.useControls();

Related

How do I make a media Query responsive in JavaScript?

I really need some help with media queries. I have made a testimonial slider and when it gets to a 800px breakpoint, I want to disable the JS for the slider and change the layout.
The problem is that I am unable to deactivate the js once it has been activated, I'm not sure if the problem is from the event handler, the if statement of from the deactivation function.
I have managed to deactivate the JS but I have to reload the page to do it, I want it to be responsive so that I don't have to reload the page every time.
If you can help, that would be a huge help, thanks!
Here is my JS code:
(All my css code works, hence, it hasn't been added).
const mQ = window.matchMedia('(max-width: 800px)');
const testimonialSlider = function () {
const slides = document.querySelectorAll('.slide');
const btnLeft = document.querySelector('.slider__btn--left');
const btnRight = document.querySelector('.slider__btn--right');
const dotContainer = document.querySelector('.dots');
const testimonialContainer = document.querySelector(
'.testimonial-outer-container'
);
//Deactivate functions
const deactivateJs = function (slide) {
slides.forEach(
(s, i) => (s.style.transform = `translateX(${0 * (i - slide)}%)`)
);
testimonialContainer.removeChild(dotContainer);
console.log('DeactivatingJs');
};
// Activate functions
const activateJs = function () {
console.log('ActivateJS');
let curSlide = 0;
const maxSlide = slides.length;
//Functions
const createDots = function () {
testimonialContainer.appendChild(dotContainer);
slides.forEach(function (_, i) {
dotContainer.insertAdjacentHTML(
'beforeend',
`<button class="dots__dot" data-slide="${i}"></button>`
);
});
};
const slideReady = function () {
createDots();
activateDot(0);
goToSlide(0);
};
const goToSlide = function (slide) {
slides.forEach(
(s, i) => (s.style.transform = `translateX(${100 * (i - slide)}%)`)
);
};
// Activate dots
const activateDot = function (slide) {
// First we remove the active class on all of the dots and then we add it to the one that it is active
document
.querySelectorAll('.dots__dot')
.forEach(dot => dot.classList.remove('dots__dot--active'));
document
.querySelector(`.dots__dot[data-slide="${slide}"]`)
.classList.add('dots__dot--active');
};
// Next slide
const nextSlide = function () {
if (curSlide === maxSlide - 1) {
curSlide = 0;
} else {
curSlide++;
}
goToSlide(curSlide);
activateDot(curSlide);
};
const prevSlide = function () {
if (curSlide === 0) {
curSlide = maxSlide - 1;
} else {
curSlide--;
}
goToSlide(curSlide);
activateDot(curSlide);
};
slideReady();
//Event Handlers
btnRight.addEventListener('click', nextSlide);
btnLeft.addEventListener('click', prevSlide);
// Creating an event with the arrows
document.addEventListener('keydown', function (e) {
console.log(e);
if (e.key === 'ArrowLeft') prevSlide();
if (e.key === 'ArrowRight') nextSlide();
});
dotContainer.addEventListener('click', function (e) {
if (e.target.classList.contains('dots__dot')) {
/// const slide = e.target.dataset.slide;
//This is the same as above, the slide part is from the html and the dataset is an HTML attribute
const { slide } = e.target.dataset;
goToSlide(slide);
activateDot(slide);
}
});
};
// if (mQ.matches) {
// deactivateJs();
// } else {
// activateJs();
// }
const js = function () {
if (mQ.matches) {
console.log('deactivate');
deactivateJs();
} else {
activateJs();
}
};
mQ.addEventListener('change', js);
};
testimonialSlider();

Counter with clearInterval, not restarting after button click

There is a word-translation card page which includes:
A 3-second countdown that runs immediately after the page loads and when you move to a new word after press the 'Correct' button.
Word and his translate which appears after 'Excellent' button pressed. This button stops and hide the counter.
Button 'Show answer' which appears if 'Excellent' didn't pressed in 3 sec.
Buttons 'Wrong' and 'Correct' which appears if 'Excellent' or 'Show answer' buttons are pressed.
The problem is how the countdown works (unstable). Sometimes it doesn't restart after clicking "Correct". I tried manage countdown in separate function, but this approach provides much more issues. So now there is a timer that is called globally and a timer that is called when you click on the "Correct" button.I think the problem is near timerId. I will be glad to any comments and ideas on the code.
<div class="deck-container">
<div class="words-container">
<h2 id="primary-word"></h2>
<h2 id="secondary-word"></h2>
</div>
<div class="btn-container">
<p id="timer-count">3</p>
<button id="btn-excellent" onClick="excellent()">Excellent!</button>
<button id="btn-show-answer" onClick="showAnswerF()">Show Answer</button>
<button id="btn-wrong">Wrong</button>
<button id="btn-correct" onClick="correctF()">Correct</button>
</div>
</div>
let currentWord = 0
let timerCount = 3
let fetched_data = {}
async function getDeck () {
let response = await fetch('/api/deck_words/2/', {
method: 'get',
headers: {
'X-Requested-With': 'XMLHttpRequest',
'Content-Type': 'application/json'
}
}
)
let data = await response.json()
let primaryElement = document.getElementById('primary-word')
primaryElement.innerText = await data[currentWord]['primary_word']
let secondaryElement = document.getElementById('secondary-word')
secondaryElement.innerText = await data[currentWord]['secondary_word']
return data
}
fetched_data = getDeck()
const getData = async () => {
return await getDeck()
}
data = getData();
function countDecrease() {
timerCount --
if (timerCount > 0) {
document.getElementById("timer-count").innerHTML = timerCount
} else {
hideExcellent()
}
}
function hideExcellent() {
showElement(true,'btn-excellent')
showElement(true,'timer-count')
showElement(false,'btn-show-answer')
}
let timerId = setInterval(() => countDecrease(), 1000)
setTimeout(() => {
clearInterval(timerId)
}, 3000)
function showElement(showProperty, elementClass) {
showProperty = !showProperty
let element = document.getElementById(elementClass)
element.style.display = (showProperty === true) ? "inline-block" : "none";
}
function showAnswerF() {
showElement(true,'btn-show-answer')
showElement(false,'secondary-word')
showElement(false,'btn-wrong')
showElement(false,'btn-correct')
}
function excellent() {
showElement(true,'timer-count')
showElement(true,'btn-excellent')
showElement(false,'btn-wrong')
showElement(false,'btn-correct')
showElement(false,'secondary-word')
clearInterval(timerId)
timerCount = 3
}
function correctF() {
currentWord++
const changeWords = () => {
fetched_data.then((data) => {
document.getElementById('primary-word').innerText = data[currentWord]['primary_word']
document.getElementById('secondary-word').innerText = data[currentWord]['secondary_word']
document.getElementById("timer-count").innerText = '3'
timerCount = 3
timerId = setInterval(() => countDecrease(), 1000)
setTimeout(() => {
clearInterval(timerId)
}, 3000)
})
}
changeWords()
let countElement = document.getElementById('timer-count')
countElement.style.display = "block"
showElement(false,'btn-excellent')
showElement(true,'btn-wrong')
showElement(true,'btn-correct')
showElement(true,'secondary-word')
}
I think this would be better handled with an async function, maybe like so.
const timerCount = document.querySelector("#timer-count")
const reset = document.querySelector("button")
function delay(ms) {
return new Promise(res => setTimeout(res, ms))
}
async function countDown(signal) {
const aborted = new Promise(resolve => signal.addEventListener("abort", resolve))
for (let i = 10; i >= 0 && signal?.aborted != true; --i) {
timerCount.textContent = i
await Promise.race([delay(1000), aborted])
}
timerCount.textContent = ""
}
async function startCountdown() {
const ac = new AbortController()
const abort = () => ac.abort()
reset.addEventListener("click", abort, { once: true })
reset.textContent = "Cancel"
await countDown(ac.signal)
reset.removeEventListener("click", abort)
reset.addEventListener("click", startCountdown, { once: true })
reset.textContent = "Start"
}
startCountdown()
<p id="timer-count"></p>
<button>Start</button>
Alternatively, you might want to model the countdown as an object that implements EventTarget.
const timerCount = document.querySelector("#timer-count")
const btn = document.querySelector("button")
class Timer extends EventTarget {
#value; #tick_rate; #enabled; #interval_handle
constructor(tick_rate = 1000) {
super()
this.#value = 0
this.#tick_rate = tick_rate
this.#enabled = false
this.#interval_handle = null
}
get value() {
return this.#value
}
set value(value) {
this.#value = value
this.dispatchEvent(new Event("update"))
}
get tick_rate() {
return this.#tick_rate
}
get enabled() {
return this.#enabled
}
start() {
if (this.#enabled) return
this.#enabled = true
this.#interval_handle = setInterval(Timer.#tick, this.#tick_rate, this)
this.dispatchEvent(new Event("start"))
}
stop() {
if (!this.#enabled) return
this.#enabled = false
clearInterval(this.#interval_handle)
this.dispatchEvent(new Event("stop"))
}
static #tick(timer) {
timer.value = Math.max(0, timer.value - 1)
if (timer.value == 0) timer.stop()
}
}
const timer = new Timer()
timer.addEventListener("start", function() {
btn.textContent = "Stop"
})
timer.addEventListener("stop", function() {
timerCount.textContent = ""
btn.textContent = "Start"
})
timer.addEventListener("update", function() {
timerCount.textContent = timer.value
})
btn.addEventListener("click", function() {
if (timer.enabled == false) {
timer.value = 5
timer.start()
} else {
timer.stop()
}
})
<p id="timer-count"></p>
<button>Start</button>
Here's a countdown. The first count is after 1 second.
let count = 3;
let timer = [];
const start = () => {
new Array(count).fill(true).forEach((_,i) => {
timer.push(setTimeout(() => console.log('count',count - i),(i+1) * 1000))
})
}
const stop = () => timer.forEach(clearTimeout);
<button onclick="stop()">STOP</button>
<button onclick="start()">START</button>

Error on Sortting Items is not a function

I have a problem with my code
So, there is picture with like, when i click on the heart that add a like
there is a container down ma page and then the likes are also displayed in it.
(picture to show you a context)
The problem is everything work fine, but when you use my function "filter"
the likes are working on the photos but not down the page and that return me an error i don't really understand from where that come.
So can you help me please ?
import showMethods from "../factories/showMethods.js";
import lightbox from "../factories/lightbox.js";
import formularSecur from "../factories/formularSecur.js";
export default class OnePhotographer {
constructor() {
this.photographer = null;
this.medias = [];
this.likes = 0;
this.lightbox = lightbox;
this.indexLightbox = 0;
this.getPhotographer();
this.eInit();
}
eInit() {
document.getElementById("filtre").addEventListener("change", (e) => {
this.filter(e.target.value);
});
document.getElementById("filtre").addEventListener("click", (e) => {
this.filter(e.target.value);
});
document.getElementById("contactForm").addEventListener("submit", (e) => {
e.preventDefault();
formularSecur.checkForm(this);
document.getElementById("contactForm").reset();
});
this.lightbox.init(this);
document.getElementById("closeLightbox").addEventListener("click", () => {
this.lightbox.closeLightbox();
});
document.getElementById("prevBox").addEventListener("click", () => {
this.lightbox.navLightbox("prev");
});
document.getElementById("nextBox").addEventListener("click", () => {
this.lightbox.navLightbox("next");
});
document.addEventListener("keydown", (event) => {
if (event.code == "ArrowLeft") {
this.lightbox.navLightbox("prev");
} else if (event.code == "ArrowRight") {
this.lightbox.navLightbox("next");
} else if (event.code == "Escape") {
this.lightbox.closeLightbox();
}
});
}
filter(param) {
if (param === "popular") {
this.medias = this.medias.sort(this.order(param));
} else {
this.medias = this.medias.sort(this.order(param)).reverse();
}
document.querySelector(".containerMedias").innerHTML = "";
this.medias.forEach((media, index) => {
showMethods.showMedia(media, index);
showMethods.showLikes(this, instance);
});
}
order(settings) {
return function (x, y) {
if (x[settings] < y[settings]) {
return -1;
}
if (x[settings] > y[settings]) {
return 1;
}
return 0;
};
}
setMedias(media) {
this.medias = media;
}
async getPhotographer() {
const response = await fetch("./data/photographers.json");
const res = await response.json();
const id = this.idUrlCatch();
res.photographers.forEach((photographer) => {
if (photographer.id == id) {
this.photographer = photographer;
res.media.forEach((media) => {
if (media.photographerId == this.photographer.id) {
this.medias.push(media);
this.likes += media.likes;
}
});
this.medias = this.medias.sort(this.order("popular"));
}
});
showMethods.showData(this);
showMethods.showLikes(this, instance);
}
idUrlCatch() {
const str = window.location.href;
const url = new URL(str);
if (url.searchParams.get("id")) {
const id = url.searchParams.get("id");
return id;
}
}
showData() {
showMethods.showData(this);
showMethods.showLikes(this, instance);
}
showHeader() {
showMethods.showHeader(this);
}
showMedia(media, index) {
showMethods.showMedia(media, index, this);
}
showLikes() {
showMethods.showLikes(this, instance);
}
setSrcLightbox() {
showMethods.setSrcLightbox(this);
}
closeLightbox() {
showMethods.closeLightbox(this);
}
navLightbox() {
}
}
this is the second part of my code
import lightbox from "../factories/lightbox.js";
export default {
showData: function (instance) {
this.showHeader(instance);
instance.medias.forEach((media, index) => {
this.showMedia(media, index, instance);
});
instance.showLikes();
},
showHeader: function (instance) {
const infoHeader = document.querySelector(".photograph-header .containerInfo");
const title = document.createElement("h1");
title.textContent = instance.photographer.name;
const loc = document.createElement("h3");
loc.textContent = `${instance.photographer.city}, ${instance.photographer.country}`;
const tagline = document.createElement("span");
tagline.textContent = instance.photographer.tagline;
infoHeader.appendChild(title);
infoHeader.appendChild(loc);
const headerImg = document.querySelector(
".photograph-header .containerImg"
);
const pic = `assets/photographers/${instance.photographer.portrait}`;
const img = document.createElement("img");
img.setAttribute("src", pic);
img.setAttribute("alt", instance.photographer.name);
headerImg.appendChild(img);
},
showMedia: function (media, index, instance) {
const mediaSection = document.querySelector(".containerMedias");
const card = document.createElement("div");
card.classList.add("cardMedia");
const containerImg = document.createElement("div");
containerImg.classList.add("containerImg");
if (media.image) {
const mediaUrl = `assets/medias/${media.image}`;
const mediaItem = document.createElement("img");
mediaItem.dataset.index = index;
mediaItem.setAttribute("tabindex", 0);
mediaItem.addEventListener("click", (e) => {
lightbox.showLightbox(e, instance);
});
mediaItem.addEventListener("focus", () => {
mediaItem.addEventListener("keydown", (e) => {
if (e.code == "Enter") {
lightbox.showLightbox(e, instance);
}
});
});
mediaItem.setAttribute("src", mediaUrl);
mediaItem.setAttribute("alt", media.title);
containerImg.appendChild(mediaItem);
} else {
const mediaUrl = `assets/medias/${media.video}`;
const mediaItem = document.createElement("video");
mediaItem.dataset.index = index;
mediaItem.controls = true;
mediaItem.classList.add("media");
mediaItem.addEventListener("click", (e) => {
lightbox.showLightbox(e, instance);
});
mediaItem.setAttribute("src", mediaUrl);
mediaItem.setAttribute("alt", media.title);
mediaItem.setAttribute("data-index", index);
containerImg.appendChild(mediaItem);
}
const subContain = document.createElement("div");
subContain.classList.add("subContain");
const picTitle = document.createElement("h3");
picTitle.textContent = media.title;
const like = document.createElement("span");
like.setAttribute("tabindex", 0);
like.classList.add("like");
like.innerHTML = `${media.likes} <i class="fa-regular fa-heart"></i>`;
like.addEventListener("click", () => {
like.classList.toggle("active");
if (like.classList.contains("active")) {
media.likes += 1;
instance.likes += 1;
like.innerHTML = `${media.likes} <i class="fa-solid fa-heart"></i>`;
} else {
media.likes -= 1;
instance.likes -= 1;
like.innerHTML = `${media.likes} <i class="fa-regular fa-heart"></i>`;
}
instance.showLikes();
});
like.addEventListener("focus", () => {
like.addEventListener("keydown", (event) => {
if (event.code == "Enter") {
like.classList.toggle("active");
if (like.classList.contains("active")) {
media.likes += 1;
instance.likes += 1;
like.innerHTML = `${media.likes} <i class="fa-solid fa-heart"></i>`;
} else {
media.likes -= 1;
instance.likes -= 1;
like.innerHTML = `${media.likes} <i class="fa-regular fa-heart"></i>`;
}
instance.showLikes();
}
});
});
subContain.appendChild(picTitle);
subContain.appendChild(like);
card.appendChild(containerImg);
card.appendChild(subContain);
mediaSection.appendChild(card);
},
showLikes: function (instance) {
const priceContainer = document.createElement("div");
priceContainer.classList.add("priceContainer");
const likes = document.createElement("span");
likes.classList.add("likes");
likes.innerHTML = `<i class="fa-solid fa-heart"></i> ${instance.likes}`;
const priceDay = document.createElement("span");
priceDay.classList.add("priceDay");
priceDay.innerHTML = `<i class="fa-solid fa-dollar-sign"></i> ${instance.photographer.price}`;
priceContainer.appendChild(likes);
priceContainer.appendChild(priceDay);
document.querySelector(".photograph-header").appendChild(priceContainer);
},
};
i don't really get why with my function showMedia everithing is fine, but with showLikes not
the code error
Uncaught TypeError: instance.showLikes is not a function
at HTMLSpanElement.<anonymous> (showMethods.js:101:16)
(anonyme) # showMethods.js:101
if you help me that will save my life
Thank you for your time <3
So i find why the bug is happening when i use my "filter" Function.
I lose Instance on "showLikes" Function, so i don't have accès to the current instance.
One of my solution make my code in the onePhotograph.js, so no Instance ==> No bug.
I know this is maybe not the only solution, and maybe not the best. But this is a great solution also !
Best Regards

How to make play button disabled after the animation is finished?

I have this problem: I have two buttons btStop and btRace . BtPlays clicks all the buttons bt1 and all my cars are driving at the same time. BtStop works exactly the same but it stops the animation. My problem is, that when I once click btRace and animation is done I cannot click it again unless I click btStop, which is misleading because animation is already stopped.
Is there a way to make btPlay active again after the animation is finished?
I have long code so I am pasting showButtons method
showButtons(bt1, bt2, img, editingCarId) {
let playBts = document.querySelectorAll('.play')
function animation(img) {
let status = 'started';
let aPICallCarEngineState = new APICallCarEngineState(editingCarId, status);
aPICallCarEngineState.processRequestJSON((res) => {
// let resStr = JSON.stringify(res);
// console.log('I got ' + res)
res.velocity = res.velocity * 0.01
// res.distance = res.distance * 0.001
res.distance = 500;
// ===========Animation===================
img.style.animation = `car_move ${res.velocity}s ease-in`
})
}
//================Stop Animation===============
function stopAnimation() {
img.style.animation = 'none'
console.log(bt2 + 'stopp')
}
bt1.addEventListener('click', () => {
animation(img)
});
bt2.addEventListener('click', () => {
stopAnimation()
})
//=================Button start all animations ====================
this.btRace.addEventListener('click', () => {
bt1.click();
})
//=================Button stop all animations ====================
this.btStop.addEventListener('click', () => {
bt2.click();
})
}
invoke:
constructor:
this.table.appendTableHeadButton('RACE!')
this.table.appendTableHeadButtonStop('stop')
Buttoncreator:
appendTableHeadButtonStop(text) {
let td = document.createElement('td');
this.btStop = document.createElement('button');
this.btStop.innerText = text;
this.btStop.style.backgroundColor = 'red';
td.appendChild(this.btStop);
let bt = this.btStop;
this.headeRow.appendChild(td);
}
showButtons(bt1, bt2, img, editingCarId) {
let playBts = document.querySelectorAll('.play')
let isAnimating = false;
function animation(img) {
isAnimating = true;
btRace.disabled = true;
let status = 'started';
let aPICallCarEngineState = new APICallCarEngineState(editingCarId, status);
aPICallCarEngineState.processRequestJSON((res) => {
// let resStr = JSON.stringify(res);
// console.log('I got ' + res)
res.velocity = res.velocity * 0.01
// res.distance = res.distance * 0.001
res.distance = 500;
// ===========Animation===================
img.style.animation = `car_move ${res.velocity}s ease-in`
img.addEventListener('animationend', () => {
isAnimating = false;
btRace.disabled = false;
});
});
}
//================Stop Animation===============
function stopAnimation() {
isAnimating = false;
btRace.disabled = false;
img.style.animation = 'none'
console.log(bt2 + 'stopp')
}
bt1.addEventListener('click', () => {
animation(img)
});
bt2.addEventListener('click', () => {
stopAnimation()
});
//=================Button start all animations ====================
this.btRace.addEventListener('click', () => {
bt1.click();
});
//=================Button stop all animations ====================
this.btStop.addEventListener('click', () => {
bt2.click();
});
}
I am adding a flag to check the state of animation, and then toggle disabled property of btRace button respectively.

In js, how can i use my todo list on the other tap?

I used javascript, html, and css to create a usable todo list by moving tabs (project todo, personal todo). But it only works on the first tab, not the other tabs. (But it does animate the button being pressed.) I think it's a matter of order, but maybe not. PLEASE HELP ME !! Below is the code in javascript.
const todoObjectList1 = [];
const todoObjectList2 = [];
$(".menu1").click(function(){
$(this).addClass('on');
$(".menu2").removeClass("on");
})
$(".menu2").click(function(){
$(this).addClass('on');
$(".menu1").removeClass("on");
})
// project todo
class Todo_Class1 {
constructor(item){
this.ulElement1 =item;
}
add() {
const todoInput1 = document.querySelector("#myInput1").value;
if (todoInput1 == "") {
alert("You did not enter any item!")
} else {
const todoObject1 = {
id1 : todoObjectList1.length,
todoText1 : todoInput1,
isDone1 : false,
}
todoObjectList1.unshift(todoObject1);
this.display();
document.querySelector("#myInput1").value = '';
}
}
done_undone(x) {
const selectedTodoIndex1 = todoObjectList1.findIndex((item)=> item.id1 == x);
console.log(todoObjectList1[selectedTodoIndex1].isDone1);
todoObjectList1[selectedTodoIndex1].isDone1 == false ? todoObjectList1[selectedTodoIndex1].isDone1 = true : todoObjectList1[selectedTodoIndex1].isDone1 = false;
this.display();
}
deleteElement(z) {
const selectedDelIndex1 = todoObjectList1.findIndex((item)=> item.id1 == z);
todoObjectList1.splice(selectedDelIndex1,1);
this.display();
}
display() {
this.ulElement1.innerHTML = "";
todoObjectList1.forEach((object_item1) => {
const liElement1 = document.createElement("li");
const delBtn1 = document.createElement("i");
liElement1.innerText = object_item1.todoText1;
liElement1.setAttribute("data-id1", object_item1.id1);
delBtn1.setAttribute("data-id1", object_item1.id1);
delBtn1.classList.add("far", "fa-trash-alt");
liElement1.appendChild(delBtn1);
delBtn1.addEventListener("click", function(e) {
const deleteId1 = e.target.getAttribute("data-id1");
myTodoList1.deleteElement(deleteId1);
})
liElement1.addEventListener("click", function(e) {
const selectedId1 = e.target.getAttribute("data-id1");
myTodoList1.done_undone(selectedId1);
})
if (object_item1.isDone) {
liElement1.classList.add("checked");
}
this.ulElement1.appendChild(liElement1);
})
}
}
// personal todo
class Todo_Class2 {
constructor(item){
this.ulElement2 =item;
}
add() {
const todoInput2 = document.querySelector("#myInput2").value;
if (todoInput2 == "") {
alert("You did not enter any item!")
} else {
const todoObject2 = {
id2 : todoObjectList2.length,
todoText2 : todoInput2,
isDone2 : false,
}
todoObjectList1.unshift(todoObject2);
this.display();
document.querySelector("#myInput2").value = '';
}
}
done_undone(x) {
const selectedTodoIndex2 = todoObjectList2.findIndex((item)=> item.id2 == x);
console.log(todoObjectList2[selectedTodoIndex2].isDone2);
todoObjectList2[selectedTodoIndex2].isDone2 == false ? todoObjectList1[selectedTodoIndex2].isDone2 = true : todoObjectList2[selectedTodoIndex2].isDone2 = false;
this.display();
}
deleteElement(z) {
const selectedDelIndex2 = todoObjectList2.findIndex((item)=> item.id2 == z);
todoObjectList2.splice(selectedDelIndex2,1);
this.display();
}
display() {
this.ulElement2.innerHTML = "";
todoObjectList2.forEach((object_item2) => {
const liElement2 = document.createElement("li");
const delBtn2 = document.createElement("i");
liElement2.innerText = object_item2.todoText2;
liElement2.setAttribute("data-id2", object_item2.id2);
delBtn2.setAttribute("data-id2", object_item1.id2);
delBtn2.classList.add("far", "fa-trash-alt");
liElement2.appendChild(delBtn2);
delBtn2.addEventListener("click", function(e) {
const deleteId2 = e.target.getAttribute("data-id2");
myTodoList2.deleteElement(deleteId2);
})
liElement2.addEventListener("click", function(e) {
const selectedId2 = e.target.getAttribute("data-id2");
myTodoList1.done_undone(selectedId2);
})
if (object_item2.isDone) {
liElement2.classList.add("checked");
}
this.ulElement2.appendChild(liElement2);
})
}
}
////-----MAIN PROGRAM------------
const listSection1 = document.querySelector("#myUL1");
myTodoList1 = new Todo_Class1(listSection1);
// project todo add
document.querySelector(".addBtn1").addEventListener("click", function() {
myTodoList1.add()
})
document.querySelector("#myInput1").addEventListener("keydown", function(e) {
if (e.keyCode == 13) {
myTodoList1.add()
}
})
// personal todo add
const listSection2 = document.querySelector("#myUL2");
myTodoList2 = new Todo_Class2(listSection2);
document.querySelector(".addBtn2").addEventListener("click", function() {
myTodoList2.add()
})
document.querySelector("#myInput2").addEventListener("keydown", function(e) {
if (e.keyCode == 13) {
myTodoList2.add()
}
})
I just gave different javascript to different todo taps.
In other javascript, the existing personal part was removed and pasted.😂

Categories

Resources