I need help with my previous button for my slideshow. My next button works just fine but everytime I press previous it does a kind of shuffle mode and retrieves the pictures in a random order. If anyone could please help that would be great! I'm fairly new to JavaScript so please be patient and clear.
HTML
<div class="container">
<header>
<nav class="clearfix">
<div class="menu">
<ul>
<li>Home</li>
<li>About</li>
<li>Before/After</li>
<li>Facilities</li>
<li>Contact</li>
<li>Staff</li>
</ul>
</div>
<p id="menu">Menu</p>
<div class="site-wrapper">
<div class="header">
<a><div class="menu-trigger" title="Menu"></div></a>
</div>
</div>
<script src="script.js" type="text/javascript"></script>
</nav>
<img src="img/logoBRB.png"/>
<h1>Brad's Auto Body</h1>
<p id="quote"><i>"Dedicated To Perfection"</i></p>
</header>
<section class="slideshow" id="slideshow">
<figure>
<img class="mySlides" src="img/corengine.jpg" width="100%">
</figure>
<figure>
<img class="mySlides" src="img/corseat.jpg" width="100%">
</figure>
<figure>
<img class="mySlides" src="img/blah.jpg" width="100%">
</figure>
<figure>
<img class="mySlides" src="img/blah2.jpg" width="100%">
</figure>
<figure class="show">
<img class="mySlides" src="img/cor.jpg" width="100%">
</figure>
<span class="prev">«</span> <span class="next">»</span>
</section>
<footer>
<div class="social">
<ul>
<li>
<i class="fa fa-facebook fa-2x" id="fa"></i>
</li>
</ul>
</div>
<p>©Copyright 2016. Brad’s Auto Body. All Rights Reserved.</p>
<p>Web Design by<img class="logo" src="img/logoJJC.png">JJC Web Developers</p>
</footer>
<script src="slideshow.js"></script>
<script src="https://code.jquery.com/jquery-2.2.1.min.js" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js" type="text/javascript"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.js" type="text/javascript"></script>
<script src="https://github.com/mattbryson/TouchSwipe-Jquery-Plugin" type="text/javascript"></script>
</div>
JavaScript
var counter = 0, // to keep track of current slide
$items = $('.slideshow figure'), // a collection of all of the slides, caching for performance
numItems = $items.length; // total number of slides
// this function is what cycles the slides, showing the next or previous slide and hiding all the others
var showCurrent = function() {
var itemToShow = Math.abs(counter % numItems); // uses remainder (aka modulo) operator to get the actual index of the element to show
$items.removeClass('show'); // remove .show from whichever element currently has it
$items.eq(itemToShow).addClass('show');
};
// add click events to prev & next buttons
$('.next').on('click', function() {
showCurrent();
counter++;
});
$('.prev').on('click', function() {
showCurrent();
counter--;
});
// if touch events are supported then add swipe interactions using TouchSwipe https://github.com/mattbryson/TouchSwipe-Jquery-Plugin
var $el = $('#slideshow');
$el.slideshow({
duration: 400,
delay: 3000,
selector: '> img',
transition: 'push(up)',
autoPlay: true,
show: function(params) {
var nextIndex = params.next.index;
if (nextIndex > 2) {
// do something awesome when the slide is after the third slide.
}
},
complete: function(params) {
// do something awesome when a transition finishes
}
});
// get the slideshow object if you want it
var slideshow = $el.data('slideshow');
// show the third slide
$el.slideshow('show', 2); // Element API
slideshow.show(2); // object API
// show the next slide
slideshow.show('next');
// pause and play
slideshow.stop();
slideshow.play();
CSS
#slideshow {
background-color: solid transparent;
padding: 0;
}
.slideshow {
position: relative;
display: block;
overflow: hidden;
height: 500px;
width: auto;
}
.show {
transition: opacity 2s;
opacity: 1;
position: relative;
zoom: 110%;
}
.mySlides {
height: 500px;
}
figure {
transition: opacity 0;
opacity: 0;
position: absolute;
margin: 0;
}
.next, .prev {
color: #fff;
position: absolute;
background: rgba(0,0,0,.6);
top: 50%;
z-index: 1;
font-size: 2em;
margin-top: -.75em;
opacity: .3;
user-select: none;
}
.next:hover, .prev:hover {
cursor: pointer;
opacity: 1;
}
.next {
right: 0;
padding: 10px 5px 15px 10px;
border-top-left-radius: 3px;
border-bottom-left-radius: 3px;
}
.prev {
left: 0;
padding: 10px 10px 15px 5px;
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
}
Im really not sure how your slider even works by selecting the figure using modulo. I would suggest you to keep track of the figure element that has the show class and change the counter based on that.
First, when Javascript is loaded, you should set the counter variable to the index of the figure which has the show class. This can be achived with the following function (or just add it straigth to the variable declaration):
function getShowIndex() {
return $('#slideshow figure').index($('.show'));
}
Then, change to next or previous image by adding or subtracting from the counter. Though, there are two exceptions:
When going from the last image to the first the counter value should be changed to 0.
Likewise from the firt to the last the counter value should be changed to [ammount of figure elements] - 1 aka index of the last figure element.
This can be achieved by somethin like this:
// Remove .show from whichever element currently has it and place it to
// figure that has index 'counter'
function showCurrent() {
$items.removeClass('show');
$items.eq(counter).addClass('show');
}
function showNext() {
if (counter == numItems - 1) {
counter = 0;
} else {
counter++;
}
showCurrent();
}
function showPrev() {
if (counter == 0) {
counter = numItems - 1;
} else {
counter--;
}
showCurrent();
}
// Add click events to prev & next buttons
$('.next').on('click', function() {
showNext();
});
$('.prev').on('click', function() {
showPrev();
});
Minimal JSFiddle demo
I removed TouchSwipe from the demo as its implementation didn't seem to be finished.
On a side note: you seem to have two versions of jQuery, 2.2.1 and 2.1.3. Consider removing the latter and placing all of your JS files at the end of body tag. This way the JS files are loaded last. The order of the files also matters, it should be:
jQuery
jQueryUI
TouchSwipe
Your own files
Related
I'm trying to make a slideshow with smooth transitions on a website a person requested me to make.
For example, when I click next, the current slide (a div with text and buttons) with fade out and the next slide will reveal.
Here is the HTML (edited thanks to a headstarter):
<div id="ssContainer">
<div class="slideshow" id="selected">
<img src="images/slideshow/1.jpg" />
<div class="ssText">
<h1>Welcome to White Grass</h1>
<p>Your complete solution to home building</p>
<button id="portfolioBtn">See Our Portfolio</button>
</div>
</div>
<div class="slideshow">
<img src="images/slideshow/2.jpg" />
<div class="ssText">
<h1>Custom Home Builder</h1>
<p>Customer satisfaction is our top priority</p>
</div>
</div>
<div class="slideshow">
<img src="images/slideshow/3.jpg" />
<div class="ssText">
<h1>Professional & Experienced</h1>
<p>A history of exceptional homes</p>
<button id="contactBtn">Contact Us Now</button>
</div>
</div>
<img id="prev" alt="Previous Slide" onclick="prev();" src="images/slideshow/leftarrow.png"></img>
<img id="next" alt="Next Slide" onclick="next();" src="images/slideshow/rightarrow.png"></img>
</div>
And the CSS:
.slideshow {
display: none;
height: 100%;
position: relative;
transition: display 0.2s;
}
.slideshow img {
max-width: 100%;
max-height: 100vh;
margin: auto;
}
.ssText {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.ssText * {
text-align: center;
}
.ssText h1 {
font-size: 2.5em;
text-transform: uppercase;
background-color: rgba(0, 0, 0, 50%);
padding: 5px;
}
.ssText p {
font-size: 1.1em;
background-color: rgba(0, 0, 0, 50%);
padding: 5px;
}
.ssText button {
position: absolute;
}
#prev, #next {
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
margin-top: -22px;
padding: 10px;
transition: background-color 0.2s;
}
#next {
right: 0;
}
#prev:hover, #next:hover {
background-color: rgba(0, 0, 0, 50%);
}
#selected {
display: block !important;
}
#portfolioBtn {
left: 26%;
transform: translateX(26%);
}
#contactBtn {
left: 29%;
transform: translateX(29%);
}
button {
display: block;
border: none;
background-color: #0074c2;
padding: 15px;
font-size: 1em;
font-family: roboto;
color: white;
border-radius: 3px;
transition: background-color 0.2s;
}
Also, the font is Roboto. I added that in the body section of the CSS.
And here are the images:
1.jpg
2.jpg
3.jpg
leftarrow.png (Chevron Left Icon by Icons8)
rightarrow.png (Chevron Right Icon by Icons8)
I got a pretty basic concept of the JavaScript now thanks to an answer:
var slideIndex = 1;
var slides = document.getElementByClassName("slideshow");
function prev() {
if(slideindex < 1) {
slideindex = 3;
}
else {
slideindex--;
}
showSlides();
}
function next() {
if(slideIndex > 3) {
slideIndex = 1;
}
else {
slideIndex++;
}
showSlides();
}
function showSlides() {
if(slideIndex == 1) {
slides[0].id = "selected";
slides[1].id = "";
slides[2].id = "";
}
else if(slideIndex == 2) {
slides[0].id = "";
slides[1].id = "selected";
slides[2].id = "";
}
else if(slideIndex == 3) {
slides[0].id = "";
slides[1].id = "";
slides[2].id = "selected";
}
}
Now, here's the problem:
With the display transition, the images don't transition from block to none.
I even tried messing with the opacity. Gives me the animation but not the slideshow feel.
Changed code for .slideshow and #selected section but reverted:
.slideshow {
display: block;
height: 100%;
position: relative;
opacity: 0;
transition: opacity 0.2s;
}
#selected {
opacity: 1 !important;
}
How do I fix this? Also, tried messing with z-index.
Also, I have to click the previous and next button twice to change from slide 3 to 1 or slide 1 to 3. Weird. Would also want a fix for this.
No jQuery, or any external JS scripts besides my own, please.
Well, this question doesn't comply with Stackoverflow in the way that we expect you to show what you have try and show what you researched. Now you are mostly asking us to write code for you.
Some research and reading will help you get a start on the subject:
how to create transition css javascript
But hey! I've been there too, so, I'll try to give you an example.
DON'T USE THIS CODE
This is only for example purposes and it won't achieve exactly what you are asking for. This code only fades the image background and you are trying to change the whole block of code including the image and text.
The goal behind what follows is only to help you get an idea on how things work.
Let's say that you only want to fade in and fade out your slide. For that, I would use opacity CSS property.
.slideshow img {
max-width: 100%;
max-height: 100vh;
margin: auto;
opacity: 0;
transition: opacity 2s;
}
That said, you will have to add some IDs and your function to your clickable images:
<img id="slide1" src="images/slideshow/1.jpg" />
<img id="slide2" src="images/slideshow/2.jpg" />
<img id="slide3" src="images/slideshow/3.jpg" />
<img id="prev" alt="Previous Slide" onclick="fadeTransition('prev')" src="images/slideshow/leftarrow.png"></img>
<img id="next" alt="Next Slide" onclick="fadeTransition('next')" src="images/slideshow/rightarrow.png"></img>
And then, there is some javacript to help you start with it
var currentSlide = 1;//You need a var that contain the current slide that is show
function fadeTransition(side) {
if ((side === 'prev' && currentSlide === 1) || (side === 'next' && currentSlide === 3)) {return;}
if (side === 'prev') {var newSlide = currentSlide - 1;}
if (side === 'next') {var newSlide = currentSlide + 1;}
document.getElementById('slide'+currentSlide).style.opacity = 0;
document.getElementById('slide'+newSlide).style.opacity = 1;
currentSlide = newSlide;
return;
}
There us a problem with that , on load, all your image will be at opacity 0. You'll have to change the initial state of the first image. At this point, I'll use a class like
.in {
opacity: 1 !important;
}
And into the Javascript, instead of changing style.opacity I would add and remove the in class and adding it into the HTML for load purposes:
<img id="slide1" class="in" src="images/slideshow/1.jpg" />
javascript change class
So now, most of the previous Javascript code blocks are unusable. Keep it in mind that you have to store what the current displayed block is. Restrict your code so the user can't get to a point where he's going to a previous slide when the current slide is the first one.
I hope this will help you in achieving your goal.
I have got a video that appears in a light box from you tube, a custom one not a plugin.
On mobile when displayed portrait the video spans the full page width which looks nice and leaves some room at the top and bottom to click out.
The issue is when I go landscape the video fills the full screen and you cannot get back onto the page. My initial reaction was to hit the phones back button but I don't know a way of getting this to simply remove my lightbox. Is there a way in JS of getting a onclick off the phones back button?
The reason it goes full screen is because I am keeping the aspect ratio
var width: number = $('.youtube-video-lightbox').outerWidth();
var height: number = (width / 16) * 9;
$('.youtube-video-lightbox').height(height);
You can try using the following code:
You need to listen to navigation event and state.direction.
$(window).on("navigate", function (event, data) {
var direction = data.state.direction;
if (direction == 'back') {
// close the light box here
}
if (direction == 'forward') {
// do something else
}
});
More details in this link
Tested the above code in my mobile and it works fine. You might need to stop the program flow after closing the light box so that default navigation of the back button is stopped.
Weave: http://kodeweave.sourceforge.net/editor/#e110ed7e89c3a38335739656a02f9850
Have you thought of trying a Pure CSS Based Lightbox?
$('[data-target]').on('click', function() {
$('.page').attr('src', $(this).attr('data-target'));
});
$('#call').on('change', function() {
(this.checked) ? "" : $('.page').attr('src', '');
});
input[id=call] {
display: none;
}
a {
margin: 1em;
}
.bg,
.content {
opacity: 0;
visibility: hidden;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
transition: all ease-in 150ms;
}
.bg {
background: #515151;
background: rgba(0, 0, 0, 0.58);
}
.content {
margin: 2.6352em;
padding: 1em;
background: #fff;
}
input[id=call]:checked ~ .bg,
input[id=call]:checked ~ .content {
visibility: visible;
opacity: 1;
}
.block {
display: block;
}
.pointer {
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="call" type="checkbox" />
<p>
<a href="javascript:void(0)" data-target="http://bing.com/" class="pointer block">
<label for="call" class="pointer">Bing</label>
</a>
<a href="javascript:void(0)" data-target="http://duckduckgo.com/" class="pointer block">
<label for="call" class="pointer">DuckDuckGo</label>
</a>
</p>
<label for="call" class="bg pointer"></label>
<div class="content">
<iframe width="100%" height="100%" frameborder="0" class="page"></iframe>
</div>
When I'm using show() and hide() methods from jquery-ui:
var current = 1;
function slide(buttonNum) {
if (current != buttonNum){
$("#page" + current).hide("slide", { direction: "left" }, 800, function() {
$("#page" + buttonNum).show("slide", { direction: "right" }, 800);
});
current = buttonNum;
}
}
My intention is that every time button is clicked for this function the page would scroll left to change to required page.
The problem is that it doesn't work first time I'm clicking page number with function above(the current div would slide to the left, but div which I change to just pops up without animation) but works normally other times.
my css is as follows:
.slider {
width: 400px;
height: 300px;
overflow: hidden;
}
.slider .content {
position: relative;
}
.slider .content .page {
float: left;
width: 400px;
height: 300px;
background-size: cover;
}
and HTML:
<div class="slider">
<div class="content">
<div id='page1' class="page">
<!-- stuff -->
</div>
<div id='page2' class="page">
<!-- stuff -->
</div>
<div id='page3' class="page">
<!-- stuff -->
</div>
</div>
</div>
<a onclick='slide(1)' href="#">1</a>
<a onclick='slide(2)' href='#'>2</a>
Try hiding the elements that you expect not to be visible at the beginning, so that the show animation will actually execute. E.g. add this at the top:
$("#page2").hide();
$("#page3").hide();
That way running .show() on them will have an effect.
I found something that can not only toggle on/off an image, but also make that image a link.
Problem: It only works in JSFiddle.
I put everything back into html (providing script) and made sure that everything was the same...but still, on my site it won't work. On JSFiddle, it does.
If anyone has a solution, I'd be most grateful.
The code I'm using for the site:
<center>
<p>
<div class="icon-container">
<a id="TOURBUTTON">
<img src="http://static.tumblr.com/6s0fefr/vFQn5uj2h/tournew.png" style="width: 188px; height: 188px;" />
</a>
</div>
</p>
</center>
<center>
<p>
<div class="display-container">
<img id="T5" style="display:none;" a href="http://music.britrodriguez.com" src="http://static.tumblr.com/6s0fefr/GXHnabnep/tahoeshow.png"/>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
$('#TOURBUTTON').on("click", function(){
$('#T5').toggle();
});
});
$('#T5').click(function(event){
var link = $(this);
var target = link.attr("target");
if ($.trim(target).length > 0){
window.open(link.attr("href"), target);
} else {
window.location = link.attr("href");
}
event.preventDefault();
});
</script>
<style type="text/css">
.icon-container{
display:inline-block;
margin-bottom: 0px;
margin-top: 10px;
}
</style>
The JSFiddle:
http://jsfiddle.net/ccymzmvn/
The site it's not working on:
http://www.britrodriguez.com/HITEST
Why do you open the url with JavaScript? Just try:
<a href="http://music.britrodriguez.com">
<img src="http://static.tumblr.com/6s0fefr/GXHnabnep/tahoeshow.png" />
</a>
These are just suggestions, but:
Make sure your HTML document is well formed and remove extraneous levels. The deeper the DOM tree goes, the "heavier" the page can get for the browser. Always strive towards a shallow DOM tree
The event handler when you click #T5 doesn't really need jQuery, I've used native JS, you can see it has a one to one drop-in.
Whenever you have a click event on an element, change the cursor for the user so they know it is clickable.
I have also user opacity to hide the #T5 instead of display. That way you can make it fade nicely
http://jsfiddle.net/ccymzmvn/5/
HTML
<p class="icon-container">
<a id="TOURBUTTON">
<img src="http://static.tumblr.com/6s0fefr/vFQn5uj2h/tournew.png" />
</a>
</p>
<p class="display-container">
<a href="http://music.britrodriguez.com">
<img id="T5" src="http://static.tumblr.com/6s0fefr/GXHnabnep/tahoeshow.png" />
</a>
</p>
CSS
body {
text-align: center;
}
#TOURBUTTON {
display: inline-block;
}
#TOURBUTTON img {
cursor: pointer;
display: block;
width: 188px;
height: 188px;
}
img#T5 {
border: 1px solid red;
max-width: 100%;
opacity: 0;
pointer-events: none;
-webkit-transition: opacity 800ms;
transition: opacity 800ms;
}
img#T5.active {
opacity: 1;
pointer-events: auto;
}
JavaScript
function open_link(event) {
event.preventDefault();
var link = this,
target = link.target;
if($.trim(target).length > 0) {
window.open(link.href, target);
} else {
window.location = link.href;
}
}
$(document).ready(function() {
var $T5 = $('#T5');
$('#TOURBUTTON').on("click", function(){
$T5.toggleClass('active');
});
$T5.on('click', open_link);
});
I've been stuck trying to figure out how to code a menu much like what you see on the Playstation website: http://us.playstation.com/
EDIT: Fiddle: http://jsfiddle.net/jjcarlson/7q64A/
So far I have a number of issues. The first is that I have been unable to create the 100% width, because, I am assuming, of the parent/child relationship.
The second issue I have is that my Timeout works on all class elements rather than only the currently hovered element. In other words, if all elements have slid down and one is hovered over, they all will remain open until none of them have been hovered for 1.5 seconds. I admit that my inability to come up with a solution may be due to my limited experience with the language. Below is the CSS:
.accordion-container {
width: 90%;
padding-bottom: 5px;
margin: 20px 0 0 20px;
}
.accordion {
width: 40%;
padding: 20px;
margin: 0 15px 35px;
position: relative;
float: left;
display: inline-block;
}
.accordion-question {
margin: 0;
padding: 0 0 5px 20px;
display: inline-block;
color: #06F;
background-color: #9F0;
cursor: pointer;
}
.accordion-answer-container {
padding: 0 20px;
overflow: hidden;
color: #999;
background: #F00;
}
.accordion-answer {
margin: 0;
padding: 0;
color: #0C0;
}
Then, the JQuery:
$(document).ready(function () {
var menu = $('.accordion-answer')
var timeout = 0;
var hovering = false;
menu.hide();
$('.accordion-question').hover(function () {
hovering = true;
// Open the menu
$(this).closest('.accordion').find('.accordion-answer')
.stop(true, true)
.delay(400).slideDown(600);
if (timeout > 0) {
clearTimeout(timeout);
}
})
.on("mouseleave", function () {
resetHover();
});
$('.accordion-answer').hover(function () {
hovering = true;
startTimeout();
})
.on("mouseleave", function () {
resetHover();
});
function startTimeout() {
timeout = setTimeout(function () {
closeMenu();
}, 1500);
};
function closeMenu() {
if (!hovering) {
$('.accordion-answer').stop(true, true).slideUp(400);
}
};
function resetHover() {
hovering = false;
startTimeout();
};
});
And finally, the HTML:
<div class="accordion-container">
<div class="accordion">
<div class="accordion-question">
<h2>Is this a question?</h2>
</div>
<div class="accordion-answer-container">
<div class="accordion-answer">
<p>To be honest, I am not sure</p>
<ul>
<li>List item one</li>
<li>List item two</li>
</ul>
<p>That is all.</p>
</div>
</div>
</div><!-- /accordion -->
<div class="accordion" id="testanchor">
<div class="accordion-question">
<h2>What would be a good second question?</h2>
</div>
<div class="accordion-answer-container">
<div class="accordion-answer">
<p>I don’t know, man!</p>
<p>That is all.</p>
</div>
</div>
</div><!-- /accordion -->
</div>
Styling is minimal right now (sorry) as I'm just trying to get this figured out. Thank you for any help you can provide.
To get a width of 100% you should not display them as inline-block and set the width of .accordion to 100%.
In the hover-event you set hovering to true. If the next hover-event occurs prior to the call of closeMenu, then the if clause will already be false.
You should be able to accomplish the 100% width of your dropdown by altering the css of your .according-answer-container to a fixed position along with setting left and right to 0:
.accordion-answer-container {
padding: 0 20px;
overflow: hidden;
color: #999;
background: #F00;
position: fixed;
left: 0;
right: 0;
}
An update to your fiddle shows this working