So, I'm trying to copy apple.com style of carousel. I wanted to have timer pagination so so far I have this much done: jsfiddle
How can I replace pagination buttons with progress bars? Here is what I have so far:
$(document).ready(function() {
var time = 2;
var $bar,
$slick,
isPause,
tick,
percentTime;
$slick = $('.slider');
$slick.slick({
draggable: true,
adaptiveHeight: false,
dots: true,
mobileFirst: true,
pauseOnDotsHover: true,
});
$bar = $('.slider-progress .progress');
$('.slider-wrapper').on({
mouseenter: function() {
isPause = true;
},
mouseleave: function() {
isPause = false;
}
})
function startProgressbar() {
resetProgressbar();
percentTime = 0;
isPause = false;
tick = setInterval(interval, 10);
}
function interval() {
if (isPause === false) {
percentTime += 1 / (time + 0.1);
$bar.css({
width: percentTime + "%"
});
if (percentTime >= 100) {
$slick.slick('slickNext');
startProgressbar();
}
}
}
function resetProgressbar() {
$bar.css({
width: 0 + '%'
});
clearTimeout(tick);
}
startProgressbar();
});
.slider-wrapper {
width: 600px;
}
.slider {
width: 600px;
height: 400px;
border: 1px solid #000;
}
.slide {
width: 100%;
height: 398px;
background: #ccc;
}
#slick-1 .slick-dots li {
width: 40px;
height: 5px;
background: #ccc;
}
#slick-1 .slick-dots li button {
width: 40px;
height: 5px;
}
#slick-1 .slick-dots li.slick-active,
#slick-1 .slick-dots li:hover {
background: #777;
}
#slick-1 .slick-dots li button,
#slick-1 .slick-dots li button:before {
color: transparent;
opacity: 0;
}
/* progress bar */
.slider-progress {
width: 100%;
height: 3px;
background: #eee;
}
.slider-progress .progress {
width: 0%;
height: 3px;
background: #000;
}
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<script src="https://cdn.jsdelivr.net/jquery.slick/1.6.0/slick.min.js"></script>
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://cdn.jsdelivr.net/jquery.slick/1.6.0/slick.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick-theme.min.css" rel="stylesheet"/>
<div class="slider-wrapper" id="slick-1">
<div class="slider">
<div class="slide">slider #1</div>
<div class="slide">slider #2</div>
<div class="slide">slider #3</div>
</div>
<div class="slider-progress">
<div class="progress"></div>
</div>
</div>
Just had to do this for my company yesterday.
It was a bit trickier because slick is implemented on our website with 2 transitions : swipe if we use the mouse, fade if we don't..
Anyway, I remembered your post when i was digging a bit yesterday so I made it simpler here.
$(".slider").slick({
infinite: true,
arrows: false,
dots: false,
autoplay: false,
speed: 800,
slidesToShow: 1,
slidesToScroll: 1,
});
//ticking machine
var percentTime;
var tick;
var time = 1;
var progressBarIndex = 0;
$('.progressBarContainer .progressBar').each(function(index) {
var progress = "<div class='inProgress inProgress" + index + "'></div>";
$(this).html(progress);
});
function startProgressbar() {
resetProgressbar();
percentTime = 0;
tick = setInterval(interval, 10);
}
function interval() {
if (($('.slider .slick-track div[data-slick-index="' + progressBarIndex + '"]').attr("aria-hidden")) === "true") {
progressBarIndex = $('.slider .slick-track div[aria-hidden="false"]').data("slickIndex");
startProgressbar();
} else {
percentTime += 1 / (time + 5);
$('.inProgress' + progressBarIndex).css({
width: percentTime + "%"
});
if (percentTime >= 100) {
$('.single-item').slick('slickNext');
progressBarIndex++;
if (progressBarIndex > 2) {
progressBarIndex = 0;
}
startProgressbar();
}
}
}
function resetProgressbar() {
$('.inProgress').css({
width: 0 + '%'
});
clearInterval(tick);
}
startProgressbar();
// End ticking machine
$('.progressBarContainer div').click(function () {
clearInterval(tick);
var goToThisIndex = $(this).find("span").data("slickIndex");
$('.single-item').slick('slickGoTo', goToThisIndex, false);
startProgressbar();
});
h3 {
margin:5px 0;
}
.sliderContainer {
position: relative;
}
.slider {
width: 500px;
margin: 30px 50px 50px;
}
.slick-slide {
background: #3a8999;
color: white;
padding: 80px 0 120px;
font-size: 30px;
font-family: "Arial", "Helvetica";
text-align: center;
}
.slick-prev:before,
.slick-next:before {
color: black;
}
.slick-dots {
bottom: -30px;
}
.slick-slide:nth-child(odd) {
background: #e84a69;
}
.progressBarContainer {
position: absolute;
bottom: 20px;
width:300px;
left:150px;
}
.progressBarContainer div {
display: block;
width: 30%;
padding: 0;
cursor: pointer;
margin-right: 5%;
float: left;
color: white;
}
.progressBarContainer div:last-child {
margin-right: 0;
}
.progressBarContainer div span.progressBar {
width: 100%;
height: 4px;
background-color: rgba(255, 255, 255, 0.4);
display: block;
}
.progressBarContainer div span.progressBar .inProgress {
background-color: rgba(255, 255, 255, 1);
width: 0%;
height: 4px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.0/jquery-ui.min.js"></script>
<script src="https://rawgit.com/kenwheeler/slick/master/slick/slick.js"></script>
<link href="https://rawgit.com/kenwheeler/slick/master/slick/slick-theme.css" rel="stylesheet"/>
<link href="https://rawgit.com/kenwheeler/slick/master/slick/slick.css" rel="stylesheet"/>
<div class="sliderContainer">
<div class="slider single-item">
<div>Slide1</div>
<div>Slide2</div>
<div>Slide3</div>
</div>
<div class="progressBarContainer">
<div>
<h3>Slide 1</h3>
<span data-slick-index="0" class="progressBar"></span>
</div>
<div>
<h3>Slide 2</h3>
<span data-slick-index="1" class="progressBar"></span>
</div>
<div>
<h3>Slide 3</h3>
<span data-slick-index="2" class="progressBar"></span>
</div>
</div>
</div>
[codepen][1]
Regards,
I am not entirely entirely familiar with these, but it seems you have been able to get the progressbar running, so it should not be that hard to turn the pagination buttons to progressbars.
What might help is that each of them has an element id (first is "slick-slide00") and the active one has a class "slick-active".
So if you want a hacky solution it might be enough to retrieve "slick-active" element every time the the slide changes (there should be listenable event for that) and turn the element with "slick-active" class into a progress bar.
For a "cleaner" solution you might need to dig into framework itself as the feature doesn't seem to be supported as of now.
Related
I've found this script for a progress bar. It runs smoothly from 100% to 0% after clicking the button.
But how can I reset the progress bar after it hits the 0? I'm planning to use this script in a slideshow and it should be 100% again after it reaches 0.
Hope you can help me in the right direction.
Thnx,
Leon
document.querySelector("button").addEventListener("click", () => {
document.querySelector(".progress .bar").style.transitionDuration = "10s";
document.querySelector(".progress").className += " complete";
});
.progress {
width: 50%;
height: 2em;
border: 1px solid black;
}
.bar {
width: 100%;
background-color: deepskyblue;
color: white;
text-align: center;
line-height: 2em;
transition-property: width;
transition-timing-function: linear;
}
.progress.complete .bar {
width: 0%;
}
button {
margin-top: 1em;
}
<div class="progress">
<div class="bar">Loading...</div>
</div>
<button>
Start
</button>
You can reset the progress bar by removing the complete class.
document.querySelector("button.start").addEventListener("click", () => {
document.querySelector(".progress .bar").style.transitionDuration = "10s";
document.querySelector(".progress").className += " complete";
});
document.querySelector("button.reset").addEventListener("click", () => {
let className = document.querySelector(".progress").className;
if (className.indexOf(' complete') > -1) {
className = className.substr(0, className.indexOf(' complete'));
document.querySelector(".progress .bar").style.transitionDuration = "0s";
document.querySelector(".progress").className = className;
}
});
.progress {
width: 50%;
height: 2em;
border: 1px solid black;
}
.bar {
width: 100%;
background-color: deepskyblue;
color: white;
text-align: center;
line-height: 2em;
transition-property: width;
transition-timing-function: linear;
}
.progress.complete .bar {
width: 0%;
}
button {
margin-top: 1em;
}
<div class="progress">
<div class="bar">Loading...</div>
</div>
<button class="start">
Start
</button>
<button class="reset">
Reset
</button>
If you want this to be dynamic without any user interaction, you can use setTimeout, set to the same duration used in your animationDuration, within your click event Handler to reset the transition and remove the complete class.
const start = document.querySelector("#start")
const progressBar = document.querySelector(".progress .bar")
const progress = document.querySelector(".progress")
function resetProgressBar(){
progressBar.style.transitionDuration = "10s"
progress.classList.add("complete")
setTimeout(() => {
progress.classList.remove("complete")// <-- remove the class with width:0
progressBar.style.transitionDuration = "0.1s" //<-- Add a very small transitionDuration or none if you prefer
}, 10000)// <-- Set this timeout duration to the same as your transitionDuration
}
start.addEventListener("click", resetProgressBar);
.progress {
width: 50%;
height: 2em;
border: 1px solid black;
}
.bar {
width: 100%;
background-color: deepskyblue;
color: white;
text-align: center;
line-height: 2em;
transition-property: width;
transition-timing-function: linear;
}
.progress.complete .bar {
width: 0%;
}
button {
margin-top: 1em;
}
<div class="progress">
<div class="bar">Loading...</div>
</div>
<button id="start">
Start
</button>
For selector .progress .bar, use a listener for event transitionend, because you are using transition rules in css:
The transitionend event is fired when a CSS transition has completed.
Inside this event listener, set transitionDuration to the default value. And in the next step, remove class complete from .progress, which will return the previous width of the progress bar.
document.querySelector("button").addEventListener("click", () => {
document.querySelector(".progress .bar").style.transitionDuration = "10s";
document.querySelector(".progress").className += " complete";
});
document.querySelector(".progress .bar").addEventListener("transitionend", () => {
document.querySelector(".progress.complete .bar").style.transitionDuration = "";
document.querySelector(".progress").classList.remove("complete");
});
.progress {
width: 50%;
height: 2em;
border: 1px solid black;
}
.bar {
width: 100%;
background-color: deepskyblue;
color: white;
text-align: center;
line-height: 2em;
transition-property: width;
transition-timing-function: linear;
}
.progress.complete .bar {
width: 0%;
}
button {
margin-top: 1em;
}
<div class="progress">
<div class="bar">Loading...</div>
</div>
<button>
Start
</button>
Thnx for all your suggestions. I've implemented the last suggestion into my slideshow script.
It is running and it is refreshing after slide change. But somewhere on the ride it stops, I think it's confused when to start the progress bar.
Anyone an idea to make this more solid?
jQuery('.owl-carousel').owlCarousel({
items: 1,
margin: 0,
nav: false,
dots: false,
slideBy: 1,
rewind: false,
autoplay: true,
autoplayTimeout: 5000,
autoplaySpeed: 10000,
loop: true,
animateOut: 'fadeOut',
responsive: false,
mouseDrag: false,
touchDrag: false,
lazyLoadEager: 2
});
jQuery('.owl-carousel').on('changed.owl.carousel', function(event) {
document.querySelector(".progress .bar").style.transitionDuration = "5s";
document.querySelector(".progress").className += " complete";
})
document.querySelector(".progress .bar").addEventListener("transitionend", () => {
document.querySelector(".progress.complete .bar").style.transitionDuration = "5";
document.querySelector(".progress").classList.remove("complete");
});
.progress {
width: 50%;
height: 2em;
border: 1px solid black;
}
.bar {
width: 100%;
background-color: deepskyblue;
color: white;
text-align: center;
line-height: 2em;
transition-property: width;
transition-timing-function: linear;
}
.progress.complete .bar {
width: 0%;
}
button {
margin-top: 1em;
}
<div class="progress">
<div class="bar">Loading...</div>
</div>
<button>
Start
</button>
I basically want the centre image in the slider to be twice as big as the others. I need to be able to pass the class active to the centre image and remove it from the last image. So that the centre image is always twice as big. Is it possible to do this with my code?
$(document).ready(function(){
// function active_class(){
// $(".active").next().addClass('active');
// $(".img_cont").index(1).addClass('jiji');
// }
// active_class();
var slide_count = $(".carousel li").length;
var slide_width = $(".carousel li").width();
var slide_height = $(".carousel li").height();
var total_width = slide_width * slide_count;
$(".cont").css({ height: slide_height, width: slide_width, paddingLeft: slide_width , paddingRight: slide_width });
$(".carousel").css({ width: total_width, marginLeft: - slide_width});
$(".carousel li:last-child").prependTo(".carousel");
$("#next").css("right", slide_width);
$("#prev").css("left", slide_width);
function next_slide(){
$(".carousel").animate({
left: + slide_width
}, 400, function(){
$(".carousel li:last-child").prependTo(".carousel");
$('.carousel').css('left', 0);
}
);
}
function prev_slide(){
$(".carousel").animate({
left: - slide_width
}, 400, function(){
$(".carousel li:first-child").appendTo(".carousel");
$(".carousel").css("left", 0);
}
);
}
$("#next").click(function(){
next_slide();
});
$("#prev").click(function(){
prev_slide();
});
var interval_time = 4000; // 1s
var mouse_hover_flag = false;
$(".cont").hover(function(){
mouse_hover_flag = true;
}, function () {
mouse_hover_flag = false;
});
setInterval(function() {
if (!mouse_hover_flag) {//if not true
next_slide();
}
}, interval_time);
});
*{
padding: 0;
margin: 0;
}
body{
margin: 0;
padding: 0;
}
.cont{
position: relative;
text-align: center;
font-size: 0;/*removes white space*/
margin: 60px auto 0 auto;
padding: 0;
overflow: hidden;
}
.carousel{
position: relative;
margin: 0;
padding: 0;
list-style-type: none;
height: 100%;
max-height: 600px;
}
.carousel li{
float: left;
width: 750px;
height: 350px;
}
.carousel li img{
width: 100%;
height: auto;
}
#next{
position: absolute;
top: 45%;
right: 0;
width: 40px;
height: 40px;
background-color: blue;
font-size: 0;
z-index: 1;
}
#prev{
position: absolute;
top: 45%;
left: 0;
width: 40px;
height: 40px;
background-color: blue;
z-index: 1;
}
.img_cont{
transform: scale(0.5);
}
.active{
transform: scale(1);
}
<div class="cont">
<div id="next">
</div>
<div id="prev">
</div>
<ul class="carousel">
<li class="img_cont active">
<img src="http://lorempixel.com/output/abstract-q-c-1500-700-2.jpg" alt="" />
</li>
<li class="img_cont">
<img src="http://lorempixel.com/output/abstract-q-c-1500-700-6.jpg" alt="" />
</li>
<li class="img_cont">
<img src="http://lorempixel.com/output/abstract-q-c-1500-700-1.jpg" alt="" />
</li>
<li class="img_cont">
<img src="http://lorempixel.com/output/abstract-q-c-1500-700-3.jpg" alt="" />
</li>
</ul>
</div>
<script
src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
https://codepen.io/Reece_Dev/pen/OgQLjE
It's easy to remove active class from all li elements, select the first and add the class again.
For example:
function next_slide(){
$(".carousel").animate({
left: + slide_width
}, 400, function(){
$(".carousel li:last-child").prependTo(".carousel");
$('.carousel').css('left', 0);
// Add the following line to prev_slide too:
$('.carousel li').removeClass('active').eq(0).addClass('active');
}
);
}
I need a slider with timer pagination on dots, like http://www.apple.com. I used slick.js. Instead of dots, I need to make a progress bar.
How can I replace pagination buttons with progress bars?
$(document).ready(function () {
$('.slider').slick({
infinite: true,
autoplay:true,
dots: true,
arrows: false,
autoplaySpeed: 3000,
slidesToShow: 1,
slidesToScroll: 1
});
});
.slider .slick-dots {
padding: 0;
}
.slider .slick-dots li {
position: relative;
display: inline-block;
width: 19%;
height: 15px;
margin: 0 2px 0 0;
padding: 0;
cursor: pointer;
background: #ccbdb6;
transition: width 5s ease-out 0s;
}
.slider .slick-dots li:last-child {
margin-right: 0;
}
.slider .slick-dots li:hover,
.slider .slick-dots li.slick-active {
background: #a08a7f;
}
.slider .slick-dots li button {
display: none !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/jquery.slick/1.6.0/slick.css"/>
<div class="slider">
<div>
<h3>1</h3>
</div>
<div>
<h3>2</h3>
</div>
<div>
<h3>3</h3>
</div>
<div>
<h3>4</h3>
</div>
<div>
<h3>5</h3>
</div>
</div>
<script type="text/javascript" src="//cdn.jsdelivr.net/jquery.slick/1.6.0/slick.min.js"></script>
Just had to do this for my company yesterday.
It was a bit trickier because slick is implemented on our website with 2 transitions : swipe if we use the mouse, fade if we don't..
Anyway, I remembered your post when i was digging a bit yesterday so I made it simpler here.
$(".slider").slick({
infinite: true,
arrows: false,
dots: false,
autoplay: false,
speed: 800,
slidesToShow: 1,
slidesToScroll: 1,
});
//ticking machine
var percentTime;
var tick;
var time = 1;
var progressBarIndex = 0;
$('.progressBarContainer .progressBar').each(function(index) {
var progress = "<div class='inProgress inProgress" + index + "'></div>";
$(this).html(progress);
});
function startProgressbar() {
resetProgressbar();
percentTime = 0;
tick = setInterval(interval, 10);
}
function interval() {
if (($('.slider .slick-track div[data-slick-index="' + progressBarIndex + '"]').attr("aria-hidden")) === "true") {
progressBarIndex = $('.slider .slick-track div[aria-hidden="false"]').data("slickIndex");
startProgressbar();
} else {
percentTime += 1 / (time + 5);
$('.inProgress' + progressBarIndex).css({
width: percentTime + "%"
});
if (percentTime >= 100) {
$('.single-item').slick('slickNext');
progressBarIndex++;
if (progressBarIndex > 2) {
progressBarIndex = 0;
}
startProgressbar();
}
}
}
function resetProgressbar() {
$('.inProgress').css({
width: 0 + '%'
});
clearInterval(tick);
}
startProgressbar();
// End ticking machine
$('.progressBarContainer div').click(function () {
clearInterval(tick);
var goToThisIndex = $(this).find("span").data("slickIndex");
$('.single-item').slick('slickGoTo', goToThisIndex, false);
startProgressbar();
});
h3 {
margin:5px 0;
}
.sliderContainer {
position: relative;
}
.slider {
width: 500px;
margin: 30px 50px 50px;
}
.slick-slide {
background: #3a8999;
color: white;
padding: 80px 0 120px;
font-size: 30px;
font-family: "Arial", "Helvetica";
text-align: center;
}
.slick-prev:before,
.slick-next:before {
color: black;
}
.slick-dots {
bottom: -30px;
}
.slick-slide:nth-child(odd) {
background: #e84a69;
}
.progressBarContainer {
position: absolute;
bottom: 20px;
width:300px;
left:150px;
}
.progressBarContainer div {
display: block;
width: 30%;
padding: 0;
cursor: pointer;
margin-right: 5%;
float: left;
color: white;
}
.progressBarContainer div:last-child {
margin-right: 0;
}
.progressBarContainer div span.progressBar {
width: 100%;
height: 4px;
background-color: rgba(255, 255, 255, 0.4);
display: block;
}
.progressBarContainer div span.progressBar .inProgress {
background-color: rgba(255, 255, 255, 1);
width: 0%;
height: 4px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.0/jquery-ui.min.js"></script>
<script src="https://rawgit.com/kenwheeler/slick/master/slick/slick.js"></script>
<link href="https://rawgit.com/kenwheeler/slick/master/slick/slick-theme.css" rel="stylesheet"/>
<link href="https://rawgit.com/kenwheeler/slick/master/slick/slick.css" rel="stylesheet"/>
<div class="sliderContainer">
<div class="slider single-item">
<div>Slide1</div>
<div>Slide2</div>
<div>Slide3</div>
</div>
<div class="progressBarContainer">
<div>
<h3>Slide 1</h3>
<span data-slick-index="0" class="progressBar"></span>
</div>
<div>
<h3>Slide 2</h3>
<span data-slick-index="1" class="progressBar"></span>
</div>
<div>
<h3>Slide 3</h3>
<span data-slick-index="2" class="progressBar"></span>
</div>
</div>
</div>
[codepen][1]
Regards,
Even though this question has a lot of down-votes, I'll leave my solution here as I thought it was pretty neat.
It's done entirely using CSS (animations) and the trick is to give each slide an ::after containing the progress bar which on .slick-active gets animated from scaleX(0) to scaleX(1).
Something like:
#keyframes scale-x-zero-to-max {
0% {
transform: scaleX(0);
}
100% {
transform: scaleX(1);
}
}
.slick-slide {
&:after {
background: blue;
display: block;
content: "";
width: 100%;
height: .25rem;
position: absolute;
left: 0;
bottom: 0;
z-index: 99;
transform: scaleX(0);
transform-origin: left 50%;
}
&.slick-active:after {
animation: scale-x-zero-to-max 6s linear .8s 1 forwards; // Note that 6s should be same as Slick's autoplaySpeed and .8s same as speed
}
}
The only issue is that on the first ever slide the .8s delay is incorrect (the slide is already visible and doesn't spend .8s sliding into view). This wasn't an issue for us as the slideshow was below the fold and so most visitors will never notice it. After the first slide has completed it works as it should for all subsequent slides.
I have created a plugin with slick slider have progress bar inside each indicators.
https://github.com/gsushil999/Slick-Slider-Plugin
enter code here
<div class="sliderContainer">
<div class="slider single-item">
<div>Slide1</div>
<div>Slide2</div>
<div>Slide3</div>
</div>
<div class="progressBarContainer">
<div>
<span data-slick-index="0" class="progressBar"></span>
</div>
<div>
<span data-slick-index="1" class="progressBar"></span>
</div>
<div>
<span data-slick-index="2" class="progressBar"></span>
</div>
</div>
</div>
<script>
$(".slider").slick({
infinite: true,
arrows: false,
dots: false,
autoplay: false,
speed: 500,
slidesToShow: 1,
slidesToScroll: 1
});
//ticking machine
var percentTime;
var tick;
var time = 1;
var progressBarIndex = 0;
var progress = $('.inProgress');
$('.progressBarContainer .progressBar').each(function (index) {
var progress = "<div class='inProgress inProgress" + index + "'></div>";
$(this).html(progress);
});
function startProgressbar() {
resetProgressbar();
percentTime = 0;
tick = setInterval(interval, 10);
}
function interval() {
if (($('.slider .slick-track div[data-slick-index="' + progressBarIndex + '"]').attr("aria-hidden")) === "true") {
progressBarIndex = $('.slider .slick-track div[aria-hidden="false"]').data("slickIndex");
console.log(progressBarIndex);
if (progressBarIndex == 1) {
$(".inProgress0").addClass('on');
$(".inProgress1").removeClass('on');
}
else if (progressBarIndex == 2) {
$(".inProgress0").addClass('on');
$(".inProgress1").addClass('on');
}
else if (progressBarIndex == 0) {
$(".inProgress0").removeClass('on');
$(".inProgress1").removeClass('on');
}
startProgressbar();
} else {
percentTime += 1 / (time + 2);
$('.inProgress' + progressBarIndex).css({
width: percentTime + "%"
});
if (percentTime >= 100) {
$('.single-item').slick('slickNext');
//console.log(progressBarIndex);
if (progressBarIndex == 0) {
$(".inProgress0").addClass('on');
}
else if (progressBarIndex == 1) {
$(".inProgress0").addClass('on');
$(".inProgress1").addClass('on');
}
else if (progressBarIndex == 2) {
$(".inProgress0").removeClass('on');
$(".inProgress1").removeClass('on');
}
progressBarIndex++;
if (progressBarIndex > 2) {
progressBarIndex = 0;
}
startProgressbar();
}
}
}
function resetProgressbar() {
$('.inProgress').css({
width: 0 + '%'
});
clearInterval(tick);
}
startProgressbar();
// End ticking machine
$('.progressBarContainer div').click(function () {
clearInterval(tick);
var goToThisIndex = $(this).find("span").data("slickIndex");
$('.single-item').slick('slickGoTo', goToThisIndex, false);
startProgressbar();
});
</script>
I have a function that creates a grid of divs that are generated and sent to a container div when the document loads (or when the user resets it). When one hovers over the divs, they highlight (change color). When the user clicks the highlighted div, it changes to black. For some reason, the div that was black reverts back to the original color when I hover over a different div. I'm puzzled as to why that is. Any help or guidance would be greatly appreciated. Here's my jsfiddle example: https://jsfiddle.net/psyonix/1g9p59bx/79/
var d = ("<div class='square'></div>");
function createGrid(numSquares) {
var area = $('#g_area');
var squareSize = Math.floor(area.innerWidth() / numSquares);
for (var i = 0, len = (numSquares * numSquares); i < len; i++) {
area.append(d);
}
$('.square')
.height(squareSize)
.width(squareSize)
.hover(
function () {
$(this).css({
'background-color': '#FFFFFF'
});
}, function () {
$(this).css({
'background-color': '#C8C8C8'
});
})
.click(
function () {
$(this).css({
'background-color': '#000000'
});
});
}
function resetGrid() {
$(".square").remove();
}
$(document).ready(function () {
createGrid(8);
$("#button").click(function () {
var numSquares = prompt("Please enter the size");
resetGrid(numSquares);
createGrid(numSquares);
});
});
Once you click on a DIV, you should maintain a flag that tells you hover function to stop changing colors
$('.square')
.height(squareSize)
.width(squareSize)
.hover(
function () {
if ($(this).data("clicked")) return; //ADDED LINE
$(this).css({
'background-color': '#FFFFFF'
});
}, function () {
if ($(this).data("clicked")) return; //ADDED LINE
$(this).css({
'background-color': '#C8C8C8'
});
})
.click(
function () {
$(this).data("clicked", true); //ADDED LINE
$(this).css({
'background-color': '#000000'
});
});
it changed because of hover function.
https://jsfiddle.net/1g9p59bx/82/
$('.square')
.height(squareSize)
.width(squareSize)
.hover(
function () {
if($(this).hasClass('active'))return;
$(this).css({
'background-color': '#FFFFFF'
});
}, function () {
if($(this).hasClass('active'))return;
$(this).css({
'background-color': '#C8C8C8'
});
})
.click(
function () {
$(this).addClass('active');
$(this).css({
'background-color': '#000000'
});
});
For some reason, the div that was black reverts back to the original color when I hover over a different div
Not quite. It reverts to the original colour when you leave the current div, because that's what you tell it in the second argument to $('.square').hover. You would need to remember that the square was clicked, and build extra logic into the "unhover" function.
Fortunately, there is an easier way: use CSS. Note the very bottom of the CSS definitions.
var d = ("<div class='square'></div>");
function createGrid(numSquares) {
var area = $('#g_area');
var squareSize = Math.floor(area.innerWidth() / numSquares);
for (var i = 0, len = (numSquares * numSquares); i < len; i++) {
area.append(d);
}
$('.square')
.height(squareSize)
.width(squareSize)
.click(function () {
$(this).addClass('clicked');
});
}
function resetGrid() {
$(".square").remove();
}
$(document).ready(function () {
createGrid(8);
$("#button").click(function () {
var numSquares = prompt("Please enter the size");
resetGrid(numSquares);
createGrid(numSquares);
});
});
.container {
background-color: #252525;
width: 600px;
height: 700px;
margin: 0 auto;
border-radius: 5px;
}
.inner {
background-color: #C8C8C8;
position: absolute;
width: 580px;
height: 600px;
margin-right: 10px;
margin-left: 10px;
margin-top: 10px;
border-radius: 5px;
}
.knob {
background-color: #575759;
width: 60px;
height: 60px;
border-radius: 60px;
}
#left_b {
position: absolute;
margin-left: 30px;
margin-top: 625px;
margin-bottom: 10px;
}
#button {
position: absolute;
margin-left: 265px;
margin-top: 640px;
margin-bottom: 10px;
}
#right_b {
position: absolute;
margin-left: 510px;
margin-top: 625px;
margin-bottom: 10px;
}
#g_area {
background-color: #C8C8C8;
position: relative;
width: 580px;
height: 600px;
margin-right: auto;
margin-left: auto;
margin-top: auto;
border-radius: 5px;
overflow: hidden;
}
.square {
display: inline-block;
position: relative;
margin: 0 auto;
}
.highlight {
background-color: #FFFFFF;
outline: #C8C8C8;
outline: 1px;
outline: solid;
margin: 0 auto;
}
.square {
background-color: #C8C8C8;
}
.square:hover {
background-color: #FFFFFF;
}
.square.clicked {
background-color: #000000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div class="container">
<div class="outer">
<div class="inner">
<div id="g_area"></div>
</div>
<div class="knob" id="left_b"></div>
<div id="button">
<button>RESET</button>
</div>
<div class="knob" id="right_b"></div>
</div>
</div>
</body>
I've tried various different things to implement this but nothing seems to work for me i am trying to make the current progress bar have functionality e.g goes according to when each slide changes, and also add tabs that will allow a user to jump to a slide on click.
Demo Fiddle
Html
<div class="omega_player">
<ul class="omega_slides">
<li>SLIDE 1</li>
<li style="background: #aaa;">SLIDE 2</li>
<li>SLIDE 3</li>
<li style="background: #aaa;">SLIDE 4</li>
</ul>
<ul class="omega_controls">
<div class="omega_timer"><div class="progress"></div></div>
<div class="omega_set">
<a onclick="return false" class="control_prev"><i class="fa fa-angle-left"></i></a>
<a onclick="return false" class="control_play"><i class="fa fa-play"></i></a>
<a onclick="return false" class="control_pause"><i class="fa fa-pause"></i></a>
<a onclick="return false" class="control_next"><i class="fa fa-angle-right"></i></a>
</div>
</ul>
</div>
JS
jQuery(document).ready(function ($) {
timer = setInterval(function () {
moveRight();
}, 8000);
var slideCount = $('.omega_player>.omega_slides>li').length;
var slideWidth = $('.omega_player>.omega_slides>li').width();
var slideHeight = $('.omega_player>.omega_slides>li').height();
var sliderUlWidth = slideCount * slideWidth;
$('.omega_player').css({ width: slideWidth, height: slideHeight });
$('.omega_player>.omega_slides').css({ width: sliderUlWidth, marginLeft: - slideWidth });
$('.omega_player>.omega_slides>li:last-child').prependTo('.omega_player>.omega_slides');
function moveLeft() {
$('.omega_player>.omega_slides').animate({
left: + slideWidth
}, 200, function () {
$('.omega_player>.omega_slides>li:last-child').prependTo('.omega_player>.omega_slides');
$('.omega_player>.omega_slides').css('left', '');
});
};
function moveRight() {
$('.omega_player>.omega_slides').animate({
left: - slideWidth
}, 200, function () {
$('.omega_player>.omega_slides>li:first-child').appendTo('.omega_player>.omega_slides');
$('.omega_player>.omega_slides').css('left', '');
});
};
$('.omega_player>.omega_controls>.omega_set>.control_prev').click(function () {
clearInterval(timer);
$('.omega_player>.omega_controls>.omega_set>.control_play').show();
$('.omega_player>.omega_controls>.omega_set>.control_pause').hide();
moveLeft();
});
$('.omega_player>.omega_controls>.omega_set>.control_next').click(function () {
clearInterval(timer);
$('.omega_player>.omega_controls>.omega_set>.control_play').show();
$('.omega_player>.omega_controls>.omega_set>.control_pause').hide();
moveRight();
});
$('.omega_player>.omega_controls>.omega_set>.control_play').click(function () {
$('.omega_player>.omega_controls>.omega_set>.control_play').hide();
$('.omega_player>.omega_controls>.omega_set>.control_pause').show();
moveRight();
timer = setInterval(function () {
moveRight();
}, 8000);
});
$('.omega_player>.omega_controls>.omega_set>.control_pause').click(function () {
clearInterval(timer);
$('.omega_player>.omega_controls>.omega_set>.control_play').show();
$('.omega_player>.omega_controls>.omega_set>.control_pause').hide()
});
return timer;
});
CSS
.omega_player {
position: relative;
overflow: hidden;
margin: 0 auto;
width: 950px;
border-radius: 4px;
}
.omega_player>.omega_slides {
position: relative;
margin: 0;
padding: 0;
height: 450px;
list-style: none;
}
.omega_player>.omega_slides>li {
position: relative;
display: block;
float: left;
margin: 0;
padding: 0;
width: 950px;
height: 450px;
background: #ccc;
text-align: center;
line-height: 300px;
}
.omega_player>.omega_controls {
bottom: 0;
left: 0;
right: 0;
height: 50px;
margin: 0;
padding: 0;
background: #333;
background: rgba(51,51,51,.8);
position: absolute;
z-index: 2;
width: 100%;
}
.omega_player>.omega_controls>.omega_set {
position: absolute;
right: 20px;
}
.omega_player>.omega_controls>li>.control_prev,
.omega_player>.omega_controls>li>.control_next {
position: absolute;
top: 40%;
z-index: 999;
display: block;
padding: 4% 3%;
width: auto;
height: auto;
background: #2a2a2a;
color: #fff;
text-decoration: none;
font-weight: 600;
font-size: 18px;
opacity: 0.8;
cursor: pointer;
}
.omega_player>.omega_controls>li>.control_prev:hover,
.omega_player>.omega_controls>li>.control_next:hover {
opacity: 1;
-webkit-transition: all 0.2s ease;
}
.omega_player>.omega_controls>li>.control_prev {
border-radius: 0 2px 2px 0;
}
.omega_player>.omega_controls>li>.control_next {
right: 0;
border-radius: 2px 0 0 2px;
}
.omega_player>.omega_controls>li>.control_play,
.omega_player>.omega_controls>li>.control_pause {
background-color: green;
color: #fff;
padding: 10px;
}
.omega_player>.omega_controls>li>.control_play {
display: none!important;
}
.omega_player>.omega_controls>.omega_set>a {
color: #FFF;
color: rgba(250,250,250,.95);
font-size: 20px;
vertical-align: middle;
padding: 10px;
display: inline-block;
cursor: pointer;
}
.omega_player>.omega_controls>.omega_set>:hover {
background: rgba(0,0,0,0.2);
color: #FFF;
}
.omega_player>.omega_controls>.omega_set>.control_prev,
.omega_player>.omega_controls>.omega_set>.control_next,
.omega_player>.omega_controls>.omega_set>.control_play,
.omega_player>.omega_controls>.omega_set>.control_pause {
font-size: 45px;
line-height: 0;
margin: 0;
height: 50px;
width: 50px;
padding: 0;
text-align: center;
transition: .1s ease-in-out;
border: 1px solid #FFF;
border-color: rgba(250,250,250,0.65);
border-top: 0;
border-bottom: 0;
float: left;
}
.omega_player>.omega_controls>.omega_set>.control_play,
.omega_player>.omega_controls>.omega_set>.control_pause {
border:0;
font-size: 25px;
line-height: 48px;
}
.omega_player>.omega_controls>.omega_set>.control_play {
display:none;
}
.omega_player>.omega_controls>.omega_timer {
background: #333;
background: rgba(51,51,51,.9);
height: 4px;
top: -4px;
position: absolute;
left: 0;
right: 0;
width: 100%;
}
.omega_player>.omega_controls>.omega_timer>.progress {
height: 4px;
display: inline-block;
background-color: #EB0000;
background: rgba(235, 0, 0, 0.86);
position: absolute;
width: 60%;
z-index: 999;
}
html,
body {margin:0;padding:0;font-family: sans-serif;font-size: 14px;}
Hope you can help thanks in advance!
Code with 4 Slides and Full Screen DEMO
Code with 8 Slides and Full Screen DEMO
Here you go. I have just written a function which will calculate progressbar's width based on number of elements present and active slide. Below is how the function looks like:
function progress(){
var activeElement=$('li:nth-child(2)').attr('data-slide');
//get the activeElement which will be always as 2nd child as per your code
var width=(increment*activeElement)+'%';
//increment variable will be based on `100/numberofslidespresent`
//each li should have a data-* property, say data-slide here, which will actually
//contain number in incremental order. Now multiply increment and activeElement
//and add % so that it will become something like 25%, 50% everytime.
$('.progress').animate({
'width':width //animate width of progressbar
},300);
}
Here is the complete code:
Html
<div class="omega_player">
<ul class="omega_slides">
<li data-slide="1">SLIDE 1</li>
<li data-slide="2" style="background: #aaa;">SLIDE 2</li>
<li data-slide="3">SLIDE 3</li>
<li data-slide="4" style="background: #aaa;">SLIDE 4</li>
<!--extra property added to each li which data-slide with incremental number-->
</ul>
<ul class="omega_controls">
<div class="omega_timer"><div class="progress"></div></div>
<div class="omega_set">
<a onclick="return false" class="control_prev"><i class="fa fa-angle-left"></i></a>
<a onclick="return false" class="control_play"><i class="fa fa-play"></i></a>
<a onclick="return false" class="control_pause"><i class="fa fa-pause"></i></a>
<a onclick="return false" class="control_next"><i class="fa fa-angle-right"></i></a>
</div>
</ul>
</div>
JS
var increment; // a global variable
jQuery(document).ready(function ($) {
timer = setInterval(function () {
moveRight();
}, 8000);
var slideCount = $('.omega_player>.omega_slides>li').length;
increment=100/slideCount; //get how much to increment parts should be
var slideWidth = $('.omega_player>.omega_slides>li').width();
var slideHeight = $('.omega_player>.omega_slides>li').height();
var sliderUlWidth = slideCount * slideWidth;
$('.omega_player').css({ width: slideWidth, height: slideHeight });
$('.omega_player>.omega_slides').css({ width: sliderUlWidth, marginLeft: - slideWidth });
$('.omega_player>.omega_slides>li:last-child').prependTo('.omega_player>.omega_slides');
progress();//call this function once prepended on page load
function moveLeft() {
$('.omega_player>.omega_slides').animate({
left: + slideWidth
}, 200, function () {
$('.omega_player>.omega_slides>li:last-child').prependTo('.omega_player>.omega_slides').addClass('active');
progress(); //after prepending call it once again
$('.omega_player>.omega_slides').css('left', '');
});
};
function moveRight() {
$('.omega_player>.omega_slides>li').removeClass('active')
$('.omega_player>.omega_slides').animate({
left: - slideWidth
}, 200, function () {
$('.omega_player>.omega_slides>li:first-child').appendTo('.omega_player>.omega_slides');
progress(); //after appending call it once again
$('.omega_player>.omega_slides').css('left', '');
});
};
//Your other functions here remains as it is so I haven't attached them
});
function progress(){
var activeElement=$('li:nth-child(2)').attr('data-slide');
var width=(increment*activeElement)+'%';
$('.progress').animate({
'width':width
},300);
}
CSS
On CSS part I just changed width mentioned for progressbar from 60% to
0%