Affix scrollspy to top using javascript - javascript

I'm trying to build a scrollspy similar to the one one the getboostrap website where the side navbar rises to the top of the page as you scroll, but then sticks to the top (http://getbootstrap.com/css/). I wrote a small script in my html to access the header size so that it would be compatible with different headers, but I want to move it into a separate javascript file. Here I'm including all of my html and the css for scrspy and affix.
HTML:
<div id="myScrollspy" role="complementary">
<script>
var element = document.getElementById('headerSize');
document.write('<ul class="nav scrspy affix" data-spy="affix" data-offset-top="' + element.offsetHeight + '" data-offset-bottom="200">');
</script>
<ul class="nav scrspy affix" data-spy="affix">
<li class="active">Section One</li>
<ul class="nav scrspy">
<li>Section 1.1</li>
<li>Section 1.2</li>
</ul>
<li>Section Two</li>
<li>Section Three</li>
<li>Section Four</li>
<li>Section Five</li>
</ul>
</div>
<section>
<h2 id="section-1">Section One</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam eu sem tempor, varius quam at, luctus dui.</p>
<h2 id="section-1-1">Section 1.1</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam eu sem tempor, varius quam at, luctus dui.
<h2 id="section-1-2">Section 1.2</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam eu sem tempor, varius quam at, luctus dui.
<h2 id="section-2">Section Two</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam eu sem tempor, varius quam at, luctus dui.</p>
<h2 id="section-3">Section Three</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam eu sem tempor, varius quam at, luctus dui.</p>
<h2 id="section-4">Section Four</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam eu sem tempor, varius quam at, luctus dui.</p>
<h2 id="section-5">Section Five</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam eu sem tempor, varius quam at, luctus dui.</p>
</section>
CSS:
.scrspy {
> li {
float: left;
> a {
color: #gray-dark;
&:hover {
border-right: 2px solid #blue;
}
}
}
.nav-stacked;
.hidden-xs;
.hidden-sm;
}
ul.scrspy, ul.scrspy ul li {
width: 9.75rem;
}
ul.scrspy.affix {
top: 1.85rem;
}
ul.scrspy ul li {
padding: .315rem .47rem;
padding-left: 1rem;
font-size: #font-size-small;
}
ul.scrspy li.active a, ul.scrspy li.active a:hover {
color: #daimler-blue;
border-right: 2px solid #blue;
}
.affix {
position: fixed;
}
ul.scrspy.affix {
position: fixed;
top: 0;
z-index: 10;
}
I tried this in a separate .js file with a link to it in the html but it doesn't seem to work.
JS:
$(document).ready(function () {
var element = document.getElementById('headerSize');
$('ul.scrspy').affix({
offset: {
top: element.offsetHeight
bottom: 200
}
});
});

Note the css apart from .sticky-top-affix is for the demo.
Also note data-top-add="20" should be whatever top you set in that class to make it smooth. It is option - try not having it and see what happens.
.sticky-top-affix {
position: fixed;
top: 20px;
}
body {
height: 2000px;
}
nav {
border: 1px solid black;
width: 250px;
}
<p>Some stuff before the menu</p>
<p>Some stuff before the menu</p>
<p>Some stuff before the menu</p>
<p>Some stuff before the menu</p>
<p>Some stuff before the menu</p>
<nav class="sticky-top" data-top-add="20">
<ul>
<li>Home</li>
<li>About</li>
<li>Contact</li>
</ul>
</nav>
var $stickyEls;
function onWindowScroll() {
var scrollTop = $(window).scrollTop();
$stickyEls.each(function() {
var $el = $(this),
topOffset = $el.data('topOffset');
$el[scrollTop >= topOffset ?
'addClass' : 'removeClass']('sticky-top-affix');
});
}
function stickyTopInit() {
$stickyEls = $('.sticky-top');
// Save positions.
$stickyEls.each(function() {
var $el = $(this);
var addToTop = +$el.attr('data-top-add') || 0;
$el.data('topOffset', $el.offset().top - addToTop);
});
$(window).scroll(onWindowScroll);
}
$(document).ready(stickyTopInit);
Fiddle: http://jsfiddle.net/y3umh/
All we are doing here is saying "When you scroll passed the top of the menu add the sticky-top-affix, if you scroll before it remove it".

I added
<ul class="nav scrspy affix" id="stay" data-spy="affix">
to the html, and changed the javascript to:
$(document).ready(function () {
var element = document.getElementById('headerSize');
$("#stay").affix({
offset: {
top: element.offsetHeight
}
});
});

Related

How to use javascript to set the Show More button to appear when the article exceeds two lines?

If you use javascript to set when the article paragraph exceeds two lines, the showMore button will appear.
If there are no more than two lines, showMore will not be displayed. At present, I use the word count method to set a problem, that is, it has more than two lines. It's OK, but the number of words has not reached 40, so the showMore button will not appear. I want to use the number of lines to judge, but how should I write it?
$(function(){
let len = 40;
$('.info_content').each(function(){
if($(this).html().trim().length >len){
var str=$(this).html().substring(0,len-1)+"<button class='info-more'>...showMore</button>";
$(this).html(str);
}
});
});
.info_content{
width: 250px;
font-size: 15px;
letter-spacing:1px;
line-height: 1.5;
margin-bottom: 8px;
letter-spacing:0;
overflow:hidden;
text-overflow:clip;
display:-webkit-box;
-webkit-box-orient:vertical;
-webkit-line-clamp:2;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h3 class="info_content">
asd asdasdasd asd asda sdasd asdasd asd asdsda sdasdasda sdasd asda sdasd asd a
</h3>
<h3 class="info_content">
asdasdasddsasfsdfsdfsdfsdf
</h3>
<!-- 第三組 -->
<h3 class="info_content">
asdasdasdasgasdasdas asdasda
asdasdasdasdasdasdasdasdasdd asdasdasdasdasdasdasdasda
asdasdasdasdasdasdas asdasdaasd asda
</h3>
I came up with this solution but rather than having a button it's easier to make it happen with those elements.
here is the solution I came up with. (click the text to show more, click again to hide)
$(this).on("click",function(e){
const c =e.target.className.includes("c2");
if(c){
$(e.target).removeClass("c2");
}else{
$(e.target).addClass("c2");}
});
.info_content{
width: 250px;
font-size: 15px;
letter-spacing:1px;
line-height: 1.5;
margin-bottom: 8px;
letter-spacing:0;
overflow:hidden;
text-overflow:clip;
display:-webkit-box;
-webkit-box-orient:vertical;
-webkit-line-clamp:2;
}
.c2{
-webkit-line-clamp: unset;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h3 class="info_content">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ut ornare metus. Integer gravida sollicitudin metus, eu aliquet mi varius at. Suspendisse elementum ex erat, at iaculis augue aliquet in. Ut nunc eros, egestas aliquet blandit a, viverra sed tellus.
</h3>
<h3 class="info_content">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</h3>
<h3 class="info_content">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque aliquam nunc ac viverra ullamcorper. Nam pellentesque aliquam enim, sit amet molestie enim iaculis non. Vestibulum sit amet diam.
</h3>
Create dummy element with a<br>a to simulate element with 2 lines.
Get its height and compare with other element.
If given element is bigger than dummy element add button after it (in will not work because it will be placed at the end of string which is hidden)
I have added inserAfter method from this answer to make adding button cleaner.
document.onreadystatechange = () => {
if (document.readyState === 'complete') {
const maxHeight = getElementMaxHeight('info_content');
document.querySelectorAll('.info_content').forEach(infoContent => {
infoContent.style.display = 'block';
if (infoContent.clientHeight > maxHeight) {
const button = document.createElement('button');
button.classList.add('info-more');
button.innerText = '...showMore';
infoContent.insertAfter(button);
}
infoContent.style.display = '-webkit-box';
});
}
};
const getElementMaxHeight = (className) => {
const element = document.createElement('div');
element.classList.add(className);
element.innerHTML = 'a<br>a';
element.style.display = 'block';
element.style.position = 'absolute';
document.body.append(element);
const height = element.clientHeight;
element.remove();
return height;
}
Element.prototype.insertAfter = function (newElement) {
this.parentNode.insertBefore(newElement, this.nextSibling);
}
.info_content {
width: 250px;
font-size: 15px;
line-height: 1.5;
margin-bottom: 8px;
letter-spacing: 0;
overflow: hidden;
text-overflow: clip;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
<h3 class="info_content">
asd asdasdasd asd asda sdasd asdasd asd asdsda sdasdasda sdasd asda sdasd asd a
</h3>
<h3 class="info_content">
asdasdasddsasfsdfsdfsdfsdf
</h3>
<!-- 第三組 -->
<h3 class="info_content">
asdasdasdasgasdasdas asdasda
asdasdasdasdasdasdasdasdasdd asdasdasdasdasdasdasdasda
asdasdasdasdasdasdas asdasdaasd asda
</h3>
<!-- 第四組 -->
<h3 class="info_content">
qqq
</h3>
<!-- 第五組 -->
<h3 class="info_content">
asdasdasdasgasdasdas asdasda s asdasda s asdasda
</h3>

How to animate multiple elements, when using the same classes?

I'm am trying to make multiple boxes, which can expand onclick and close again when clicking on the X. Well first off, the close jquery doesn't work, but that isn't the main thing I'am looking fore, how can I optimize the code, so doesn't become 400-600 hundred lines of the same, just for each box/element.
When click on one box/element, it should expand and so should the content inside - in the order as they come. Then it can be closed again an you would be able to click on another element with the same result - using pretty much the same code.
How can I make the site know, which element has bin click on.
Thanks in advance :)
$(document).ready(function(){
$( ".calendarBox" ).click(function() {
$(".calendarBox").addClass("calendarBoxOpen").delay(2000);
$(".dateTitle").addClass("dateTitleOpen");
$(".dateMonthBox").addClass("dateMonthBoxOpen");
$(".closeMonth").addClass("showMonth");
$(".dateDayBox").addClass("dateDayBoxOpen");
$(".closeDay").addClass("showDay");
$(".dateCloseBtnBox").addClass("dateOpenBtnBox");
$(".closeHr").addClass("showHr");
$(".dayActivitiesInfo").addClass("dayActivitiesInfoOpned");
$(".dayInfoTxt_1May").addClass("dayInfoTxt_1MayOpen");
$(".dayInfoBtnBox_1Maj").addClass("dayInfoBtnBox_1MajOpen");
});
});
$(document).ready(function(){
$( ".dateCloseBtn" ).click(function() {
$(".dayInfoBtnBox_1Maj").removeClass("dayInfoBtnBox_1MajOpen");
$(".dayInfoTxt_1May").removeClass("dayInfoTxt_1MayOpen");
$(".dayActivitiesInfo").removeClass("dayActivitiesInfoOpned");
$(".closeHr").removeClass("showHr");
$(".dateCloseBtnBox").removeClass("dateOpenBtnBox");
$(".closeDay").removeClass("showDay");
$(".dateDayBox").removeClass("dateDayBoxOpen");
$(".closeMonth").removeClass("showMonth");
$(".dateMonthBox").removeClass("dateMonthBoxOpen");
$(".dateTitle").removeClass("dateTitleOpen");
$(".calendarBox").removeClass("calendarBoxOpen");
});
});
.calendarBox { /*This is when closed*/
width:14.28571428571428%;
border:0.5px solid #000;
height:100%;
transition-duration:1s;
}
.calendarBox:hover {
background-color:#8abcc2;
}
.calendarBoxOpen { /*This is when opened*/
width:57.14285714285712%;
}
.calendarDate {
}
.calendarHeader {
display:flex;
}
.dateTitle { /*This is when closed*/
margin-left:15px;
display:none;
transition:ease-in-out;
transition-duration:1s;
}
.dateTitleOpen { /*This is when opened*/
display:block;
}
.dateDayMonthBox {
width:100%;
}
.dateMonthBox { /*This is when closed*/
display:inline-flex;
float:right;
}
.dateMonthBoxOpen { /*This is when Opened*/
margin-left:25px;
}
.closeMonth { /*This is when closed*/
display:none;
}
.showMonth { /*This is when opened*/
display:block;
}
.dateDayBox { /*This is when closed*/
display:inline-flex;
float:left;/*This is when open*/
}
.dateDayBoxOpen { /*This is when opened*/
float:right;
}
.closeDay { /*This is when closed*/
display:none;
}
.showDay { /*This is when opened*/
display:block;
}
.dateCloseBtnBox { /*This is when date is closed*/
-webkit-margin-before: 1.33em;
-webkit-margin-after: 1.33em;
-webkit-margin-start: 0px;
-webkit-margin-end: 0px;
font-weight: bold;
margin-left:25px;
margin-right:5px;
display:none;
}
.dateOpenBtnBox { /*This is visible, when date open*/
display:block;
}
.dateCloseBtn {
}
.closeHr { /*This is when closed*/
display:none;
}
.showHr { /*This is when opened*/
display:block;
}
/*====Content of the calendar day=====*/
.dateDayInformationBox {
}
.dateDayInformation {
width:100%;
display:inline-flex;
overflow-y:hidden;
}
.dayActivitiesInfo { /*This is when closed*/
height:18px;
width:100%;
margin-left: 15px;
padding-left: 10px;
list-style-type:none;
border-left:2.5px solid purple;
}
.dayActivitiesInfoOpned { /*This is when opened*/
height:100%;
width:50%;
margin-left: 15px;
padding-left: 10px;
list-style-type:none;
border-left:2.5px solid purple;
}
/*====The txt======*/
.dayInfoTitel_1May {
}
.dayInfoTxt_1May { /*This is when closed*/
display:none;
}
.dayInfoTxt_1MayOpen { /*This is when opened*/
display:block;
}
.dayInfoBtnBox_1Maj { /*This is when closed*/
display:none;
}
.dayInfoBtnBox_1MajOpen { /*This is when opened*/
text-align: center;
margin: auto;
display:block;
}
<script src="http://code.jquery.com/jquery.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="calendarBox">
<div class="calendarDate">
<div class="calendarHeader">
<h3 class="dateTitle">Information</h3>
<div class="dateDayMonthBox">
<div class="dateMonthBox"><h4 class="">1</h4><h4 class="closeMonth">.Maj</h4></div> <div class="dateDayBox"><h4 class="">M</h4><h4 class="closeDay">andag</h4></div>
</div>
<div class="dateCloseBtnBox">
<div class="dateCloseBtn">close</div>
</div><!--The clouse btn-->
</div>
<hr class="closeHr">
<div class="dateDayInformationBox">
<div class="dateDayInformation">
<ul class="dayActivitiesInfo">
<li class="dayInfoTitel_1May">Børnekor - kl.14:40</li>
<li class="dayInfoTxt_1May">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis aliquam nunc sit amet ante lacinia, vitae dictum erat egestas. Duis rutrum vitae orci vitae euismod.</li>
</ul>
<div class="dayInfoBtnBox_1Maj">
<h5>Tilmeldte 23 <span>Icon</span></h5>
<div>
<button>Del</button>
<button>Tilmeld</button>
</div>
</div>
</div>
<div class="dateDayInformation">
<ul class="dayActivitiesInfo">
<li class="dayInfoTitel_1May">Bord og Vin - kl.18:30</li>
<li class="dayInfoTxt_1May">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis aliquam nunc sit amet ante lacinia, vitae dictum erat egestas. Duis rutrum vitae orci vitae euismod.</li>
</ul>
<div class="dayInfoBtnBox_1Maj">
<h5>Tilmeldte 23 <span>Icon</span></h5>
<div>
<button>Del</button>
<button>Tilmeld</button>
</div>
</div>
</div>
</div>
</div>
</div>
<!---------><div class="close">
close
</div>
<div class="calendarBox" onclick="animateDayOpen_1Maj">
<div class="calendarDate">
<div class="calendarHeader">
<h3 class="dateTitle">Information</h3>
<div class="dateDayMonthBox">
<div class="dateMonthBox"><h4 class="">2</h4><h4 class="closeMonth">.Maj</h4></div> <div class="dateDayBox"><h4 class="">M</h4><h4 class="closeDay">andag</h4></div>
</div>
<div class="dateCloseBtnBox" onclick="animateDayClose_1Maj">
<div class="dateCloseBtn">X</div>
</div><!--The clouse btn-->
</div>
<hr class="closeHr">
<div class="dateDayInformationBox">
<div class="dateDayInformation">
<ul class="dayActivitiesInfo">
<li class="dayInfoTitel_1May">Børnekor - kl.14:40</li>
<li class="dayInfoTxt_1May">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis aliquam nunc sit amet ante lacinia, vitae dictum erat egestas. Duis rutrum vitae orci vitae euismod.</li>
</ul>
<div class="dayInfoBtnBox_1Maj">
<h5>Tilmeldte 23 <span>Icon</span></h5>
<div>
<button>Del</button>
<button>Tilmeld</button>
</div>
</div>
</div>
<div class="dateDayInformation">
<ul class="dayActivitiesInfo">
<li class="dayInfoTitel_1May">Bord og Vin - kl.18:30</li>
<li class="dayInfoTxt_1May">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis aliquam nunc sit amet ante lacinia, vitae dictum erat egestas. Duis rutrum vitae orci vitae euismod.</li>
</ul>
<div class="dayInfoBtnBox_1Maj">
<h5>Tilmeldte 23 <span>Icon</span></h5>
<div>
<button>Del</button>
<button>Tilmeld</button>
</div>
</div>
</div>
</div>
</div>
</div>
So, you have multiple boxes that you want to expand/shrink on click. You can give all that boxes one class - boxExpandable for expample, with initial width. Then user clicks on boxExpandable - you should toggle .expanded class with higher width.
If you want some content to be shown only when box is expanded - wrap it in .showWhenExpanded class, like shown below.
$(document).ready(function(){
$('.expandableBox').on('click', function(){
$(this).toggleClass('expanded');
});
});
.box {
margin-bottom: 10px;
padding: 15px;
width: 40%;
border: solid 5px goldenrod;
transition: background-color .4s, width .4s;
}
.box:hover {
background-color: #32cd32;
}
.box.expanded {
width: 80%;
}
.showWhenExpanded {
display: none;
}
.box.expanded .showWhenExpanded {
display: inline-block;
}
<script src="//code.jquery.com/jquery.js"></script>
<div class="content">
<div class="box expandableBox">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. <span class="showWhenExpanded">Duis aliquam nunc sit amet ante lacinia, vitae dictum erat egestas. Duis rutrum vitae orci vitae euismod.</span></p>
</div>
<div class="box expandableBox">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. <span class="showWhenExpanded">Duis aliquam nunc sit amet ante lacinia, vitae dictum erat egestas. Duis rutrum vitae orci vitae euismod.</span></p>
</div>
<div class="box expandableBox">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. <span class="showWhenExpanded">Duis aliquam nunc sit amet ante lacinia, vitae dictum erat egestas. Duis rutrum vitae orci vitae euismod.</span></p>
</div>
</div>
See this codepen

Selecting *specific* element in jQuery

I'm new to jQuery and I'd like to add a class to an individual image by hovering over a button - something I thought I knew how to do, turns out I don't.
The problem being I have several .service sections, each with their own .service button. Therefore, the end result is as expected: when I hover over the button, ALL the .service-image are affected. I thought I could resolve this by using $(this) or find() but I just cant figure it out...
$(".service button").hover(function() {
$(".service-image").toggleClass("raise");
});
.raise {
transform: translateY(-10px);
transition: all 0.2s ease;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="service home-service1">
<div class="service-image">
<img src="images/phone.png" alt="" />
</div>
<div class="service-title">
<h2>Kiosk Renovation</h2>
</div>
<div class="service-text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut feugiat quam sit amet vehicula auctor. Aliquam vel orci hendrerit, vestibulum ligula laoreet, faucibus mi.</p>
</div>
<button class="outline-on-dark">Explore</button>
</div>
Since the <button> element is a sibling of the .service-image you're trying to target (i.e. they both share the same .service parent), you can use siblings(). By specifying the .service-image selector in the siblings() function, you can be sure to only ever target the .service-image inside of the .service element.
$('.service button').hover(function() {
$(this).siblings('.service-image').toggleClass('raise');
});
.raise {
transform: translateY(-10px);
transition: all 0.2s ease;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="service home-service1">
<div class="service-image">
<img src="images/phone.png" alt="" />
</div>
<div class="service-title">
<h2>Kiosk Renovation</h2>
</div>
<div class="service-text">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut feugiat quam sit amet vehicula auctor. Aliquam vel orci hendrerit, vestibulum ligula laoreet, faucibus mi.</p>
</div>
<button class="outline-on-dark">Explore</button>
</div>
Try:
$('service button').on('hover', function(e){
$(this).siblings('.service-image').toggleClass('raise');
});
Your thinking was right, as both button and specific image share the same parent.

jQuery slider not going to beginning

I'm working on a little jQuery widget to add to my portfolio/knowledge base. The widget works, and cycles through 5 slides, however, it does not loop back around to slide 1 as it should. It only advances to a blank slide, and the page requires refreshing to move back or forward again. I am a Javascript/jQuery beginner, so I'm sure I'm missing something simple, but I can't figure it out for the life of me. Any assistance is greatly appreciated.
//(document).ready(); makes sure that all elements on the page are
//loaded before loading the script
$(document).ready(function() {
//alert('Doc is loaded');
//specifies speed to change from image to image, in ms
var speed = 500;
//specifies auto slider option
var autoswitch = true;
//Autoslider speed
var autoswitch_speed = 4000;
//Add initial active class
$('.slide').first().addClass('active');
//Hide all slides
$('.slide').hide();
//Show first slide
$('.active').show();
$('#next').on('click', function() {
$('.active').removeClass('active').addClass('oldActive');
if ($('.oldactive').is('slider:last-child')) {
//alert('true');
$('.slide').first().addClass('active');
} else {
$('.oldActive').next().addClass('active');
}
$('.oldActive').removeClass('oldActive');
$('.slide').fadeOut(speed);
$('.active').fadeIn(speed);
});
$('#prev').on('click', function() {
$('.active').removeClass('active').addClass('oldActive');
if ($('.oldactive').is(':first-child')) {
$('.slide').last().addClass('active');
} else {
$('.oldActive').prev().addClass('active');
}
$('.oldActive').removeClass('oldActive');
$('.slide').fadeOut(speed);
$('.active').fadeIn(speed);
});
});
* {
margin: 0;
padding: 0;
}
body {
font-family: 'Arial', sans-serif;
font-size: 14px;
color: #fff;
background: #333;
line-height: 1.6em;
}
a {
color: #fff;
text-decoration: none;
}
h1 {
text-align: center;
margin-bottom: 20px;
}
#container {
width: 980px;
margin: 40px auto;
overflow: hidden;
}
#slider {
width: 940px;
height: 350px;
position: relative;
overflow: hidden;
float: left;
padding: 3px;
border: #666 solid 2px;
border-radius: 5px;
}
#slider img {
width: 940px;
height: 350px;
}
.slide {
position: absolute;
}
.slide-copy {
position: absolute;
bottom: 0;
left: 0;
padding: 20px;
background: 7f7f7f;
background: rgba(0, 0, 0, 0.5);
}
#prev,
#next {
float: left;
margin-top: 130px;
cursor: pointer;
position: relative;
z-index: 100;
}
#prev {
margin-right: -45px;
}
#next {
margin-left: -45px;
}
<!DOCTYPE html>
<html>
<head>
<title>jQuery Content Slider</title>
<link rel="stylesheet" href="css/style.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="js/script.js"></script>
</head>
<body>
<div id="container">
<header>
<h1>jQuery Content Slider</h1>
</header>
<img src="img/arrow-left.png" alt="Prev" id="prev">
<div id="slider">
<div class="slide">
<div class="slide-copy">
<h2>Slider One</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae commodo sem. Integer eros nibh, molestie congue elementum quis, mattis nec tortor. Vivamus sed hendrerit sed vitae orci convallis.</p>
</div>
<img src="img/slide1.jpg">
</div>
<div class="slide">
<div class="slide-copy">
<h2>Slider Two</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae commodo sem. Integer eros nibh, molestie congue elementum quis, mattis nec tortor. Vivamus sed hendrerit sed vitae orci convallis.</p>
</div>
<img src="img/slide2.jpg">
</div>
<div class="slide">
<div class="slide-copy">
<h2>Slider Three</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae commodo sem. Integer eros nibh, molestie congue elementum quis, mattis nec tortor. Vivamus sed hendrerit sed vitae orci convallis.</p>
</div>
<img src="img/slide3.jpg">
</div>
<div class="slide">
<div class="slide-copy">
<h2>Slider Four</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae commodo sem. Integer eros nibh, molestie congue elementum quis, mattis nec tortor. Vivamus sed hendrerit sed vitae orci convallis.</p>
</div>
<img src="img/slide4.jpg">
</div>
<div class="slide">
<div class="slide-copy">
<h2>Slider Five</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae commodo sem. Integer eros nibh, molestie congue elementum quis, mattis nec tortor. Vivamus sed hendrerit sed vitae orci convallis.</p>
</div>
<img src="img/slide5.jpg">
</div>
</div>
<img src="img/arrow-right.png" alt="Next" id="next">
</div>
</body>
</html>
var cur = 0, // Start Slide Index. We'll use ++cur to increment index
pau = 2000, // Pause Time (ms)
fad = 500, // Fade Time (ms)
$ga = $('#slider'), // Cache Gallery Element
$sl = $('> div', $ga), // Cache Slides Elements
tot = $sl.length, // We'll use cur%tot to reset to first slide
itv ; // Used to clear on mouseenter
$sl.hide().eq( cur ).show(); // Hide all Slides but desired one
function stopFn() { clearInterval(itv); }
function loopFn() { itv = setInterval(fadeFn, pau); }
function fadeFn() { $sl.fadeOut(fad).eq(++cur%tot).stop().fadeIn(fad); }
$ga.hover( stopFn, loopFn );
loopFn(); // Finally, Start
Add this code in the script. this will enable looping effect. Tried working with your code, but its a little bit complex for me. Try this method, this will work like a charm.
See the DEMO
See the snippet
//(document).ready(); makes sure that all elements on the page are
//loaded before loading the script
$(document).ready(function() {
//alert('Doc is loaded');
//specifies speed to change from image to image, in ms
var speed = 1000;
//specifies auto slider option
var autoswitch = true;
//Autoslider speed
var autoswitch_speed = 4000;
//Add initial active class
$('.slide').first().addClass('active');
//Hide all slides
$('.slide').hide();
//Show first slide
$('.active').show();
$('#next').on('click', function() {
$('.active').removeClass('active').addClass('oldActive');
if ($('.oldactive').is('slider:last-child')) {
//alert('true');
$('.slide').first().addClass('active');
} else {
$('.oldActive').next().addClass('active');
}
$('.oldActive').removeClass('oldActive');
$('.slide').fadeOut(speed);
$('.active').fadeIn(speed);
});
$('#prev').on('click', function() {
$('.active').removeClass('active').addClass('oldActive');
if ($('.oldactive').is(':first-child')) {
$('.slide').last().addClass('active');
} else {
$('.oldActive').prev().addClass('active');
}
$('.oldActive').removeClass('oldActive');
$('.slide').fadeOut(speed);
$('.active').fadeIn(speed);
});
});
var cur = 0, // Start Slide Index. We'll use ++cur to increment index
pau = 1000, // Pause Time (ms)
fad = 500, // Fade Time (ms)
$ga = $('#slider'), // Cache Gallery Element
$sl = $('> div', $ga), // Cache Slides Elements
tot = $sl.length, // We'll use cur%tot to reset to first slide
itv; // Used to clear on mouseenter
$sl.hide().eq(cur).show(); // Hide all Slides but desired one
function stopFn() {
clearInterval(itv);
}
function loopFn() {
itv = setInterval(fadeFn, pau);
}
function fadeFn() {
$sl.fadeOut(fad).eq(++cur % tot).stop().fadeIn(fad);
}
$ga.hover(stopFn, loopFn);
loopFn(); // Finally, Start
* {
margin: 0;
padding: 0;
}
body {
font-family: 'Arial', sans-serif;
font-size: 14px;
color: #fff;
background: #333;
line-height: 1.6em;
}
a {
color: #fff;
text-decoration: none;
}
h1 {
text-align: center;
margin-bottom: 20px;
}
#container {
width: 980px;
margin: 40px auto;
overflow: hidden;
}
#slider {
width: 500px;
height: 300px;
position: relative;
overflow: hidden;
float: left;
padding: 3px;
border: #666 solid 2px;
border-radius: 5px;
}
#slider img {
width: 500px;
height: 300px;
}
.slide {
position: absolute;
}
.slide-copy {
position: absolute;
bottom: 0;
left: 0;
padding: 20px;
background: 7f7f7f;
background: rgba(0, 0, 0, 0.5);
}
#prev,
#next {
float: left;
margin-top: 130px;
cursor: pointer;
position: relative;
z-index: 100;
}
#prev {
margin-right: -45px;
}
#next {
margin-left: -45px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<body>
<div id="container">
<header>
<h1>jQuery Content Slider</h1>
</header>
<img src="http://leedspromoproducts.com/templates//img/thumbnails_prev_button.png" alt="Prev" id="prev">
<div id="slider">
<div class="slide">
<div class="slide-copy">
<h2>Slider One</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae commodo sem. Integer eros nibh, molestie congue elementum quis, mattis nec tortor. Vivamus sed hendrerit sed vitae orci convallis.</p>
</div>
<img src="http://www.vectordiary.com/isd_premium/048-hot-air-balloon/hot-air-balloon.jpg">
</div>
<div class="slide">
<div class="slide-copy">
<h2>Slider Two</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae commodo sem. Integer eros nibh, molestie congue elementum quis, mattis nec tortor. Vivamus sed hendrerit sed vitae orci convallis.</p>
</div>
<img src="http://www.moneyindices.com/admin/upload/50193693.jpg">
</div>
<div class="slide">
<div class="slide-copy">
<h2>Slider Three</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae commodo sem. Integer eros nibh, molestie congue elementum quis, mattis nec tortor. Vivamus sed hendrerit sed vitae orci convallis.</p>
</div>
<img src="http://images.china.cn/attachement/jpg/site1007/20110808/000cf1a48f870fa9c75c55.jpg">
</div>
<div class="slide">
<div class="slide-copy">
<h2>Slider Four</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae commodo sem. Integer eros nibh, molestie congue elementum quis, mattis nec tortor. Vivamus sed hendrerit sed vitae orci convallis.</p>
</div>
<img src="http://cdn.allsteamboat.com/images/content/5418_gBVhd_Hot_Air_Balloon_Rodeo_in_Steamboat_Springs_md.jpg">
</div>
<div class="slide">
<div class="slide-copy">
<h2>Slider Five</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae commodo sem. Integer eros nibh, molestie congue elementum quis, mattis nec tortor. Vivamus sed hendrerit sed vitae orci convallis.</p>
</div>
<img src="http://www.moneyindices.com/admin/upload/50193693.jpg">
</div>
</div>
<img src="http://thehaircraftersco.com/wp-content/uploads/2015/10/next-button.png" alt="Next" id="next">
</div>
</body>
Your operation has the wrong syntax, it should be "is(':last-child'))"
if($('.oldActive').is(':last-child')){
//alert('true');
$('.slide').first().addClass('active');
} else {
$('.oldActive').next().addClass('active');
}
You can rewrite your code to use function for easy understanding and reading.
var hwSlideSpeed = 700;
var slideNum = 0;
slideCount = $("#slider .slide").size(); //Count of slides
var animSlide = function(arrow){
$('.slide').eq(slideNum).fadeOut(hwSlideSpeed);
if(arrow == "next"){
if(slideNum == (slideCount-1)){slideNum=0;}
else{slideNum++}
}
else if(arrow == "prew")
{
if(slideNum == 0){slideNum=slideCount-1;}
else{slideNum-=1}
}
else{
slideNum = arrow;
}
$('.slide').eq(slideNum).fadeIn(hwSlideSpeed);
}
$('#nextbutton').click(function(){
animSlide("next");
})
$('#prewbutton').click(function(){
animSlide("prew");
})
Hope it helps

only first FAQ element expands on click - jquery

I'm trying to create an FAQ list. The answer displays fine on first click but I want to be able to click on another question and have that answer expand and the other close. Here's the javascript:
$(document).ready(function() {
// hide all the answers
$('.faq li div').hide();
$('.faq li').click(function(){
var question = $(this);
var answer = $(this).find('div');
// if the faq isn't active
if(!$('.faq li').hasClass('active')) {
answer.slideDown();
$(this).siblings('div').slideUp();
question.addClass('active');
}
else {
answer.slideUp();
question.removeClass('active');
}
});
});
The CSS:
ul.faq {
list-style:none;
cursor:pointer;
z-index:1;
}
ul.faq li h3 {
background:#0A5C75 url(../images/faq-inactive.png) right no-repeat;
color:#fff;
padding:20px 50px 20px 10px;
margin-bottom:10px;
border:1px solid #fff;
}
ul.faq li.active h3 {
background:#0A5C75 url(../images/faq-active.png) right no-repeat;
}
ul.faq li div {
background:#FFFFFF;
margin:0px 10px 10px 10px;
padding:20px;
overflow:hidden;
/* added fixed width to stop the jerkyness*/
width:522px;
position:relative;
top:-10px;
box-shadow: inset 0px 4px 4px 0px rgba(63, 70, 76, 0.15), 0px 4px 4px rgba(63, 70, 76, 0.15);
}
and the HTML
<ul class="faq">
<li>
<h3>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut arcu magna, sodales vel dignissim pharetra, adipiscing sed orci?</a></h3>
<div>Vivamus rutrum arcu sit amet dolor pulvinar dictum. Etiam porttitor leo eget velit volutpat quis ultricies urna ornare. Quisque ac ultrices est. Ut lobortis malesuada justo, sed blandit sapien bibendum et. Donec vel ante eu orci pellentesque dictum. Phasellus molestie egestas du</div>
</li>
<li>
<h3>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut arcu magna, sodales vel dignissim pharetra, adipiscing sed orci?</a></h3>
<div>This is the answer to question 2</div></li>
<li>
<h3>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut arcu magna, sodales vel dignissim pharetra, adipiscing sed orci?</a></h3>
<div>This is the answer to question 3</div>
</li>
</ul>
I think I could improve on your code a bit and produce the behavior and also shorten the code by a fair bit.
Notice, I skipped using your active class in order to show how it could be achieved.
Here's a tinker.io for demo I tested it in FF13 and Chrome
$('.faq li div').hide();
$('.faq li').click(function(event) {
var clickedQuestion = event.target;
var answer = $(clickedQuestion).siblings('div');
if($('ul.faq').find('div').is(':visible')){
$('ul.faq').find('div').slideUp();
}
answer.slideDown();
});
Working demo http://jsfiddle.net/e3Bec/ OR http://jsfiddle.net/XGJXM/
Your code is fine only thing is use ==> if (!$(this).hasClass('active')) { instead of if(!$('.faq li').hasClass('active')) { :) Also you don't need this in your first conditional check question.addClass('active');
Rest code should help, :)
code
$(document).ready(function() {
// hide all the answers
$('.faq li div').hide();
$('.faq li').click(function() {
$('div').slideUp();
var question = $(this);
var answer = $(this).find('div');
// if the faq isn't active
if (!$(this).hasClass('active')) {
answer.slideDown();
$(this).siblings('div').slideUp();
//question.addClass('active');
}
else {
answer.slideUp();
question.removeClass('active');
}
});
});​
I like that you are not sliding up the element if it is already visible.
Maybe move the .hide into css "display:none", no point waiting for the dom to load to hide them.
$(document).ready(function() {
$('.faq li').click(function(event){
$(this).find('div').not(":visible").slideDown();
$('.faq li div:visible').not($(this).find('div')).slideUp();
});
});
Why not use a Accordion. http://jqueryui.com/demos/accordion/

Categories

Resources