I am trying to create a news slider that consists of a big slide area (picture and heading) and a second area to the left which contains a simple list of all the slides.
I've managed to get the slider to work so that you can click on one of the list items and this then changes the slide.
However, I'd also like the slider to animate by default through all the slides. I'd like clicking on a list item to override the animation and make the animation loop go to the point in the loop at which the current slide is at. So if the user clicks slide 2, the next slide to be animated to will be slide 3. I'd also like hovering over a slide to pause the animation.
Any ideas how I can achieve the animation/hover part? I am new to jQuery so pretty confused.
This is what I've come up with so far:
var $newsitem = jQuery('.featured-news');
var $newsitem1 = jQuery('.featured-news.item-1');
var $newsitem2 = jQuery('.featured-news.item-2');
var $newsitem3 = jQuery('.featured-news.item-3');
var $newslistitem1 = jQuery( '.newslist.item-1' );
var $newslistitem2 = jQuery( '.newslist.item-2' );
var $newslistitem3 = jQuery( '.newslist.item-3' );
// click actions
$newslistitem1.click(function () {
$newsitem.hide();
$newsitem1.fadeIn();
});
$newslistitem2.click(function () {
$newsitem.hide();
$newsitem2.fadeIn();
});
$newslistitem3.click(function () {
$newsitem.hide();
$newsitem3.fadeIn();
});
// timed actions
animate();
function animate() {
$newsitem1.delay(4000).hide();
$newsitem2.delay(4000).fadeIn();
$newsitem2.delay(4000).hide();
$newsitem3.delay(4000).fadeIn();
}
HTML:
<ul>
<li class="newslist item-1">
News item 1
</li>
<li class="newslist item-2">
News item 2
</li>
<li class="newslist item-3">
News item 3
</li>
</ul>
<ul>
<li class="featured-news item-1">
<img src="http://placehold.it/350x150">
<br>News Story 1
</li>
<li class="featured-news item-2" style="display: none">
<img src="http://placehold.it/350x150">
<br>News Story 2
</li>
<li class="featured-news item-3" style="display: none">
<img src="http://placehold.it/350x150">
<br>News Story 3
</li>
</ul>
And here's a fiddle:
http://jsfiddle.net/HdDG6/
here is how I modified your code :
First, setup global variables :
var $newsitem = $('.featured-news');
// global variable of the current slide
var current = 0;
// global variable interval, which will call "nextSlide" func every 3s
var interval = setInterval(nextSlide, 3000);
I updated your slide list click function so it become general. You won't need to setup every slide click event now :
// attach event to every list item
$('.newslist').click(function () {
// clear the interval
clearInterval(interval);
// set it back to reset the timer
interval = setInterval(nextSlide,3000);
// set current slide var to .newslist item index (0, 1, 2,...)
current = $(this).index();
// hide every shown item
$newsitem.hide();
// show item which index = current slide index
$newsitem.eq(current).fadeIn();
});
Then I created the nextSlide function which will increment current before hiding every slides and showing the current one as $('.newslist').click function
function nextSlide () {
// if current slide is the last one, go back to the first, else increment
if (current == $newsitem.length - 1) {
current = 0;
} else {
current++;
}
// hide every slides and show the good one
$newsitem.hide();
$newsitem.eq(current).fadeIn();
}
Then I finally set the hover event, which simply clear the timer when mouse enter .featured-news and set it back on mouse leave :
$('.featured-news').hover(function(ev){
clearInterval(interval);
}, function(ev){
interval = setInterval(nextSlide,3000);
});
Here is a working fiddle : DEMO
This way you can add as many slides as you want without changing the code. You can also bind nextSlide function to any button or control (like arrow keys or a "next slide" button).
Hope I helped you :)
Related
i would like to ask how to make loop fadeIn and fadeout every 2 items from unorder list. I trying to do this with jQuery but my loop only take 1 by 1 item.
<div>
<ul>
<li>item1</li> // will be first display
<li>item2</li> // will be first display
<li>item3</li> // will be second display
<li>item4</li> // will be second display
<li>item5</li> // will be third display
</ul>
</div>
My javaScript code. I try to split array for 2 elements each array then im trying to fade out it.
function slide(elements) {
var perChunk = 2
var inputArray = Array.from(elements[0].children);
var result = inputArray.reduce((resultArray, item, index) => {
const chunkIndex = Math.floor(index/perChunk)
if(!resultArray[chunkIndex]) {
resultArray[chunkIndex] = []
}
resultArray[chunkIndex].push(item)
return resultArray
}, [])
console.log('res',result);
$(inputArray).hide();
setInterval(function() {
result.map(el => {
$(el).show().fadeIn();
});
}, 2000);
}
Using .slice() you can select a range of elements, then each time increase the start of that range.
With the help of this question to call a function when all elements have finished .fadeOut() (otherwise you get a callback per element), gives:
var items = $("ul>li");
var pos = 0;
var count = 2;
items.hide().slice(pos, pos+count).show();
setInterval(() => {
$.when(items.slice(pos, pos+count).fadeOut())
.then(function() {
pos += count;
if (pos>items.length)
pos = 0;
items.slice(pos, pos+count).fadeIn();
});
}, 1000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<ul>
<li>item1</li>
<li>item2</li>
<li>item3</li>
<li>item4</li>
<li>item5</li>
</ul>
</div>
There are, of course, many different ways to do this, for example using $("ul>li").each((idx) => and comparing the idx (index) value or using a setTimeout instead of the $.when to fadeIn when fadeOut has completed.
If you are just doing two list items together each time:
In your for loop increment i by 2 each time and set i and i+1 to visible, fadein and the rest to hidden, fadeout. With your example have 5 items, I would put a check to make sure the i+1 is not greater than your set list length.
for(i=0;i<list_length;i+=2){
//Add fade out ability here if you want it to happen before the fadein
$(list[i]).fadin();
$(list[i+1]).fadein();
//Add fade out ability here if you want it to happen after the fadein
}
If you are no just make every other item in your list fade in and out. Set an id for the ones you want to pair together, then loop over your list and fadein and fadeout which ones want active at a time. If this is the option you are looking for I can add some example code but I think you are looking for the first option.
does anyone know how to add an additional "Next slide" button to a Slick Slider? I am already using the dots, and the previous & next arrows, but on the first slide I need to add an additional "Next Slide Button" (for design purposes). Suggestions...help...
Basically a button that advances to the next slide (so on tab-slick-index="0" go to tab-slick-index="1"). This button would only show on the first slide.
Check out the https://kenwheeler.github.io/slick/ Methods section.
Possible Solution
Add your button <button id="nextSlideBtn">Next Slide Button</button> inside the first slide.
ES6
const button = document.getElementById('nextSlideBtn');
const nextSlide = (slider) => {
$(slider).slick('slickNext');
};
button.addEventListener('click', () => {
nextSlide(<YOUR SLIDER>);
});
ES5
var button = document.getElementById('nextSlideBtn');
var nextSlide = function nextSlide(slider) {
$(slider).slick('slickNext');
};
button.addEventListener('click', function () {
return nextSlide(<YOUR SLIDER>);
});
I am using Basic JQuery Slider, How can I get the active/current number, I am using multiple sliders.
var bannerslides = $('#banner-slides').bjqs({
animtype : 'slide'
});
var bannerslides2 = $('#banner-slides2').bjqs({
animtype : 'slide'
});
EDIT
$scope.update = function() {
//Need to get slider number here, like
console.log(bannerslides.index());
}
HTML:
<div id="banner-slides">
<ul class="bjqs>
<li>
...
</li>
<li>
...
</li>
</ul>
I actually need it in on a click event of button to decide an action.
Modified plugin to get current slide number.
Just added a function to return active/current slide.
Above the init(); return this; at the end of the file bjqs-1.3.js
Add the following function.
this.getactiveslide = function() {
return state.currentindex;
};
And called this console.log(bannerslides.getactiveslide());
Hope this helps and saves someones time in future.
I have a nav set up that when a link is clicked, the page scrolls down to the corresponding item in a list, changing the class of the link when the item is reached.
<nav>
one
two </nav>
<ul>
<li id="one"></li>
<li id="two"></li>
</ul>
Here is a rather crude example
http://jsfiddle.net/FSk5Q/1/
I would also like to change the background colour of the item once it is reached (preferably fading to a new colour), and then restore it's original class when another item is scrolled to, then changing the next item's class.
I need this to happen when clicked to AND scrolled to, so the :target option is not really ideal.
Many thanks for an advice. Not too good in the js department.
Hopefully this can at least get you started. What I have done is check that the offset top is less than the document's scroll top (you could also do something like if it's within X number of pixels).
The color fading can be done with CSS3 transitions.
$(document).on('scroll', function () {
$("li").each(function () {
if ($(this).offset().top <= $(document).scrollTop()) {
$("li").removeClass('highlight');
$(this).addClass('highlight');
}
else {
$(this).removeClass('highlight');
}
});
});
http://jsfiddle.net/FSk5Q/6/
I did a fixed version based on Explosion Pills' one. Hope it's what you wanted.
$(document).on('scroll', function ()
{
$("nav a").removeClass('highlight'); // reset all menu items
temp = $();
$("li").each(function (i) // for each content blcok (you schould give them a class)
{
if ($(this).offset().top <= $(document).scrollTop()) // if it's position is above/at the page top
{
temp = $("nav a:nth-child("+(i+1)+")");
}
});
temp.addClass('highlight');
});
http://jsfiddle.net/maxmeuten/FSk5Q/8/
<ul>
<li>one</li>
<li>two</li>
<li>three</li>
</ul>
I'd like to show only one li at a time using slide effect, thats it. I'd like to avoid using plugins for something as simple as this.
Thanks in advance for your help.
i have made something simple up for you (based on your description), just to point you in the right direction:
check it out here:
http://jsfiddle.net/meo/ACenH/234/
function slider(container, delay){
$container = $(container) // select the container elements and store them in a variable
if ( !$container.length ){ return fasle; } // checks if the slider exists in your dom. if not the function ends here...
var slides = $container.length, // gives back the total LI's you have
slide = 0 // set the actual li to show
setInterval(function(){ // set a Interval for your main function
if (slide == slides - 1) { // if the actual slide is equal the total slides (-1 because eq is 0 based and length gives back the number of elements in the jQuery object) the slide counter is set to 0
$container.slideDown(); // and all slides a shown again
slide = 0;
} else {
$container.eq(slide).slideUp(); //slides the selected slide up i think you could think of a solution with .next() instead of eq()
slide++; // slide counter +1
}
}, delay)
}
slider('ul > li', 2000); // call your slider function
Your question already mentions jquery as the javascript framework of choice. The best place you can start is the jquery docs on hiding:
http://api.jquery.com/hide/
and sliding:
http://api.jquery.com/slideUp/
http://api.jquery.com/slideDown/
http://api.jquery.com/slideToggle/