Slider using json - javascript

I have a slider. If I upload photos using html, then everything works correctly. As soon as I try to upload files using Json, the block is stretched and the animation does not work smoothly, styles are no longer applied to it. Pictures are loaded cropped. Screenshots below. Where is the mistake?
https://ibb.co/FwbV9Gb
https://ibb.co/hLjpb5p
slider.js
var slideCount = $(".slider ul li").length;
var slideWidth = $(".slider ul li").width();
var slideHeight = $(".slider ul li").height();
var slideUlWidth = slideCount * slideWidth;
$(".slider").css({"max-width":slideWidth, "height": slideHeight});
$(".slider ul").css({"width":slideUlWidth, "margin-left": - slideWidth });
$(".slider ul li:last-child").prependTo($(".slider ul"));
function moveLeft() {
$(".slider ul").stop().animate({
left: + slideWidth
},700, function() {
$(".slider ul li:last-child").prependTo($(".slider ul"));
$(".slider ul").css("left","");
});
}
function moveRight() {
$(".slider ul").stop().animate({
left: - slideWidth
},700, function() {
$(".slider ul li:first-child").appendTo($(".slider ul"));
$(".slider ul").css("left","");
});
}
$(".next").on("click",function(){
moveRight();
});
$(".prev").on("click",function(){
moveLeft();
});
});
html
<div class="img">
<div class="slider">
Next
Prev
<ul id="sliders">
<li> <img src="/img/2.jpg"> </li>
<li><img src="/img/4.jpg"></li>
<li> <img src="/img/5.jpg"> </li>
<li> <img src="/img/6.jpg"> </li>
</ul>
</div>
</div>
add images using JSON (.js)
$(function() {
$.getJSON('catalog.json', function(data) {
$.each(data.catalog, function(i, category) {
const detail= category.details;
const image =detail.images;
const $slider=$(
"<li><img src="+image.one+"></li><li><img src="+image.two+"></li><li><img src="+image.three+"></li><li><img src="+image.four+"></li>"
)
console.log(image.one)
$slider.appendTo("#sliders");
});
});

The problem most likely lies in timing. On page load, all of the variables are calculated for widths etc.. However, your json takes a few seconds to load, therefore the sizes have already been calculated. What I did is create a function for slider creation and add that in the getJson success callback.
var slideCount;
var slideWidth;
var slideHeight;
var slideUlWidth;
$.create_slider = function(){
slideCount = $(".slider ul li").length;
slideWidth = $(".slider ul li").width();
slideHeight = $(".slider ul li").height();
slideUlWidth = slideCount * slideWidth;
$(".slider").css({"max-width":slideWidth, "height": slideHeight});
$(".slider ul").css({"width":slideUlWidth, "margin-left": - slideWidth });
$(".slider ul li:last-child").prependTo($(".slider ul"));
}
function moveLeft() {
$(".slider ul").stop().animate({
left: + slideWidth
},700, function() {
$(".slider ul li:last-child").prependTo($(".slider ul"));
$(".slider ul").css("left","");
});
}
function moveRight() {
$(".slider ul").stop().animate({
left: - slideWidth
},700, function() {
$(".slider ul li:first-child").appendTo($(".slider ul"));
$(".slider ul").css("left","");
});
}
$(".next").on("click",function(){
moveRight();
});
$(".prev").on("click",function(){
moveLeft();
});
});
$(function() {
$.getJSON('catalog.json', function(data) {
$.each(data.catalog, function(i, category) {
const detail= category.details;
const image =detail.images;
const $slider=$(
"<li><img src="+image.one+"></li><li><img src="+image.two+"></li><li><img src="+image.three+"></li><li><img src="+image.four+"></li>"
)
$slider.appendTo("#sliders");
});
$.create_slider();
});

Related

Jquery slider with autoplay doesn't pause on final slide

I'm trying to make a simple slider which stays 5 secondes on each slide (4 elements per slide), then goes back to the first slide and run again.
The number of elements may vary from 1 to 16.
Right now, my slider doesn't pause on last slide. It goes straight back to the first one.
Any ideas ? Thanks
Here is a fiddle.
var width = $(window).width();
var currentSlide = 1;
var $slides = $('ul li');
var itemNbr = document.getElementsByTagName("li").length;
$(function() {
if ( itemNbr > 4) {
setInterval(function () {
$('ul').animate({
'margin-left' : '-='+width}, 700, function () {
currentSlide++;
if (currentSlide >= itemNbr/4) {
currentSlide = 1;
$('ul').animate({
'margin-left' : '0px'},700
);
};
});
},5000);
};
});
You can modify your setInterval function this way :
var width = $(window).width();
var currentSlide = 1;
var $slides = $('ul li');
var itemNbr = document.getElementsByTagName("li").length;
$(function() {
if ( itemNbr > 4) {
setInterval(function () {
if (currentSlide >= itemNbr/4) {
$('ul').animate({'margin-left' : '0px'}, 700);
currentSlide = 1; // Edit
}
else {
$('ul').animate({'margin-left' : '-='+width}, 700);
currentSlide++;
}
},5000);
};
});
wrapper {
width:100%;
overflow:hidden;
}
ul {
width:300vw; height:320px;
list-style:none;
padding:0; margin:0;
overflow:hidden;
}
ul li {
width:80vw;
height:60px;
display:inline-block;
margin:10px 10vw;
background-color:red;
padding:0;
text-align:center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<wrapper>
<ul>
<li>ITEM</li><!--
--><li>ITEM</li><!--
--><li>ITEM</li><!--
--><li>ITEM</li><!--
--><li>ITEM</li><!--
--><li>ITEM</li><!--
--><li>ITEM</li><!--
--><li>ITEM</li><!--
--><li>ITEM</li><!--
--><li>ITEM</li><!--
--><li>ITEM</li>
</ul>
</wrapper>

jQuery page scroll not changing navbar href to active class

I have a one-page website. When I scroll down I want my (fixed) navbar links to change the status to active when reaching the position of that specific div.
I used jQuery but it doesn't work. Here is my code:
// SMOOTH SCROLLING PAGES
$(document).ready(function () {
$(document).on("scroll", onScroll);
//smoothscroll
$('a[href^="#"]').on('click', function (e) {
e.preventDefault();
$(document).off("scroll");
$('a').each(function () {
$(this).removeClass('active');
})
$(this).addClass('active');
var target = this.hash,
menu = target;
$target = $(target);
$('html, body').stop().animate({
'scrollTop': $target.offset().top+2
}, 800, 'swing', function () {
window.location.hash = target;
$(document).on("scroll", onScroll);
});
});
});
function onScroll(event){
var scrollPos = $(document).scrollTop();
$('main-navigation a').each(function () {
var currLink = $(this);
var refElement = $(currLink.attr("href"));
if (refElement.position().top <= scrollPos && refElement.position().top + refElement.height() > scrollPos) {
$('main-navigation ul li a').removeClass("active");
currLink.addClass("active");
}
else{
currLink.removeClass("active");
}
});
};
Here is my HTML:
<nav id="main-navigation">
<ul>
<li class="active">Home</li>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
</nav>
<div id="a">DIV Alpha</div>
<div id="b">DIV Bravo</div>
<div id="c">DIV Charlie</div>
<div id="d">DIV Delta</div>
The smooth scrolling works perfectly, but when I scrolling back up from div #d the navbar li active state doesn't change.
Here, i prepare fiddle for you, i hope it what you looking for - http://jsfiddle.net/skyr9999/dpuvcj5w
<div class="content">
<div id="site-main">DIV Home</div>
<div id="a">DIV Alpha</div>
<div id="b">DIV Bravo</div>
<div id="c">DIV Charlie</div>
<div id="d">DIV Delta</div>
</div>
<nav id="main-navigation">
<ul>
<li><a class="menuitem" href="#site-main">Home</a></li>
<li><a class="menuitem" href="#a">A</a></li>
<li><a class="menuitem" href="#b">B</a></li>
<li><a class="menuitem" href="#c">C</a></li>
<li><a class="menuitem" href="#d">D</a></li>
</ul>
</nav>
js
$(document).ready(function () {
$('a[href^="#site-main"]').addClass('active');
//smoothscroll
$('.menuitem').on('click', function (e) {
e.preventDefault();
// $(document).off("scroll");
var athis = this;
var target = this.hash,
menu = target;
$target = $(target);
$('html, body').stop().animate({
'scrollTop': $target.offset().top + 2
}, 800, 'swing', function () {
window.location.hash = target;
$('.menuitem').removeClass('active');
$(athis).addClass('active');
});
});
$(window).scroll(function (event) {
var scrollPos = $(document).scrollTop();
if (scrollPos === 0)
{
$('a[href^="#site-main"]').addClass('active');
return;
}
$('.menuitem').each(function () {
var currLink = $(this);
var refElement = $(currLink.attr("href"));
if (refElement.position().top <= scrollPos && refElement.position().top + refElement.height() > scrollPos) {
$('.menuitem').removeClass("active");
currLink.addClass("active");
} else {
currLink.removeClass("active");
}
});
})
});
Because you did not include any css, i improvise a little, but it seems works just fine.
css
#a,#b,#c,#d,#site-main { height: 400px;}
#main-navigation {
position: fixed;
top: 0px;
right:10px;
}
#main-navigation ul li {
display: inline;
}
.active {
background: #f00;
}
Update 1
I update code to match fiddle now it change menu item selection when you scrool to item
You have to loop through with the list items instead and correct the id selector with a # notation:
$('#main-navigation li').each(function () { //<---correct id selector
var currLink = $(this);
var refElement = $(currLink.find('a').attr("href")); //<---find the anchor here
if (refElement.position().top <= scrollPos && refElement.position().top + refElement.height() > scrollPos) {
$('#main-navigation ul li').removeClass("active"); //<---and here
currLink.addClass("active");
}
else{
currLink.removeClass("active");
}
});
you can use this cool tiny plugin to achieve this
https://github.com/davist11/jQuery-One-Page-Nav
it will add current class when you are in a specific div or section
Hope this help :)
replace
$('a').each(function () {
$(this).removeClass('active');
})
$(this).addClass('active');
with
$('a').each(function () {
$(this).parent().removeClass('active');
})
$(this).parent().addClass('active');
complete code:
$('a[href^="#"]').on('click', function (e) {
e.preventDefault();
$(document).off("scroll");
$('a').each(function () {
$(this).parent().removeClass('active');
})
$(this).parent().addClass('active');
var target = this.hash,
menu = target;
$target = $(target);
$('html, body').stop().animate({
'scrollTop': $target.offset().top+2
}, 800, 'swing', function () {
window.location.hash = target;
});
});
No need of onScroll function

slider function not running as desired in safari as it does in chrome/firefox

I have a slider function that automatically runs through a group of list items. In Chrome and Firefox, the resting image is the first one after the automatic rotation. Unfortunately, in Safari and IE, it rests on the last image. I thought this might have been a style issue but I'm not using any styles that would cause this. I also thought maybe setInterval() or setTimeout() was causing the inconsistency. I'm not able to lock down what is the cause.
$(function ($) {
var slideCount = $('#slider ul li').length;
var slideWidth = $('#slider ul li').width();
var slideHeight = $('#slider ul li').height();
var sliderUlWidth = slideCount * slideWidth;
$('#slider').css({ width: slideWidth, height: slideHeight });
$('#slider ul').css({ width: sliderUlWidth, marginLeft: - slideWidth });
$('#slider ul li:last-child').prependTo('#slider ul');
function moveLeft() {
$('#slider ul').animate({
left: + slideWidth
}, 800, function () {
$('#slider ul li:last-child').prependTo('#slider ul');
$('#slider ul').css('left', '');
});
};
function moveRight() {
$('#slider ul').animate({
left: - slideWidth
}, 800, function () {
$('#slider ul li:first-child').appendTo('#slider ul');
$('#slider ul').css('left', '');
});
};
$('.sa-left').click(function () {
moveLeft();
clearInterval(auto);
});
$('.sa-right').click(function () {
moveRight();
clearInterval(auto);
});
var auto = setInterval(moveRight, 1000);
var stopOnSlide = slideCount*1000+1000;
window.setTimeout(function(){
clearInterval(auto);
$( '.sa-left , .sa-right' ).delay(1000).fadeIn('slow');
}, stopOnSlide);
});
What am I missing here? I've researched this specific issue and haven't found a clue as to what this issue might be.
<div id="container">
<div id="sliderContainer">
<div id="slider">
<div class="slider-arrow sa-left"><img src='arrowLeft.png'/></div>
<div class="slider-arrow sa-right"><img src='arrowRight.png'/></div>
<ul>
<li id='toggle1'><img src="t1.png"></li>
<li id='toggle2'><img src="t2.png"></li>
<li id='toggle3'><img src="t3.png"></li>
</ul>
</div>
</div>
</div>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<!-- crucial scripts -->
<script type="text/javascript" src="https://s0.2mdn.net/ads/studio/Enabler.js"></script>
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.0.min.js"></script>
/<!-- plugin scripts -->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.18.0/TweenLite.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.18.0/TimelineLite.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.18.0/plugins/CSSPlugin.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.18.0/easing/EasePack.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/draggabilly/1.2.0/draggabilly.pkgd.min.js"></script>
<!-- custom scripts -->
<script type="text/javascript" src="script.js"></script>
Updated JS
$(function ($) {
var slider = $('#slider ul');
var slideCount = $('#slider ul li').length;
var slideWidth = $('#slider ul li').width();
var slideHeight = $('#slider ul li').height();
var sliderUlWidth = slideCount * slideWidth;
var transitionDuration = 400;
var sliderDuration = 4000;
var activeSlide = 1;
var autoSlide;
var setAuto = true;
$('#slider').css({ width: slideWidth, height: slideHeight, overflow: 'hidden',position:'relative' });
$('#slider ul').css({ width: sliderUlWidth, position: 'absolute'});
function sliderAnimate() {
clearInterval(autoSlide);
slider.animate({
left: -(activeSlide-1)*slideWidth
},transitionDuration);
if(setAuto){
autoSlideHandler();
}
};
sliderAnimate();
function autoSlideHandler(){
autoSlide = setInterval(function(){
if(activeSlide<slideCount){
activeSlide++;
sliderAnimate();
}else {
swapFirstToLast();
setAuto = false;
$( '.sa-left , .sa-right' ).fadeIn('slow');
sliderAnimate()
}
},sliderDuration);
}
$('.sa-left').click(function () {
if(activeSlide >1){
activeSlide--;
sliderAnimate();
}else {
swapLastToFirst();
sliderAnimate()
}
});
$('.sa-right').click(function () {
if(activeSlide < slideCount){
activeSlide++;
sliderAnimate();
}else {
swapFirstToLast();
sliderAnimate()
}
});
function swapFirstToLast(){
var firstSlide = slider.find('li:first-child');
slider.append(firstSlide.clone());
slider.css('left',-(activeSlide-2)*slideWidth);
firstSlide.remove()
}
function swapLastToFirst(){
var lastChild = slider.find('li:last-child');
slider.prepend(lastChild.clone()).css('left',-(activeSlide)*slideWidth);
lastChild.remove();
}
});
Working demo using your code
Updated demo(continuous slider)

How to stop mouseenter function when mouseout

This is the code I'm using for a slider
jQuery(document).ready(function ($) {
setInterval(function () {
moveRight();
}, 1000);
var slideCount = $('#slider ul li').length;
var slideWidth = $('#slider ul li').width();
var slideHeight = $('#slider ul li').height();
var sliderUlWidth = slideCount * slideWidth;
$('#slider').css({ width: slideWidth, height: slideHeight });
$('#slider ul').css({ width: sliderUlWidth, marginLeft: - slideWidth });
$('#slider ul li:last-child').prependTo('#slider ul');
function moveLeft() {
$('#slider ul').animate({
left: + slideWidth
}, 200, function () {
$('#slider ul li:last-child').prependTo('#slider ul');
$('#slider ul').css('left', '');
});
};
function moveRight() {
$('#slider ul').animate({
left: - slideWidth
}, 200, function () {
$('#slider ul li:first-child').appendTo('#slider ul');
$('#slider ul').css('left', '');
});
};
$('a.control_prev').click(function () {
moveLeft();
});
$('a.control_next').click(function () {
moveRight();
});
});
I tried creating a function that makes the slideshow slower on hover and go back to normal why the cursor is off of it. This is my code.
function moveNot() {
$('#slider ul').animate({
left: - slideWidth
}, 20000, function () {
$('#slider ul li:first-child').appendTo('#slider ul');
$('#slider ul').css('left', '');
});
};
$('#slider').mouseover(function () {
moveNot();
});
$('#slider').mouseout(function () {
setInterval(function () {
moveRight();
}, 1000);
});
I was able to make the slider go slower, but the mouseout or mouseleave (tried both) don't work, I don't know what else to do.
How would I stop the slider on hover and make the slider go when the mouse is off?
Please try the following code.
jQuery(document).ready(function ($) {
var slidetime = 500;
var t;
$('#slider li').on('mouseout',function(){
slidetime = 500;
clearInterval(t);
startAnimation();
});
$('#slider li').on('mouseenter',function(){
//slidetime = 1000; if want to make it slower uncomment it
clearInterval(t);
//startAnimation(); if want to make it slower uncomment it
});
function startAnimation(){
t = setInterval(function () {
moveRight();
}, slidetime);
}
startAnimation();
var slideCount = $('#slider ul li').length;
var slideWidth = $('#slider ul li').width();
var slideHeight = $('#slider ul li').height();
var sliderUlWidth = slideCount * slideWidth;
$('#slider').css({ width: slideWidth, height: slideHeight });
$('#slider ul').css({ width: sliderUlWidth, marginLeft: - slideWidth });
$('#slider ul li:last-child').prependTo('#slider ul');
function moveLeft() {
$('#slider ul').animate({
left: + slideWidth
}, slidetime, function () {
$('#slider ul li:last-child').prependTo('#slider ul');
$('#slider ul').css('left', '');
});
};
function moveRight() {
$('#slider ul').animate({
left: - slideWidth
}, slidetime, function () {
$('#slider ul li:first-child').appendTo('#slider ul');
$('#slider ul').css('left', '');
});
};
});
li{
width:100px;
height:100px;
float:left;
display:block;
}
ul:nth-child(even){
background:red;
}
ul:nth-child(odd){
background:black;
color:red;
}
ul{
display:inline-flex;
}
#slider{
width:100px;
overflow:hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="slider">
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
</ul>
</div>
Here is the JSfiddle Link
An obvious issue with your code is the mouseout function, that it would repeatedly setInterval. Note that you need to call clearInterval() to "un-register" the function if you want it stops running...
To your question
How would I stop the slider on hover and make the slider go when the mouse is off?
You might try something like this:
var myVar; // rename it to something makes sense to you
$('#slider').mouseover(function(){
clearInterval(myVar);
});
$('#slider').mouseout(function (){
myVar = setInterval(function(){
moveRight();
}, 1000);
});
Take a look at the clearInterval function here.
Before anything you should add the setInterval to a variable and you can clear it with clearInterval() before calling the same function again. I guess you should pass time as an argument in the specific function:
jQuery(document).ready(function ($) {
var time,
callRight = function(time){
time = setInterval(function () {
moveRight(time);
}, time);
};
callRight(200); // <----call it here
// other code as is
});
Now these are the changes you should use:
function moveRight(time) {// <----pass the duration here.
$('#slider ul').stop(true, true).animate({
left: -slideWidth
}, time, function() {// <----add the duration here.
$('#slider ul li:first-child').appendTo('#slider ul');
$('#slider ul').css('left', '');
});
};
function moveNot(time) { // <----pass the duration here.
$('#slider ul').stop(true, true).animate({
left: -slideWidth
}, time, function() { // <----add the duration here.
$('#slider ul li:first-child').appendTo('#slider ul');
$('#slider ul').css('left', '');
});
};
$('#slider').on('mouseenter mouseleave', function(e) {
if(e.type === 'mouseenter' && time){
clearInterval(time);
moveNot(20000);
} else {
callRight(200);
}
});
Use instead hover instead of mouseover and mouseout
$('#slider').hover(function(){
moveNot()
},function () {
setInterval(function(){
moveRight()
}, 1000)
});

How to add prev and next button in a JQuery slideshow code

I have jQuery code for a slideshow below. It works perfectly in the project I am working on right now. Although, I would like to implement a previous and next button in the same code if it's possible. Any help would be really appreciated.
<script type="text/javascript">
function() {
$(".slider #1").show("fade",500);
$(".slider #1").delay(5500).hide("slide",{direction:"left"},500);
var sc = $(".slider img").size();
var count = 2;
setInterval(function(){
$(".slider #"+count).show("slide",{direction:"right"},500);
$(".slider #"+count).delay(5500).hide("slide",{direction:"left"},500);
if(count == sc){
count = 1;
}
else
{
count=count+1;
}
},6500);
}
</script>
<div class="slider">
<img id="1" src="images/slider/slide1.jpg" border="0" alt="primeira" />
<img id="2" src="images/slider/slide2.jpg" border="0" alt="segunda" />
<img id="3" src="images/slider/slide3.jpg" border="0" alt="terceira" />
</div>
<style>
.slider {
width: 800px;
height: 349px;
overflow:hidden;
margin: 30px auto;
background-image: url(images/slider/load.GIF);
background-repeat: no-repeat;
background-position: center;
}
.slider img {
width: 800px;
height: 349px;
display: none;
}
</stile>
You can do the following:
var sc;
var count = 1;
$(document).ready(function() {
sc = $(".slider img").size();
$(".slider #1").show("fade",500);
setInterval(function(){
switchPanel(1);
},5500);
$("#prev").click(function(){switchPanel(-1)});
$("#next").click(function(){switchPanel(1)});
});
function switchPanel(direction)
{
var hide, show;
if (direction == 1)
{
show = "right";
hide = "left";
}
else if (direction == -1)
{
show = "left";
hide = "right";
}
$(".slider #"+count).hide("slide",{direction:hide},500);
count = count + direction;
if(count == sc + 1) count = 1;
else if(count == 0) count = sc;
$(".slider #"+count).show("slide",{direction:show},500);
}
What's left for you is to add the previous (#prev) and next (#next) buttons.
This should be works.
$(".slider #1").show("fade",500);
$(".slider #1").delay(5500).hide("slide",{direction:"left"},500);
var sc = $(".slider img").size();
var count = 2;
var hideImage;
var slideshow;
var slideImage = function(isNext) {
var showDirection;
if (isNext){
showDirection = "right";
} else {
showDirection = "left";
}
$(".slider #"+count).show("slide",{direction:showDirection},500);
hideImage = setTimeout(function(){
$(".slider #"+count).hide("slide",{direction:"left"},500);
count = (count+1) > sc ? 1 : count+1;
}, 5500);
}
// Start the slideshow
slideshow = setInterval(function(){
slideImage(true);
},6500);
var manualSlide = function(isNext) {
// Stop the slideshow
clearTimeout(hideImage);
clearInterval(slideshow);
// Force hide current image
var hideDirection = isNext ? "left" : "right";
$(".slider #"+count).hide("slide",{direction:hideDirection},500);
if(isNext) {
count = (count+1) > sc ? 1 : count+1;
} else {
count = (count-1) == 0 ? sc : count-1;
}
setTimeout(function(){
slideImage(isNext);
// Start the slideshow again
slideshow = setInterval(function(){
slideImage(true);
},6500);
}, 1000);
}
$("#prev").on("click", function() { manualSlide(false); });
$("#next").on("click", function() { manualSlide(true); });
This is the result: FIDDLE
Note: I have to change delay into setTimeout because we can't cancel delay.

Categories

Resources