I have a CSS slider that works for the most part except for two things I cannot figure out. The first being, how to get my slider navigation buttons to work the way I am after. Right now, if you click on one, my addClass adds .active to all of the buttons instead of only the one clicked on. Along with that I cannot figure out how to associate the slider position with the navigation menu. What I mean is if the user does not click any of the buttons I still want the buttons to show which slide is active.
MY second issue is whenever the buttons are clicked it stops the slide show.
What am I doing wrong in my attempts?
Off-topic, but would it be difficult to transition what I have now to fade in the slides rather than sliding them?
$('.control-button').click(function() {
button = $(this).attr('id');
id = button.replace('slide', '');
pos = (id - 1) * 100;
$('div#slider figure').css('animation-play-state', 'paused');
$('div#slider figure').removeClass('figure2');
$('.control-button').addClass('active');
posStr = '-' + pos + '%';
$('.figure').css('left', posStr);
});
$('img').click(function() {
$('div#inner').css('left', '0px');
$('div#slider figure').addClass('figure2');
$('div#slider figure').css('animation-play-state', 'running');
})
div#slider {
width: 100%;
overflow: hidden;
}
div#slider .figure {
position: relative;
width: 400%;
margin: 0;
padding: 0;
font-size: 0;
text-align: left;
/*animation: 20s company-slider infinite;*/
}
.figure2 {
animation: 20s company-slider infinite;
}
#keyframes company-slider {
0% {
left: 0%;
}
30% {
left: 0%;
}
35% {
left: -100%;
}
55% {
left: -100%;
}
60% {
left: -200%;
}
90% {
left: -200%;
}
95% {
left: -300%;
}
100% {
left: -300%;
}
}
div#slider figure img {
width: 25%;
min-height: 100%;
float: left;
}
/*div#slider figure:hover { animation-play-state:paused; }*/
div#slider li {
list-style: none;
}
div#slider label {
background-color: #111;
bottom: .5em;
cursor: pointer;
display: block;
height: .5em;
position: absolute;
width: .5em;
z-index: 10;
}
#controls {
width: 100%;
height: auto;
}
#control-container {
padding: 25px 12%;
}
.control-button {
display: inline;
margin: 0 2%;
width: 25%;
background: gray;
height: 10px;
border: none;
}
.control-button.active {
display: inline;
margin: 0 2%;
width: 25%;
background: black;
height: 10px;
border: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<div id="slider">
<figure class="figure figure2">
<img src="https://iso.500px.com/wp-content/uploads/2016/02/stock-photo-139669245.jpg" alt>
<img src="http://i.cbc.ca/1.3376224.1450794847!/fileImage/httpImage/image.jpg_gen/derivatives/4x3_620/tundra-tea-toss.jpg" alt>
<img src="https://static.pexels.com/photos/22804/pexels-photo.jpg" alt>
<img src="https://iso.500px.com/wp-content/uploads/2016/02/stock-photo-139669245.jpg" alt>
</figure>
<div id="controls">
<div id="control-container">
<button id="slide1" class="control-button"></button>
<button id="slide2" class="control-button"></button>
<button id="slide3" class="control-button"></button>
</div>
</div>
</div>
This makes all of the buttons active:
$('.control-button').addClass('active');
Replace it with:
$('.control-button').removeClass('active');
$(event.target).addClass('active');
Add the event parameter to the function so you can use event.target:
$('.control-button').click(function(event) {
EDIT:
Making the control buttons activate "naturally" as the images slide is a bit harder.
Make each image have an attribute that says which slide it is:
<figure class="figure figure2">
<img data-number="slide1" src="https://iso.500px.com/wp-content/uploads/2016/02/stock-photo-139669245.jpg" alt>
<img data-number="slide2" src="http://i.cbc.ca/1.3376224.1450794847!/fileImage/httpImage/image.jpg_gen/derivatives/4x3_620/tundra-tea-toss.jpg" alt>
<img data-number="slide3" src="https://static.pexels.com/photos/22804/pexels-photo.jpg" alt>
<img data-number="slide4" src="https://iso.500px.com/wp-content/uploads/2016/02/stock-photo-139669245.jpg" alt>
</figure>
Create a system to detect when the image comes into view:
window.setInterval(function() {
Detect which image is being shown:
var activeImage = document.elementFromPoint($(window).width()/2, 10); // The image at the horizontal midpoint of the screen
Set the class of the corresponding control button to active:
$('.control-button').removeClass('active');
$("#"+$(activeImage).attr("data-number")).addClass('active'); // Sets whichever control button that corresponds to the image under the horizontal midpoint of the screen as active
Set how often you want to check at the closing of the setInterval:
}, /*time interval in miliseconds*/);
As far as adding 'active' to all buttons you should replace this:
$('.control-button').addClass('active');
with this:
$('.control-button').removeClass('active'); //this removes all '.active' first
$(this).addClass('active');
What's happening here is that within the .control-button click function, $(this) represents the current .control-button element.
https://jsfiddle.net/q3j01xrs/
What about this? I improved your script. I took out your CSS animation and replaced it by another JavaScript animation. Have a look!
$('.control-button').click(function() {
clearInterval(setInt);
$('.control-button').removeClass('active');
$(this).addClass('active');
var getIndex = $(this).index('.control-button');
$('.figure img').hide();
$('.figure img').eq(getIndex).show();
setInt = setInterval(slide, 5000);
});
function slide() {
var getIndex = $('.figure img:visible').index('.figure img');
$('.control-button').removeClass('active');
$('.figure img:visible').animate({
width: 'toggle'
}, 350);
getIndex++;
if ((getIndex) == $('.control-button').length) {
$('.control-button').eq(0).addClass('active');
$('.figure img').eq(0).animate({
width: 'toggle'
}, 350);
} else {
$('.control-button').eq(getIndex).addClass('active');
$('.figure img').eq(getIndex).animate({
width: 'toggle'
}, 350);
}
};
var setInt = setInterval(slide, 5000);
Related
I'm making a random image that changes when the mouse enter in a div with testarea class.
Mouse enter Div, toggle the 'off-cursor' tag of the image randomly.
I have referred to several sites.
but, I am JS and JQUERY beginners. I don't know how to complete it.
I'd be very grateful if you could help me.
const Cursor = document.querySelectorAll('.cursor');
function getRdCursor() {
const index = Math.floor(Math.random() * Cursor.length);
return Cursor[index];
};
$(function () {
$(".testarea").mousemove(function (e) {
$(".cursor").show().css({
"left": e.clientX,
"top": e.clientY
});
}).mouseout(function () {
$(".cursor").hide();
});
});
.testarea {
border: 1px dashed #ccc;
height: 100px;
margin: 100px 100px 100px 100px;
cursor: none;
}
.cursor {
position: absolute;
width: 5%;
height: auto;
left: -100px;
cursor: none;
pointer-events: none;
transform: translate(-50%,-50%);
}
.off-cursor {
visibility: hidden;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<img src="https://media.giphy.com/media/tJ1jipvvMs4r7xuZnI/giphy.gif" alt="Cursor" class="cursor" />
<img src="https://media.giphy.com/media/XFpIo4jKuUrjQHYHeq/giphy.gif" alt="Cursor" class="cursor off-cursor" />
<img src="https://media.giphy.com/media/uxunn6z4qKrGsND3II/giphy.gif" alt="Cursor" class="cursor off-cursor" />
<img src="https://media.giphy.com/media/XxRl7rbKSFvXEFoNzv/giphy.gif" alt="Cursor" class="cursor off-cursor" />
<div class="testarea"></div>
<div class="testarea"></div>
<div class="testarea"></div>
<div class="testarea"></div>
I miss 1% to finish my script, I just don't know how to do it :D
When you hover over the target to the left, you can see the image will scroll. But after clicking on a new image it won't. I then have to resize the window to make it work again. How to fix that? Below is my code but for a working example, here's a CodePen
(function($) {
// virables
var layoutContainer = '.container';
var layoutTarget = '#target';
var layoutTargetIMG = '#target img';
var layoutIMG = '.container .gallery .item img';
var layoutIMGFirst = '.container .gallery .item:first-child img';
// Add first image to target
$(layoutIMGFirst).clone().appendTo(layoutTarget);
// Add image to target when click on gallery image
$(layoutIMG).click(function() {
$(this).closest(layoutContainer).find(layoutTarget).empty();
$(this).clone().appendTo(
$(this).closest(layoutContainer).find(layoutTarget)
);
});
// Image scroll on hover
// This won't work after clicking on an image unless resizing the browser
$(window).resize(function() {
// If i remove this it won't work on the start image.
// Any other solution?
setTimeout(function() {
$('#target img').each(function() {
var itemHeight = $('#target').outerHeight();
var imgHeight = $(this).outerHeight();
// Work out what percentage the image is of the item and remove 100% from that
var topHeight = (imgHeight / itemHeight) * 100 - 100;
//Make the animation speed proptional to that ratio
var animationSpeed = (imgHeight / itemHeight) / 1; //change 2 to tweak the speed
$(this).css({
transition: 'all ease ' + animationSpeed + 's'
});
$(this).mouseleave(function() {
$(this).css({
top: '0'
});
})
// The 'top' property of the image needs
// to be set as as a percentage of the parent
$(this).mouseenter(function(e) {
$(this).css({
top: '-' + topHeight + '%',
});
})
});
}, 200);
});
$(document).ready(function() {
setTimeout(function() { // Add delay after resize so function will load
$(window).triggerHandler('resize');
}, 200);
});
})(jQuery);
.container {
display: flex;
flex-flow: row wrap;
align-items: flex-start;
margin-left: -40px;
max-width: 1000px;
background: lightblue;
padding: 20px;
.column {
flex: 1;
min-width: 30%;
margin-left: 40px;
.target {
height: 400px;
background: pink;
position: relative;
overflow: hidden;
img {
position: absolute;
top: 0;
left: 0;
width: 100%;
}
}
.cta {
display: flex;
a {
background: lightgreen;
width: 50%;
padding: 16px 8px;
;
text-align: center;
justify-content: center;
text-decoration: none;
&:last-child {
background: orange;
}
}
}
.gallery {
display: flex;
flex-flow: row wrap;
margin-left: -4px;
.item {
flex: 1;
margin-left: 4px;
position: relative;
overflow: hidden;
&::before {
content: '';
padding-top: 80%;
display: block;
}
img {
position: absolute;
min-width: 100%;
min-height: 100%;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
cursor: pointer;
}
}
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="column">
<div id="target" class="target"></div>
<div class="cta">
SE DEMO
KØB LAYOUT
</div>
</div>
<div class="column">
<div class="gallery">
<div class="item">
<img src="https://picsum.photos/600/1200" alt="">
</div>
<div class="item">
<img src="https://picsum.photos/500/1600" alt="">
</div>
<div class="item">
<img src="https://picsum.photos/400/2000" alt="">
</div>
</div>
</div>
</div>
Just change this
$(layoutIMG).click(function() {
$(this).closest(layoutContainer).find(layoutTarget).empty();
$(this).clone().appendTo(
$(this).closest(layoutContainer).find(layoutTarget)
);
});
to
$(layoutIMG).click(function() {
$(this).closest(layoutContainer).find(layoutTarget).empty();
$(this).clone().appendTo(
$(this).closest(layoutContainer).find(layoutTarget)
);
$(window).triggerHandler('resize'); // added this line
});
I have the following code for an image slider. It is a bit complicated because i want to use the slider code for multiple slider elements on the page. See below the code for one slider:
The problem i am having is described at the bottom.
$(document).ready(function(){
$('.vertical_img').first().addClass('display currentvertical_img').removeClass('invisable');
$('.horizontal_img').first().addClass('display currenthorizontal_img').removeClass('invisable');
$('.diagonal_img').first().addClass('display currentdiagonal_img').removeClass('invisable');
// image slider interaction with user
$('.right').click(function(){
next($(this).data('id'));
});
$('.left').click(function(){
previous($(this).data('id'));
});
});
function next(img_class){
var count;
$('.current'+img_class).animate({left: 0}, 500, function(){
console.log("animated?");
$('.current'+img_class).removeClass('display current'+img_class).addClass('invisable previous'+img_class);
if($('.previous'+img_class).is(':last-child')) {
count = $('.'+img_class).first().data('num');
$('.'+img_class).first().removeClass('invisable').addClass('display current'+img_class);
}
else{
$('.previous'+img_class).next().addClass('display current'+img_class).removeClass('invisable');
count = $('.previous'+img_class).next().data('num');
}
$('.'+img_class+'_slider').text(count+'/4');
$('.previous'+img_class).removeClass('previous'+img_class);
});
}
function previous(img_class){
var count;
$('.current'+img_class).removeClass('display current'+img_class).addClass('invisable previous'+img_class).animate({right: 0});
if ( $('.previous'+img_class).is(':first-child')) {
count = $('.'+img_class).last().data('num');
$('.'+img_class).last().removeClass('invisable').addClass('display current'+img_class);
}
else{
$('.previous'+img_class).prev().addClass('display current'+img_class).removeClass('invisable');
count = $('.previous'+img_class).prev().data('num');
}
$('.'+img_class+'_slider').text(count+'/4');
$('.previous'+img_class).removeClass('previous'+img_class);
}
.main_image_slide_container{
position: fixed;
left: 50px;
right:50px;
width: 500px;
height: 500px;
}
.image_slide_container_all_text_wrapper{
width: 100%;
height: auto;
overflow: overlay;
}
.image_slider_title{
float: left;
}
.image_slider_counter{
float: right;
}
.main_image_slide_container .image_slider_counter{
display: none;
}
.image_slide_container_all_text_wrapper .image_slider_counter{
display: block;
}
.slider_images_wrapper_window{
width: 100%;
height: auto;
position: relative;
}
.image_slider_controls{
position: absolute;
z-index: 10;
width: 50%;
height: 100%;
}
.left{
left: 0;
cursor: default;
}
.left:hover{
cursor: url(../../data/cursor_left.png) 40 30, move;
}
.right{
right: 0;
cursor: default;
}
.right:hover{
cursor: url(../../data/cursor_right.png) 40 30, move;
}
.slider_images_container{
width: 100%;
height: auto;
}
.slider_images_container img{
position: relative;
width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="main_image_slide_container">
<div class="image_slide_container_all_text_wrapper">
<div class="image_slider_title big_text font">Gravient Vertical</div>
<div class="image_slider_counter big_text font vertical_img_slider">1/4</div>
</div>
<div class="slider_images_wrapper_window">
<div class="image_slider_controls left" data-id="vertical_img"></div>
<div class="image_slider_controls right" data-id="vertical_img"></div>
<div class="slider_images_container">
<img class="vertical_img invisable" data-num="1" src="https://www.geeky-gadgets.com/wp-content/uploads/2010/06/google-mac-linux1.jpg">
<img class="vertical_img invisable" data-num="2" src="https://images.techhive.com/images/idge/imported/article/ctw/2012/10/19/samsung_chromebook_338-100391696-orig.jpg">
</div>
</div>
<div class="image_slider_counter big_text font vertical_img_slider">1/4</div> <!--mobile counter -->
</div>
So my current problem is that the images are not animating to the left. And i dont know why.. I am pretty sure my animate syntax is correct. I copy pasted it from the jquery website.
All suggestions and tips are welcome.
If something is not clear please let me know so i can clarify it!
You have missed the invisable css. Here is the working Example.
jsfiddle
Here's a function:
function rollImgOnSwipe(direction) {
changeDirection(direction);
rollImage(direction);
}
The first called function (changeDirection(direction);) is supposed to place a div in either the left or right side of the screen, depending on the value of its argument. The second one (rollImage(direction);) is to make the div move from left to right or from right to left, depending on where the first function placed it.
Well, it seems like it first calls rollImage and then changeDirection because it takes rollImgOnSwipe to be called more than once in order for the div to be placed on the other side.
The best way to explain this to you is to show you - run the code snippet and try switching between the divs with the prev and next buttons and see how they behave.
var nextBtn = document.getElementById('next'),
prevBtn = document.getElementById('prev'),
shown = document.getElementsByClassName('shown')[0],
hidden = document.getElementsByClassName('hidden')[0];
function rollImage(direction) {
shown.classList.remove("shown");
shown.classList.add("hidden");
hidden.classList.remove("hidden");
hidden.classList.add("shown");
shown = document.getElementsByClassName('shown')[0];
hidden = document.getElementsByClassName('hidden')[0];
changeDirection(direction);
}
function rollImgOnSwipe(direction) {
changeDirection(direction);
rollImage(direction);
}
function changeDirection(direction) {
hidden.style.left = (105 * direction) + "%";
shown.style.left = 0;
}
nextBtn.addEventListener('click', function () { rollImgOnSwipe(1); });
prevBtn.addEventListener('click', function () { rollImgOnSwipe(-1); });
.img {
position: absolute;
display: block;
width: 80px;
height: 30px;
border-style: solid;
border-color: red;
border-width: 5px;
}
.shown{
left: 0;
transition: left .6s ease, transform .6s ease;
}
.hidden{
left: 105%;
}
.img-wrapper{
position: relative;
width: 80px;
height: 30px;
padding: 30px;
white-space: nowrap;
overflow: hidden;
}
<button id="prev">prev</button>
<div class="img-wrapper">
<div class="img shown"></div>
<div class="img hidden"></div>
</div>
<button id="next">next</button>
To fix this, i make the compiler wait for a bit before calling rollImage by using the setTimeout function in rollImgOnSwipe.
And now the program works as expected:
var nextBtn = document.getElementById('next'),
prevBtn = document.getElementById('prev'),
shown = document.getElementsByClassName('shown')[0],
hidden = document.getElementsByClassName('hidden')[0];
function rollImage(direction) {
shown.classList.remove("shown");
shown.classList.add("hidden");
hidden.classList.remove("hidden");
hidden.classList.add("shown");
shown = document.getElementsByClassName('shown')[0];
hidden = document.getElementsByClassName('hidden')[0];
changeDirection(direction);
}
function rollImgOnSwipe(direction) {
changeDirection(direction);
setTimeout(function() { rollImage(direction); }, 50);
}
function changeDirection(direction) {
hidden.style.left = (105 * direction) + "%";
shown.style.left = 0;
}
nextBtn.addEventListener('click', function(){ rollImgOnSwipe(1); });
prevBtn.addEventListener('click', function(){ rollImgOnSwipe(-1); });
.img {
position: absolute;
display: block;
width: 80px;
height: 30px;
border-style: solid;
border-color: red;
border-width: 5px;
}
.shown{
left: 0;
transition: left .6s ease, transform .6s ease;
}
.hidden{
left: 105%;
}
.img-wrapper{
position: relative;
width: 80px;
height: 30px;
padding: 30px;
white-space: nowrap;
overflow: hidden;
}
<button id="prev">prev</button>
<div class="img-wrapper">
<div class="img shown"></div>
<div class="img hidden"></div>
</div>
<button id="next">next</button>
My question is:
What is the problem and why is it fixed by making the compiler wait?
When hover on the first and second element, some element will animate to the left, it works well if hovered with a normal speed, but will crashed if hovered too fast for some times
(the text won't show or the text won't move back to its original place when mouseoff, checkout the figures below).
Any suggestions would be appreciated.
1.text won't show
2.text won't move back to its original place
$(document).ready(function() {
var flag = false;
$(".tab-ico").hover(function() {
var f = $(this);
f.data('timeout', window.setTimeout(function() {
f.find(".tab-text").stop(true, true).animate({
left: "-=64"
}, 300, function() {
flag = true;
});
}, 300));
}, function() {
clearTimeout($(this).data("timeout"));
if (flag === true) {
$(this).find(".tab-text").stop(true, true).animate({
left: "+=64"
}, 300, function() {
flag = false;
});
}
});
});
.pfm-toolbar-wrap {
height: 100%;
position: fixed;
right: 0;
top: 0;
width: 35px;
z-index: 9990;
}
.pfm-tbar-tab-Spike {
position: relative;
width: 35px;
}
.pfm-toolbar-tabs {
border-right: 5px solid #7a6e6e;
height: 100%;
}
.p-tab div.tab-ico {
background: #7a6e6e;
}
.tab-text {
border-radius: 3px;
color: #fff;
height: 32px;
left: 0px;
line-height: 32px;
position: absolute;
text-align: center;
width: 70px;
padding-right: 5px;
z-index: -1;
background: #7a6e6e;
}
.tab-text a {
color: #fff;
display: block;
}
.p-tab {
left: 0;
margin-top: -100px;
position: absolute;
top: 50%;
width: 35px;
z-index: 9;
text-align: center;
}
.p-tab div.tab-ico:hover {
background: #e20531;
cursor: pointer;
}
.p-tab div.tab-ico:hover .tab-text {
background: #e20531;
}
.tab-ico {
width:35px;
height:35px;
margin-bottom:5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="pfm-toolbar-wrap">
<div class="pfm-toolbar-tabs">
<div class="p-tab">
<div class="pfm-tbar-tab-Spike m_b15">
<div class="tab-ico cart"> <i class="cbl-icon"></i> <em class="tab-text"> text</em>
</div>
</div>
<div class="pfm-tbar-tab-group m_b15">
<div class="tab-ico "> <i class="cbl-icon"></i>
<em class="tab-text"> text2</em>
</div>
</div>
</div>
</div>
</div>
you can use css transition-delay property as follows:
transition-delay: 1s; /* delays for 1 second */
-webkit-transition-delay: 1s; /* for Safari & Chrome */
Find more info here.
I suggest that you use CSS transition, here are two links that will help you make that with less code and using CSS transition
https://css-tricks.com/almanac/properties/t/transition/
https://blog.alexmaccaw.com/css-transitions