I cannot solve this problem, are you able to solve it? I would need your expert advice on how to do it in JS vanilla or jQuery (optional).
A sample of code on jsfiddle would be high appreciated.
I have to display an array of 5 elements in a list with a limit of 3 at one time
var range = [0,1,2,3,4];
<ul>
<li>0</li>
<li>1</li>
<li>2</li>
</ul>
<div id="prev">prev</div>
<div id="next">next</div>
When user click on "next", I need to add a class "focus" on the first "li".
<ul>
<li class="focus">0</li>
<li>1</li>
<li>2</li>
</ul>
Second click on "next"
<ul>
<li>0</li>
<li class="focus">1</li>
<li>2</li>
</ul>
click on "next" ...
<ul>
<li>0</li>
<li>1</li>
<li class="focus">2</li>
</ul>
click on "next" ... note array shift
<ul>
<li>1</li>
<li>2</li>
<li class="focus">3</li>
</ul>
click on "next" ... array shift
<ul>
<li>2</li>
<li>3</li>
<li class="focus">4</li>
</ul>
click on "next" ... but I cannot go any further as there is not element in the array to be displayed, so if I clicking "prev" I would like have the reverse
click on "prev" …
<ul>
<li>2</li>
<li class="focus">3</li>
<li>4</li>
</ul>
click on "prev" …
<ul>
<li class="focus">2</li>
<li>3</li>
<li>4</li>
</ul>
click on "prev" … note array shift
<ul>
<li class="focus">1</li>
<li>2</li>
<li>3</li>
</ul>
click on "prev" … note array shift
<ul>
<li class="focus">0</li>
<li>1</li>
<li>2</li>
</ul>
click on "prev" … nothing happen it has we reach the beginning go the array
<ul>
<li class="focus">0</li>
<li>1</li>
<li>2</li>
</ul>
Any idea? Thanks in advance
Revised solutions as suggested in answers
http://jsfiddle.net/QwATR/
// Initalize everything
var curPos = 0;
var minIndex = 0;
var maxIndex = 2;
var clicks = 0;
var range = ['0','1','2','3','4','5','6','7','8','9','10'];
if($('li.focus').length === 0)
{
$('ul > li:eq(0)').addClass('focus');
$('ul > li').each(function(index){
$(this).text(range[index+curPos]);
});
}
// Next click handler
$('#next').click(function(){
if($('ul li').index($('li.focus')) < 2)
{
$('li.focus').removeClass('focus');
if(curPos < 2)
curPos++;
else
{
clicks++;
}
$('ul > li:eq('+curPos+')').addClass('focus');
} else {
if(clicks < range.length -3)
clicks++;
}
$('ul > li').each(function(index){
$(this).text(range[index+clicks]);
});
});
// Previous click handler
$('#prev').click(function(){
if($('ul li').index($('li.focus')) > 0)
{
$('li.focus').removeClass('focus');
if(curPos > 0)
curPos--;
else
{
clicks--;
}
$('ul > li:eq('+curPos+')').addClass('focus');
} else {
if(clicks > 0)
clicks--;
}
$('ul > li').each(function(index){
$(this).text(range[index+clicks]);
});
console.log('clicks after prev:' + clicks);
});
http://jsfiddle.net/QAsQj/2/
$(function(){
$("#next").click(function(){
if($(".focus").length == 0){
$("ul li:first-child").addClass("focus");
}
else{
if($(".focus").is(":last-child")){
$("ul li").each(function(){
var content = $(this).next("li").html();
$(this).empty().html(content);
}
$(".focus").html(/**WHATEVER YOUR NEXT CONTENT IS**/);
}
else{
var active = $(".focus");
$("ul li").removeClass("focus");
active.next("li").addClass("focus");
}
}
}
);
$("#prev").click(function(){
if($(".focus").length == 0){
break;
}
else{
if($(".focus").is(":first-child")){
$("ul li").each(function(){
var content = $(this).prev("li").html();
$(this).empty().html(content);
}
$(".focus").html(/**WHATEVER YOUR PREV CONTENT IS**/);
}
else{
var active = $(".focus");
$("ul li").removeClass("focus");
active.prev("li").addClass("focus");
}
}
}
);
}
);
This is quite straightforward in vanilla javascript (jsfiddle)
var range = [0, 1, 2, 3, 4],
lis = document.getElementsByTagName('li'),
foc, offset = 0;
function next() {
if (foc === undefined) {
foc = 0;
} else if (foc < lis.length - 1) {
foc++;
} else if (offset + foc < range.length - 1) {
offset++;
}
rewriteList();
}
function previous() {
if (foc === undefined) {
foc = 0;
} else if (foc > 0) {
foc--;
} else if (offset > 0) {
offset--;
}
rewriteList();
}
function rewriteList() {
for (var i = 0; i < lis.length; i++) {
lis[i].innerHTML = range[i + offset];
lis[i].className = i == foc ? 'focus' : '';
}
}
document.getElementById('prev').onclick = previous;
document.getElementById('next').onclick = next;
Alternatively you could set up the carousels with a constructor function (jsfiddle)
Related
I want to add an alternate class visible after 2 seconds to each element starting from 0 index. (like 0, 1, 2, 3, ... until the end).
When it comes to the last element, then add class to backwards like (10, 9, 8, ... until 0), so when on 0 again, forward and backward like an infinite loop. Thanks in advance for your help.
$(function() {
iterate();
function iterate() {
var i = 0;
var plus = setInterval(function() {
i++;
if (i == 10) {
clearInterval(plus);
}
}, 1000);
var minus = setInterval(function() {
i--;
if (i == 0) {
clearInterval(minus); // again start plus interval
}
});
$('li').removeClass('visible');
$('li').eq(i).addClass('visible');
}
});
.visible {
background: red
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<ol>
<li class="visible">One</li>
<li>Two</li>
<li>Three</li>
<li>Four</li>
<li>Five</li>
<li>Six</li>
<li>Seven</li>
<li>Eight</li>
<li>Nine</li>
<li>Ten</li>
</ol>
Try this: try below code where you can put logic to save current index and add / remove classes with setInterval function
$(function () {
var i = $("ol li").length;
var j =0;
var down = true;
setInterval(function(){
if(i==j || j<0) {
down = !down;
if(j<0) {
j=0;
}
}
if(down) {
$("ol li").eq(j).addClass("visible");
j++;
} else {
$("ol li").eq(j).removeClass("visible");
j--;
}
}, 2000);
});
.visible {
background: red
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ol>
<li>One</li>
<li>Two</li>
<li>Three</li>
<li>Four</li>
<li>Five</li>
</ol>
I have following script ,work perfectly . it only show first x element li and after click on show more it show all . how can i make limit when click on show more button , like i need x element show , next x element show and soo on here is my code
$('.tabNav ul').each(function() {
var LiN = $(this).find('li').length;
if (LiN > 3) {
$('li', this).eq(5).nextAll().hide().addClass('toggleable');
$(this).append('<li class="more">More...</li>');
}
});
$('.tabNav ul').on('click', '.more', function() {
if ($(this).hasClass('less')) {
$(this).text('More...').removeClass('less');
} else {
$(this).text('Less...').addClass('less');
}
$(this).siblings('li.toggleable').slideToggle();
});
Your help would be greatly appreciated.
Here is an idea of how you could toggle using step with the use of slice.
var step_nbr = 2;
var min_nbr = 6;
$('.tabNav ul').each(function() {
var LiN = $(this).find('li').length;
if (LiN > 3) {
$('li', this).eq(5).nextAll().hide().addClass('toggleable');
$(this).append('<li class="more">More...</li>');
}
});
$('.tabNav ul').on('click', '.more', function() {
var visible_lis = $('.tabNav ul li:visible').length;
if ($(this).hasClass('less')) {
$(this).prevAll('li:not(.toggleable)').slice(0, step_nbr).addClass('toggleable').hide();
if ($('li:visible').length <= (min_nbr + 1)) {
$(this).text('More...').removeClass('less');
}
} else {
$(this).siblings('li.toggleable').slice(0, step_nbr).removeClass('toggleable').show();
if ($('li.toggleable').length == 0) {
$(this).text('Less...').addClass('less');
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="tabNav">
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
</ul>
</div>
Javascript isn't my forte, so I'm looking for help : How would you write a function which add a Class to 3 elements with interval ?
<ul>
<li class="panel">Item 1</li>
<li class="panel">Item 2</li>
<li class="panel">Item 3</li>
</ul>
The idea is to add an .--active class on the 1st item when document is ready and remove it after 2sec to add it to the 2nd item and so on.
If you're using jQuery you could loop through the li's using the index, and reset the index to 0 when you reach the last li element :
if( $('li.panel.active').index() == lis_count-1 )
active_li_index = 0;
else
active_li_index++;
Hope this helps.
jQuery solution:
$(function(){
var lis_count = $('li.panel').length;
var active_li_index = 0;
setInterval(function(){
if( $('li.panel.active').index() == lis_count-1 )
active_li_index = 0;
else
active_li_index++;
$('li.panel.active').removeClass('active');
$('li.panel').eq(active_li_index).addClass('active');
}, 1000);
})
.active{
background-color: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="panel active">Item 1</li>
<li class="panel">Item 2</li>
<li class="panel">Item 3</li>
</ul>
Pure JS solution:
document.addEventListener('DOMContentLoaded', function(){
var lis = Array.prototype.slice.call( document.querySelectorAll('li.panel'));
var lis_count = lis.length;
var active_li_index = 0;
setInterval(function(){
var active_li = document.querySelector('li.panel.active');
if( lis.indexOf(active_li) == lis_count-1 )
active_li_index = 0;
else
active_li_index++;
active_li.classList.remove('active');
document.querySelectorAll('li.panel')[active_li_index].classList.add('active');
}, 1000);
}, false);
.active{
background-color: yellow;
}
<ul>
<li class="panel active">Item 1</li>
<li class="panel">Item 2</li>
<li class="panel">Item 3</li>
</ul>
Without jQuery:
function showGarland () {
var itemClass = 'panel';
var activeClass = '--active';
var wait = 2000; // 2 seconds
function toggleActive (element, index, maxIndex) {
setTimeout(function(){
element.classList.add(activeClass);
setTimeout(function(){
element.classList.remove(activeClass);
if (index == maxIndex) {
runLoop();
}
}, wait);
}, wait * index);
}
function runLoop () {
var allItems = document.getElementsByClassName(itemClass);
for (var index = 0; index < allItems.length; index++) {
var element = allItems[index];
toggleActive(element, index, allItems.length - 1);
}
}
runLoop();
}
window.addEventListener('load', showGarland);
.--active {
color:red;
}
<ul>
<li class="panel">Item 1</li>
<li class="panel">Item 2</li>
<li class="panel">Item 3</li>
</ul>
since you use jQuery you can do :
jQuery(() => { // callback when DOM is ready
$('.panel1').addClass('active'); // add your class
setTimeout(() => { // function that execute the callback after 2000ms (2s)
$('.panel1).removeClass('active'); // remove your class active
}, 2000);
});
you should use different class for your differents div
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<!-- <div class="hide">
text
</div> -->
<ul id="Items">
<li class="panel">Item 1</li>
<li class="panel hide">Item 2</li>
<li class="panel hide">Item 3</li>
</ul>
<style>
.hide{
visibility: hidden;
}
</style>
<script>
$(document).ready(function() {
var listItems = $("#Items li");
// alert(listItems);
listItems.each(function(idx, li) {
var product = $(li);
setInterval(function(){
product.css( "visibility", "visible" );
$(li).next().css( "visibility", "hidden" );
$(li).prev().css( "visibility", "hidden" );
}, 2000);
});
});
</script>
The above one works fine for two elements, but for the third element its showing quickly without displayinh the second element.
You can use something like this, you need to call toggleClass with the index you want to start, The functions addClass and removeClass supports multiple elements and multiple classes.
// Add class to element
// support multiple classes
function addClass(elements, className){
// split classes
var classArray = className.split(' ');
var els = [];
// If element does not have length property
if(elements.length == undefined)
els[0] = elements
else
els = elements;
for(e=0; e<els.length; e++){
var element = els[e];
for(i=0; i<classArray.length; i++){
if(element.className.indexOf(classArray[i])==-1){
element.className += ' ' + classArray[i];
}
}
}
}
// Remove class to element
// support multiple classes
function removeClass(elements, className){
var classArray = className.split(' ');
var els = [];
// If elements does not have length property
if(elements.length == undefined)
els[0] = elements
else
els = elements;
for(e=0; e<els.length; e++){
var element = els[e];
for(i= 0; i<classArray.length; i++){
element.className = element.className.replace(classArray[i], '').trim();
}
}
}
function toggleClass(index){
// get active elements and remove active class
removeClass(document.getElementsByClassName('active'), 'active');
// add class to element at index
addClass(document.getElementsByClassName('panel')[index], 'active');
// test if index should increment or reset
if(index<document.getElementsByClassName('panel').length - 1){
index++;
}else{
index = 0;
}
// wait 2sec until execute toggleClass again
setTimeout(toggleClass, 2000, index);
}
toggleClass(0);
.active {
color: green;
}
<ul>
<li class="panel">Item 1</li>
<li class="panel active">Item 2</li>
<li class="panel">Item 3</li>
</ul>
Edit: By the way beware with method classList since you'll need to polyfill for browser compatibility
window.addEventListener("load",function change(i=0){
var els=document.getElementsByClassName("panel");
if(els[i-1]) els[i-1].classList.toggle("active");
els[i].classList.toggle("active");
if(i<els.length-1) setTimeout(change,2000,i+1);
});
You could use a recursive approach to iterate over the class elements slowly and toggle their active class...
Without jQuery:
function showGarland () {
var itemClass = 'panel';
var activeClass = '--active';
var wait = 2000; // 2 seconds
function toggleActive (element, index, maxIndex) {
setTimeout(function(){
element.classList.add(activeClass);
setTimeout(function(){
element.classList.remove(activeClass);
if (index == maxIndex) {
runLoop();
}
}, wait);
}, wait * index);
}
function runLoop () {
var allItems = document.getElementsByClassName(itemClass);
for (var index = 0; index < allItems.length; index++) {
var element = allItems[index];
toggleActive(element, index, allItems.length - 1);
}
}
runLoop();
}
window.addEventListener('load', showGarland);
.--active {
color:red;
}
<ul>
<li class="panel">Item 1</li>
<li class="panel">Item 2</li>
<li class="panel">Item 3</li>
</ul>
Trying not set the background color every time the count is 7 or less, if its already red it shouldnt set it again.
<div class="parent">
<ul class="list">
<li class="item">Item 1</li>
<li class="item">Item 2</li>
<li class="item">Item 3</li>
<li class="item">Item 4</li>
<li class="item">Item 5</li>
<li class="item">Item 6</li>
<li class="item">Item 7</li>
</ul>
</div>
How can I stop setting the color over and over once the count is less than 7?
var parent = document.querySelector('.parent');
parent.addEventListener('click', changeColor, false);
function changeColor( e ) {
var element = e.target;
var item = document.querySelectorAll('.item');
element.parentNode.removeChild(element);
if( item.length <= 7 ) {
parent.style.background = "red";
console.log(
item.length + " set backgroud color"
)
}
}
DEMO http://jsfiddle.net/Grundizer/awc6rymn/
If I understand your question correctly, this should do the trick:
var parent = document.querySelector('.parent');
var background = 'false';
parent.addEventListener('click', changeColor, false);
function changeColor( e ) {
var element = e.target;
var item = document.querySelectorAll('.item');
element.parentNode.removeChild(element);
if( item.length <= 7 && parent.style.background != 'red') {
parent.style.background = "red";
console.log(
item.length + " set backgroud color"
)
}
You could remove event listener if count is under 7. That way, not only you're not changing color again, you're not running anything on click anymore.
if( item.length <= 7 ) {
parent.style.background = "red";
parent.removeEventListener('click', changeColor, false);
}
And if somewhere you have a function adding element, simply start listening again.
I have an unordered HTML list such as this:
<ul>
<li class="current"></li>
<li></li>
<li></li>
</ul>
Using jquery, I would like to automatically remove the current class from the first li element and add it to the second class. After a short period of time I would like to remove the class from the second li element and add it to the third. I would like for this to repeat as well.
I have this so far but it's not at all what I need:
$("ul li:first-child").addClass('current').delay(1000).queue(function(next){
$(this).removeClass('current');
$(this).next().addClass('current')
next();
});
If you want to be able to stop and start it:
var myInterval;
var myFunc = function() {
var cur = $('ul li.current');
if(cur.index() == $('ul li').length - 1) {
cur.removeClass('current');
$('ul li:first').addClass('current');
} else {
cur.removeClass('current').next().addClass('current');
}
};
//Start Interval
myInterval = setInterval(myFunc, 1000);
Then, to stop/start:
clearInterval(myInterval);
myInterval = setInterval(myFunc, 1000);
jsFiddle
var $li = $('ul li'), i = 0;
setInterval(function(){
i++;
if( $li.length === i ) i = 0;
$li.removeClass('current').eq(i).addClass('current')
}, 1000);
http://jsfiddle.net/mr7J6/
Try this:
var idx = 1;
setInterval(function () {
$('ul li').removeClass('current').eq(idx).addClass('current');
idx++;
if (idx == $('ul li').length) idx = 0;
}, 1000);
jsFiddle example
$(function(){
move();
});
function move(){
$("ul li.current").delay(1000).queue(function(next){
$(this).removeClass('current');
if($(this).next().addClass('current').length){
move();
}
});
}
If you need it to wrap around, you can do it using the modulus operator like this:
$(document).ready(function() {
var targets = $('ul li');
var len = targets.length;
var i = 0;
setInterval(function() {
// remove from current
$('li.highlight').removeClass('highlight');
i = (i + 1) % len;
targets.eq(i).addClass('highlight');
}, 1000);
});
Demo
Add and remove class unorder list current class using the jQuery click event.
**
Working Example
**
$(document).on('ready', function() {
$('.list-1 li').each(function(){
var t = $(this);
t.find('a').click(function(){
$('li.current').removeClass('current');
t.addClass('current');
});
});
});
.list-1 li a{text-decoration:none; color:#444; background:#ddd; padding:5px 15px 10px;}
.list-1 li.current a{background:tomato; color:#fff;}
.list-1{display:flex; flex-wrap:wrap;min-width:140px}
.list-1 li{padding:5px;margin:0 0 15px;display:block;}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="list-inline list-1">
<li class="current">Exapmle 1</li>
<li>Exapmle 2</li>
<li>Exapmle 3</li>
<li>Exapmle 4</li>
<li>Exapmle 5</li>
<li>Exapmle 6</li>
<li>Exapmle 7</li>
<li>Exapmle 8</li>
<li>Exapmle 9</li>
</ul>