Few object in one place - javascript

I have one selector: #circle-timer and I have few objects which target is this selector. Is any options to display only the selected item?
Example:
function timer(time){
var target = $('.value');
var counter = time;
var id = setInterval(function() {
counter--;
if(counter < 0) {
clearInterval(id);
} else {
target.text(counter);
}
}, 1000);
}
var p = timer(60);
var c = timer(33)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<div class="timer" id="round">
<div id="circle-timer" class="circle-timer">
<div class="time">
<p class="value">00</p>
</div>
</div>
</div>
<ul>
<li>show first timer</li>
<li>show second timer</li>
</ul>
But is showing all in one time. I want show selected timer (when click show first timer), not all.

Maybe this would help
jsFiddle
$('li').click(function(){
$(".value2").toggle();
$(".value1").toggle();
})
function timer(time,element){
var target = $('p.'+element);
var counter = time;
var id = setInterval(function() {
counter--;
if(counter < 0) {
clearInterval(id);
} else {
target.text(counter);
}
}, 1000);
}
var p = timer(60,'value1');
var c = timer(33,'value2')
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<div class="timer" id="round">
<div id="circle-timer" class="circle-timer">
<div class="time">
<p class="value1">00</p>
<p class="value2" style='display:none'>00</p>
</div>
</div>
</div>
<ul>
<li class="value1">show second timer</li>
<li class="value2" style='display:none'>show first timer</li>
</ul>

Related

Index number is connected with multiple slides, and cannot handle with them independently

Background
I made slides which are appeared on a modal, and its main functions are below.
There are "←Prev, Next→" buttons, and it enables to flip the page.
There are page numbers, "1, 2, 3", and it enables to flip the page.
If the shown page is the first or the last one, "←Prev, Next→" buttons are hidden, respectively.
Those functions were working properly when I had only one slide with the code below, but the last funtion doesn't work with multiple slides now.
slide.html.erb
<ul>
<li><div data-target="slide01">Slide1</div>
<div id="slide01" class="modal-wrapper">
<div class="modal">
<div class="close-modal">
<i class="fa fa-2x fa-times"></i>
</div>
<div class="slide-wrapper">
<div class="slide-title">Slide1</div>
<div class="change-btn-wrapper">
<div class="change-btn prev-btn">← Prev</div>
<div class="change-btn next-btn">Next →</div>
</div>
<ul class="slides">
<li class="slide active">A</li>
<li class="slide">B</li>
<li class="slide">C</li>
</ul>
<div class="index-btn-wrapper">
<div class="index-btn">1</div>
<div class="index-btn">2</div>
<div class="index-btn">3</div>
</div>
</div>
</div>
</div>
</li>
<li><div data-target="slide02">Slide2</div>
<div id="slide02" class="modal-wrapper">
<div class="modal">
<div class="close-modal">
<i class="fa fa-2x fa-times"></i>
</div>
<div class="slide-wrapper">
<div class="slide-title">Slide2</div>
<div class="change-btn-wrapper">
<div class="change-btn prev-btn">← Prev</div>
<div class="change-btn next-btn">Next →</div>
</div>
<ul class="slides">
<li class="slide active">D</li>
<li class="slide">E</li>
<li class="slide">F</li>
</ul>
<div class="index-btn-wrapper">
<div class="index-btn">1</div>
<div class="index-btn">2</div>
<div class="index-btn">3</div>
</div>
</div>
</div>
</div>
</li>
</ul>
slide.js
$(document).on('turbolinks:load', function() {
$(function() {
function toggleChangeBtn(){
var slideIndex = $('.slide').index($('.active'));
$('.change-btn').show();
if (slideIndex == 0) {
$('.prev-btn').hide();
} else if (slideIndex == $('.slide').length -1) {
$('.next-btn').hide();
}
$('.index-btn').click(function() {
$('.active').removeClass('active');
var clickedIndex = $('.index-btn').index($(this));
$('.slide').eq(clickedIndex).addClass('active');
toggleChangeBtn();
});
$('.change-btn').click(function() {
var $displaySlide = $('.active');
$displaySlide.removeClass('active');
if ($(this).hasClass('next-btn')) {
$displaySlide.next().addClass('active');
}
else {
$displaySlide.prev().addClass('active');
}
toggleChangeBtn();
});
})
});
Problems
Those codes below check if the shown page is the first or the last one from its index number, and hide "←Prev, Next→" buttons, respectively.
slide.js
var slideIndex = $('.slide').index($('.active'));
$('.change-btn').show();
if (slideIndex == 0) {
$('.prev-btn').hide();
} else if (slideIndex == $('.slide').length -1) {
$('.next-btn').hide();
}
The trouble is that those index numbers are connected when multiple slides are made. As a result, the code above just checks only both of the first page in the first slide and the last page in the last slide.
What I have tried
I tried to use $(this).parents method to narrow down the range of the slide like below. I did not make any change on the view.
slide.js
$(document).on('turbolinks:load', function() {
$(function() {
function toggleChangeBtn(dir){
var dir = $(this).parents('.slide-wrapper'); // Identify the slide.
$('.change-btn').show();
var slideIndex = dir.find('.slide').dir.index('.active');
if (slideIndex == 0) {
dir.find('.prev-btn').hide();
} else if (slideIndex == dir.find('.slide').length -1) {
dir.find('.next-btn').hide();
}
}
$('.index-btn').click(function() {
var dir = $(this).parents('.slide-wrapper');
dir.find('.active').removeClass('active');
var clickedIndex = $('.index-btn').index($(this));
$('.slide').eq(clickedIndex).addClass('active');
toggleChangeBtn(dir);
});
$('.change-btn').click(function() {
var dir = $(this).parents('.slide-wrapper');
var $displaySlide = dir.find('.active');
$displaySlide.removeClass('active');
if ($(this).hasClass('next-btn')) {
$displaySlide.next().addClass('active');
}
else {
$displaySlide.prev().addClass('active');
}
toggleChangeBtn(dir);
});
})
});
However, "←Prev, Next→" buttons are not hidden properly in any slide with this code.
And how "←Prev, Next→" buttons are shown in one slide affects to the other slide too.
I am grateful if anyone gives me some advice.
Versions
ruby 2.6.4p104
RubyGems 3.0.3
Rails 5.2.3
jquery 1.12.4
If both buttons should be independent of each other, why are they made dependant by the if / else if block?
if (slideIndex == 0) {
dir.find('.prev-btn').hide();
} else if (slideIndex == dir.find('.slide').length -1) {
dir.find('.next-btn').hide();
}
To make the .prev-btn and .next-btn appear/disappear independently, make these independant if statements:
var slides = dir.find('.slide');
var slideIndex = slides.length ? slides.dir.index('.active') : 0;
if (slideIndex == 0) {
dir.find('.prev-btn').hide();
}
if (slides.length <= 1 || slideIndex == slides.length - 1) {
dir.find('.next-btn').hide();
}

Show active class

I want to add class 'active' to next div 1 second before first is removed.
Practically, I want to have an 'active' class on 2 elements at the same time for that 1 second.
Can someone help me?
Thanks
<div class="map-inner">
<div class="map-location-outer">
<div class="map-location-inner location1 active">
<div class="map-location">
<div class="map-icon">
<img src="i/content/map-icon2.svg">
</div>
<span class="map-pin"><span></span></span>
</div><!-- map-location -->
</div>
</div>
<div class="map-location-outer">
<div class="map-location-inner location2">
<div class="map-location">
<div class="map-icon">
<img src="i/content/map-icon3.svg">
</div>
<span class="map-pin"><span></span></span>
</div><!-- map-location -->
</div>
</div>
<div class="map-location-outer">
<div class="map-location-inner location3">
<div class="map-location">
<div class="map-icon">
<img src="i/content/map-icon1.png">
</div>
<span class="map-pin"><span></span></span>
</div><!-- map-location -->
</div>
</div>
</div>
var x = 1;
function updateClass() {
let a = $(".map-location-inner.active");
a.removeClass("active");
a = a.parent().next(".map-location-outer");
if (a.length == 0)
a = $(".map-location-outer").first();
a.find(".map-location-inner").addClass("active");
}
setInterval(function () {
updateClass();
}, x * 5500);
You can use setTimeout to wait before removing 1st .active class and add 2nd .active class before removing 1st one.
var x = 1;
function updateClass() {
let a = $(".map-location-inner.active");
let b = a.parent().next(".map-location-outer");
if (b.length == 0)
b = $(".map-location-outer").first();
b.find(".map-location-inner").addClass("active");
setTimeout(function() {
a.removeClass("active");
}, 1000);
}
setInterval(function () {
updateClass();
}, x * 5500);

How to change style on other element using Javascript with nodelist

Need help with using js script.
<ul class="producers-links">
<li class="section_All active-producer">A-Z</li>
<li class="section_0-9">0-9</li>
<li class="section_A">A</li>
<li class="section_B">B</li>
<li class="section_C">C</li>
</ul>
And
<div class="producers-list">
<div class="producers-container" id="producers-0-9">
<div class="break-producers">0-9</div>
</div>
<div class="producers-container" id="producers-A">
<div class="break-producers">A</div>
Producer 1
</div>
<div class="producers-container" id="producers-B">
<div class="break-producers">B</div>
Producer 2
</div>
<div class="producers-container" id="producers-C">
<div class="break-producers">C</div>
Producer 3
</div>
</div>
How to make js script that will allow user click on list element then all divs from producers-list will get display:none without this one which was clicked at list.
var producersList = document.querySelectorAll('ul.producers-links>li');
var producersLists = document.querySelectorAll('div.producers-list>div.producers-container');
for (var i = 0; i < producersList.length; i++) {
producersList[i].addEventListener('click', function () {
document.querySelector('.active-producer').classList.remove('active-producer');
this.classList.add('active-producer');
var index = 0,
length = producersList.length;
for (; index < length; index++) {
producersLists[index].style.display = "none";
}
});
}
This allow me to hide all elements from producers-container but i don't know how to show only one element clicked before at list.
First of all you should use classes instead of id in the second list in order to have the ability to add more procedures in the future
try this:
<ul class="producers-links">
<li id="section_All" class="active-producer">A-Z</li>
<li id="section_0-9">0-9</li>
<li id="section_A">A</li>
<li id="section_B">B</li>
<li id="section_C">C</li>
</ul>
<div class="producers-list">
<div class="producers-container section_0-9 section_All">
<div class="break-producers">0-9</div>
</div>
<div class="producers-container section_A section_All">
<div class="break-producers">A</div>
Producer 1
</div>
<div class="producers-container section_B section_All">
<div class="break-producers">B</div>
Producer 2
</div>
<div class="producers-container section_C section_All">
<div class="break-producers">C</div>
Producer 3
</div>
</div>
var producersList = document.querySelectorAll('ul.producers-links > li');
var producersLists = document.querySelectorAll('.producers-container');
for (var i = 0; i < producersList.length; i++) {
producersList[i].addEventListener('click', function () {
document.querySelector('.active-producer').classList.remove('active-producer');
this.classList.add('active-producer');
for (var index = 0; index < producersLists.length ; index++) {
var currElement = producersLists[index];
var hide = !currElement.classList.contains(this.id);
producersLists[index].style.display = hide? "none" : "block";
}
});
}
On click, you can sequentially:
- hide all
- select the one having the same end of id than the textContent of the clicked item (or select all if text is A-Z)
var producersList = document.querySelectorAll('ul.producers-links>li');
var producersLists = document.querySelectorAll('div.producers-list>div.producers-container');
// add eventlistener...
producersList.forEach(x => {
x.addEventListener("click", x => {
hideAll();
document.querySelector('.active-producer').classList.remove('active-producer');
x.target.classList.add('active-producer');
const txt = x.target.textContent;
selectForText(txt);
});
});
// hide/show all...
function hideAll(bShow) {
const cl = bShow === true?"block":"none";
producersLists.forEach(x => x.style.display = cl);
}
// select for text...
function selectForText(txt) {
if(txt === "A-Z") {
// select all...
hideAll(true);
return;
}
// the [...nodelist] part allows to 'cast' to proper array, and to have access to find() function...
const found = [...producersLists].find(q => q.id.split("producers-")[1] === txt);
if(found) {
found.style.display = "block";
}
else {
// ???
}
}
.active-producer {
color: #19f;
}
<ul class="producers-links">
<li class="section_All active-producer">A-Z</li>
<li class="section_0-9">0-9</li>
<li class="section_A">A</li>
<li class="section_B">B</li>
<li class="section_C">C</li>
</ul>
And
<div class="producers-list">
<div class="producers-container" id="producers-0-9">
<div class="break-producers">0-9</div>
</div>
<div class="producers-container" id="producers-A">
<div class="break-producers">A</div>
Producer 1
</div>
<div class="producers-container" id="producers-B">
<div class="break-producers">B</div>
Producer 2
</div>
<div class="producers-container" id="producers-C">
<div class="break-producers">C</div>
Producer 3
</div>
</div>

How to target a specific slider using javascript when there is more than one

I have 3 sliders on my page I'm a building but i am just curious to know the best way to go about targeting only the active one so the javascript below would work for all of them. Everything seems to work fine if i disable the other 2 sliders. First time I have done something like this.
I'm guessing my javascript selectors may need to change some what to get it to work.
Appreciate any advice on the best way forward.
var sliderSlide = document.querySelectorAll('.slider__slide');
var nextSlide = document.querySelector('.slider__button--next');
var previousSlide = document.querySelector('.slider__button--previous');
var currentSlide = 0;
var currentSlideImg = 0;
//Reset slides
function resetSlides() {
for (var s = 0; s < sliderSlide.length; s++) {
sliderSlide[s].classList.remove('active');
}
for (var i = 0; i < sliderSlideImg.length; i++) {
sliderSlideImg[i].classList.remove('active');
}
}
//Start slides
function startSlide() {
resetSlides();
sliderSlide[0].classList.add('active');
sliderSlideImg[0].classList.add('active');
}
//Previous slide
function slidePrevious() {
resetSlides();
sliderSlide[currentSlide - 1].classList.add('active');
currentSlide--;
sliderSlideImg[currentSlideImg - 1].classList.add('active');
currentSlideImg--;
}
previousSlide.addEventListener('click', function() {
if (currentSlide === 0 && currentSlideImg === 0) {
currentSlide = sliderSlide.length;
currentSlideImg = sliderSlideImg.length;
}
slidePrevious();
});
//Next slide
function slideNext() {
resetSlides();
sliderSlide[currentSlide + 1].classList.add('active');
currentSlide++;
sliderSlideImg[currentSlideImg + 1].classList.add('active');
currentSlideImg++;
}
nextSlide.addEventListener('click', function() {
if (currentSlide === sliderSlide.length - 1 && currentSlideImg === sliderSlideImg.length - 1) {
currentSlide = -1;
currentSlideImg = -1;
}
slideNext();
});
<div class="slider slider--1 active">
<div class="slider__slide">
<p class="slider__text">some text</p>
</div>
<div class="slider__slide">
<p class="slider__text">some text</p>
</div>
<div class="slider__slide">
<p class="slider__text">some text</p>
</div>
<div class="slider__buttons">
<span class="slider__button--previous">Previous</span>
<span class="slider__button--next">Next</span>
</div>
</div>
<div class="slider slider--2">
<div class="slider__slide">
<p class="slider__text">some text</p>
</div>
<div class="slider__slide">
<p class="slider__text">some text</p>
</div>
<div class="slider__slide">
<p class="slider__text">some text</p>
</div>
<div class="slider__buttons">
<span class="slider__button--previous">Previous</span>
<span class="slider__button--next">Next</span>
</div>
</div>
<div class="slider slider--3">
<div class="slider__slide">
<p class="slider__text">some text</p>
</div>
<div class="slider__slide">
<p class="slider__text">some text</p>
</div>
<div class="slider__slide">
<p class="slider__text">some text</p>
</div>
<div class="slider__buttons">
<span class="slider__button--previous">Previous</span>
<span class="slider__button--next">Next</span>
</div>
</div>
You can create loop over .slider and then use querySelector on each item, that way you will have variables for each slider
Array.from(document.querySelectorAll('.slider')).forEach(function(slider) {
var sliderSlide = slider.querySelectorAll('.slider__slide');
var nextSlide = slider.querySelector('.slider__buttons--next');
var previousSlide = slider.querySelector('.slider__buttons--previous');
...
});
or if you prefer for loop:
var sliders = document.querySelectorAll('.slider');
for (var i = 0; i < sliders.length; ++i) {
var slider = sliders[i];
...
}
document.querySelector('.slider--3 .slider__slide')
but I would recommend to put id's on your sliders and then select
document.querySelector('#slider--3')

Simple JavaScript only "next" and "previous" action?

I currently have it so that a block of text changes when you click on the "page" number, but I'd like to add previous and next buttons.
Check out my current version here: http://jsfiddle.net/ZBWqS/
Every solution I've thought of turns into a mess of non-working code when I start going.
Sorry for the noob-JS question.
<div id="1" style="display: block;">
<p>This is the first block of text</p>
<p class="page">
1 of 3
</p>
</div>
<div id="2" style="display: none;">
<p class="red">This is the second block of text</p>
<p class="page">
2 of 3
</p>
</div>
<div id="3" style="display: none;">
<span>This is the third block of text</span>
<p class="page">
3 of 3
</p>
</div>
<div class="bottom">
1 2 3
</div>
<script>
function show(id) {
document.getElementById(id).style.display = 'block';
}
function hide(id) {
document.getElementById(id).style.display = 'none';
}
</script>​
I have also build a refactored version of your code, you decide which one you like more ;)
http://jsfiddle.net/haDAj/
HTML
<div id="1" class="pagecontainer" style="display: block;">
<p>This is the first block of text</p>
<p class="page">
1 of 3
</p>
</div>
<div id="2" class="pagecontainer" style="display: none;">
<p class="red">This is the second block of text</p>
<p class="page">
2 of 3
</p>
</div>
<div id="3" class="pagecontainer" style="display: none;">
<span>This is the third block of text</span>
<p class="page">
3 of 3
</p>
</div>
<div class="bottom">
‹
1
2
3
›
</div>​
SCRIPT
var currentPage = 1;
function page(pg)
{
var els = document.getElementsByClassName("pagecontainer");
for (var i = 0; i < els.length; i++)
{
var page_of_container = els[i].getAttribute("id");
els[i].style.display = page_of_container == pg ? 'block' : 'none';
}
currentPage = pg;
}
function prev()
{
if (currentPage <= 1) return;
page(currentPage -1);
}
function next()
{
if (currentPage >= document.getElementsByClassName("pagecontainer").length) return;
page(currentPage + 1);
}​
Keep a variable to store where you are, increment/decrement it, then show content based on that variable.
http://jsfiddle.net/ZBWqS/3/
// hold where we are right now. For previous and next to make sense,
// you have to know where you are.
var current = 1;
// function to go to previous
var prev = function() {
current -= 1;
if (current < 1) current = 1; // can't go too far previous
showContent();
};
// function to go next
var next = function() {
current += 1;
if (current > 3) current = 3; // can't go too far next
showContent();
};
// Update what content we are showing based on the "current" index
var showContent = function() {
var display;
for (var i = 1; i <= 3; i++) {
if (i == current) {
display = 'block';
} else {
display = 'none';
}
document.getElementById(i).style.display = display;
}
};
// bind the prev and next function to the links
document.getElementById('prev').onclick = prev;
document.getElementById('next').onclick = next;
// Setup the initial state of the content
showContent();
​

Categories