jQuery apply css class to next single element - javascript

I am trying to create a simple jquery slideshow. However I am having trouble getting it to loop through the elements.
I know next() just add's the active class to the next elements, and not a single. That is the part i am having trouble with. How can just apply a single class to the next element, and it loop forever.
jQuery(document).ready(function () {
var slides = jQuery('#slideshow'); //Parent container for the slideshow
var activeClass = 'active'; //Set the active slide CSS class
var interval = 3000; // Interval in miliseconds
var countSlides = slides.children().length;
//Runs the slideshow
function cycle() {
slides.children().removeClass(activeClass);
slides.children().next().addClass(activeClass);
};
setInterval(cycle, interval);
});

According to the documentation .next() returns the element next to every element in the collection it is called on. In your case that is all children. If you select only the current active element before dropping the .active class you can get the element next to it.
function cycle() {
var $current = slides.children('.active');
$current
.removeClass('active')
.next().addClass('active');
}
Edit: as on how to loop. You need to check if there is a next element. If .next() does not return a new element you could grab the first child instead:
var $current = slides.children('.active'),
$next = $current.next();
if (!$next.length) {
// No next slide, go back to the first one.
$next = slides.children().first();
}
$current.removeClass('active');
$next.addClass('active');

Related

How to make autoplay with li elements on screen one at a time with setInterval using JavaScript?

I want to go through li element's that will display the img on the screen one by one by using setInterval. I'm not sure how to approach this, I already made the buttons work to click that will go through the li element's.
I tried making a function that will go through the li element's and then call it inside a setInterval. It didn't work as I expected, it does count from 0-4, and repeats.
const slide = document.querySelector("[data-slides]");
console.log(slide);
const newIndex = [...slide.children];
console.log(newIndex);
let start = 0;
function slider() {
if (start < newIndex.length) {
start = start + 1;
} else {
start = 0;
}
console.log(start);
}
setInterval(slider, 2000);
codepen: https://codepen.io/jimmyjimenez2400/pen/KKBeezj
I think you need to change the visibility of the li elements on each iteration of the slider() function. you can add a class ("visible") to the current li element and remove it from the previous one, and track of the current slide index.
kindly try this approach:
const slide = document.querySelector("[data-slides]");
const newIndex = [...slide.children];
let start = 0;
function slider() {
newIndex[start].classList.remove("visible");
start = (start + 1) % newIndex.length;
newIndex[start].classList.add("visible");
}
setInterval(slider, 2000);

Opacity on first and last element of slider which has ".active" classes using javascript or css

I have owl carousel slider with 5 items. And my problem is that i need first and last element of my slider to be always with opacity. Slider has like 15 elements which 9 cloned, 5 have .active class and one with cloned and .active.
I tryied make it using javascript where i found all ".active" classes in slider, but i don't exactly know what i should do with object which was found.
There is code which found all ".active" classes
var owlCarouselActive = document.getElementById("slider-tour").getElementsByClassName("owl-item active");
I need in order to this .active first and last have :before with my background style when i click on button prev or next.
You could do this with javascript
var owlCarouselActive = document.getElementsByClassName("owl-item active");
var first = owlCarouselActive[0]; //get first item
var last = owlCarouselActive[owlCarouselActive.length - 1]; //get last item
first.style.opacity = 0.8;
last.style.opacity = 0.8;
I'm not at home but try something like this:
function setOpacity() {
var elements = $('.active');
let count = 0;
$(elements).each(function(k,v) {
if (count == 0 || count == elements.length - 1) {
$(v).css('opacity', '0.8');
}
count++;
});
}
$(document).ready(function() {
setOpacity();
});
Run that function everytime you want it to update.
E.G on a button click.
You can use owlCarouselActive [0] to access the first element and owlCarouselActive [owlCarouselActive.length-1] to access the last element. Generally you can access i-th element by owlCarouselActive [i].

why add the class next left when I should add the active class in the boostrap carousel

What I want to do is that when my question has a timer and the user next, that question disappears and I can not answer it.
Code:
var timer = $(".active").attr('data-timer');
if (timer == undefined) {
var $carousel = $('#carousel');
var NextElement = $carousel.next('.item').first();
NextElement.addClass('active');
$('.timer').remove();
} else {
var $carousel = $('#carousel');
var ActiveElement = $carousel.find('.item.active');
ActiveElement.remove();
var NextElement = $carousel.next('.item');
NextElement.addClass('active');
$('.timer').remove();
}
It does everything, except that when it enters the else instead of adding the active in my carousel it adds the class next left.
Instead of this class being added, it should be active, so when it re-enters the if the slide does not work anymore. Even add the following:
var NextElement = $carousel.next('.item').first();
It's the .first
Just use var NextElement = $carousel.next('.item'), next only returns one element https://api.jquery.com/next/

upgrading from javascript to jquery

I have the following javascript function that I call on body onload. But I want to change the javascript function into jQuery statements and call them directly inside of the document.ready() function.
function ChangeSomeStyles(){
//hide the last two links of TopNav
var container = document.getElementsByTagName("ul")[0];
var lastchild = container.lastChild;
var secondlastchild = container.childNodes[container.childNodes.length-2];
lastchild.style.display = 'none';
secondlastchild.style.display = 'none';
//Show TopNav as it is hidden by default in CSS
document.getElementById('WrapperTopNav').style.display = 'block';
//if homepage, set Footer width to 960
if ((document.URL === "http://testsiteqa/Pages/Default.aspx") || (document.URL === "http://testsitetf/Pages/Default.aspx") || (document.URL === "http://testsite/Pages/Default.aspx")){
document.getElementById('Footer').style.width = '960px';
}
}
======================================================>
$(document).ready(){
$('ul li:last-child').hide();
//how do I get the second last li?
$('#WrapperTopNav').css('display','block');
if ((document.URL === "http://testsiteqa/Pages/Default.aspx") || (document.URL === "http://testsitetf/Pages/Default.aspx") || (document.URL === "http://testsite/Pages/Default.aspx")){
$('#Footer').css('width','960px');
}
});
How do I get the second last menu item to hide? Is the above conversion look about right?
You can achieve that by using .eq()
Try,
var cache = $('ul li');
cache.eq(cache.length-1).hide(); //last one
cache.eq(cache.length-2).hide(); //second one from the last
or you can use .prev() to get the previous sibling of the last li element,
var cache = $('ul li:last-child').hide(); //last one
cache.prev().hide(); //second one from the last
Conceptual DEMO
Or as A.wolf suggested we can access the collection reversely by providing index in negative,
var cache = $('ul li');
cache.eq(-1).hide(); //last one
cache.eq(-2).hide(); //second one from the last
I would use this:
$('ul > li:gt(-3)').hide();
That will select the last two li that are direct descendants of the ul and hide them.

Javascript to fade text in, one word at a time, works with one div, but not multiple divs?

I'm trying to fade in one word at a time from a div. The below code works fine for one div but when I have multiple divs, it does not do it sequentially.
Here is the fiddle : http://jsfiddle.net/zlud/6czap/110/
Can anyone see an obvious problem? Any suggestions to print one line after the other would be greatly appreciated. (So the text in the second div will be printed after the first div is done.)
<html>
<div class="example">These are some words that </br> should be faded in one after the other.</div>
<div class="example"> No way some words that </br> should be faded in one after the other.</div>
</html>
JavaScript
var $el = $('.example').map(function () {
return this;
}).get();
$el.forEach(function (eachdiv){
var text = $(eachdiv).text(),
words = text.split(" ");
var html = "";
for (var i = 0; i < words.length; i++) {
html += "<span>" + words[i] + " </span>";
$(eachdiv).html(html).children().hide().each(function(i){
return $(this).delay(i*500).fadeIn(700);``
});
}
});
How about this?
I am assuming you dont need a delay in animation, instead you need them to appear one after the other.
var words, $el;
var arrEl = [];
// loop through each div and populate the array with the container (div) element and its text content split
$('.example').each(function(){
var $this = $(this);
arrEl.push({el:$this,words : $.trim($this.text()).split(" ")});
$this.empty();
});
//This will the startup function
function fadeIn(){
var len = arrEl.length, obj = arrEl.shift() || {}; //get the top item from array and remove it from the array using array.shift
$el = obj.el; //get the container from the item
words = obj.words; //get the array of words
//if there are any items in the array start the animation process for this item.
if(len) window.setTimeout(transitionElement, 0);
}
function transitionElement(){
var wlen = words.length,
span = $('<span/>', {'class':'hide'}).append(" " + words.shift()); //remove and get the top text string from the word array wrap it in span with a class "hide" which will hide it by default
window.setTimeout(function(){
if(wlen) //if words are available anymore then call show word
showWord(span);
else //else call fadeIn to process the next container in the arrEl array of items
fadeIn();
},0);
}
function showWord(span){
span.appendTo($el).fadeIn(500, transitionElement); // append the span to the container with an animation duration of 500ms and in the complete callback of this invoke transitionElement to process the next word or next item. Here there is no delay required since this will invoked only when the transition of first word is completed
}
//Start animation process
fadeIn();
Fiddle
fadeIn() callback syntax
Array.shift
Jquerys animation functions have a callback in the parameter list. This callback will be executed after the animation completes. Or maybe it's that i is passed by reference.
You should pick on div at a time to work on and continue to the next one ones the first is done. Now you attach the delay and fade-in to each word in each div at the same time. Initiate the animation of the second div by a trigger when the first one is done or something like that?

Categories