Next / previous arrows to cycle through divs - javascript

I want to add two arrows to the sides of the "boxes" divs (below) to cycle through the 3 divs.
Working JSFiddle: https://jsfiddle.net/HBHcC/11/
Can someone help me with this?
HTML:
<div class="container">
<div class="boxes">
<div class="one box">
</div>
<div class="two box">
</div>
<div class="three box">
</div>
</div>
</div>
CSS:
.container{
width:100px;
height:100px;
overflow:hidden;
position:relative;
}
.box {
display:inline-block;
float: left;
width: 100px;
height: 100px;
}
.one{
background-color:green;
}
.two{
background-color:red;
}
.three{
background-color:blue;
}
.boxes{
width:400px;
}
JS:
$(document).ready(function(){
$('.box').on("click", function() {
// Is this the last div, or is there a next one?
if ($(this).next().length) {
var animSpeed = 200; // Make this 0 for an instant change
$('.boxes').animate({marginLeft : "-=100"}, animSpeed);
}
});
});

After adding arrows to the div, here is a new fiddle that should get you started:
$('.rightarrow').on("click", function() {
// Is this the last div, or is there a next one?
var animSpeed = 200; // Make this 0 for an instant change
$('.boxes').animate({marginLeft : "-=100"}, animSpeed);
});
$('.leftarrow').on("click", function() {
// Is this the last div, or is there a next one?
var animSpeed = 200; // Make this 0 for an instant change
$('.boxes').animate({marginLeft : "+=100"}, animSpeed);
});
https://jsfiddle.net/tx2yg06w/1/
Updated w/arrows moved out of divs:
$(document).ready(function(){
var animSpeed = 200;
$('.rightarrow').on("click", function() {
if(parseInt($("#boxes").css("marginLeft")) == -200){ return;}
$('.boxes').animate({marginLeft : "-=100"}, animSpeed);
});
$('.leftarrow').on("click", function() {
if(parseInt($("#boxes").css("marginLeft")) == 0){ return;}
$('.boxes').animate({marginLeft : "+=100"}, animSpeed);
});
});
https://jsfiddle.net/b56r0d72/

Errata has given you a good solution. Just wire up his code to the arrows in the snippet below.
Run snippet to view:
<html>
<body>
<style type="text/css">
.leftarrow, .rightarrow {
font-size: 48px;
color: blue;
text-decoration: none;
}
.rightarrow {
color: red;
float: right;
}
.content {
width: 200px;
padding: 4px;
border: 1px gray solid;
}
.box {
height: 200px;
border: 1px green solid;
}
</style>
<div class="content">
<div>
◀
▶
</div>
<div class="box">slide</div>
</div>
</body>
</html>

Related

How to add Prev and next buttons to change on outer divs

I have this sample navigation that I'm trying to create. What I want to achieve is when you clicked on prev or next class. The active class will be added to map-inr and the scale_text will also be added to the global_map_location class. I believe that only the eq() function will be used in this part.
Here's my js Code:
// Open Popup
$(".map-inr").on("click", function () {
let myIndex = $(this).closest(".global-map").index() - 1;
$('.map-inr').removeClass('active');
$(this).addClass('active');
$('.global_map_location').removeClass('scale_text');
$(this).closest(".global-map").find('.global_map_location').addClass('scale_text');
if ($(".map-item.is--show").length) {
$(".map-item").removeClass("is--show");
setTimeout(function () {
$(".map-item").eq(myIndex).addClass("is--show");
}, 600);
} else {
$(".map-item").eq(myIndex).addClass("is--show");
}
});
//Next function
$('.next').click(function(){
if ($('.is--show').next('.map-item').length) {
$('.is--show').removeClass('is--show')
.next('.map-item')
.addClass('is--show');
}
});
//Prev function
$('.prev').click(function(){
if ($('.is--show').prev('.map-item').length) {
$('.is--show').removeClass('is--show')
.prev('.map-item')
.addClass('is--show');
}
});
.global-map {
display: inline-block;
vertical-align: top;
margin-right: 20px;
margin-bottom: 20px;
}
.map-inr {
background: red;
width: 150px;
height: 150px;
cursor: pointer;
}
.map-inr.active {
background: yellow;
}
.global_map_location.scale_text {
font-weight: 600;
}
.contain {
width: 100%;
max-width: 1000px;
margin: 50px auto 0;
padding: 0;
}
.map-item {
display: inline-block;
vertical-align: top;
padding: 20px;
border-radius: 20px;
text-align: center;
}
.map-item.is--show {
background: yellow;
}
.slider-arrow-wrapper {
margin-bottom: 20px;
}
.slider-arrow-wrapper .prev,
.slider-arrow-wrapper .next {
display: inline-block;
vertical-align: top;
text-decoration: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="global-map">
<div class="map-inr active"></div>
<p class="global_map_location scale_text">map1</p>
</div>
<div class="global-map">
<div class="map-inr"></div>
<p class="global_map_location">map2</p>
</div>
<div class="global-map">
<div class="map-inr"></div>
<p class="global_map_location">map3</p>
</div>
<div class="contain">
<div class="map-item is--show">
<div class="slider-arrow-wrapper">
prev
next
</div>
1
</div>
<div class="map-item">
<div class="slider-arrow-wrapper">
prev
next
</div>
2</div>
<div class="map-item">
<div class="slider-arrow-wrapper">
prev
next
</div>
3</div>
</div>
I have tried this on next button:
//Next function
$('.next').click(function(){
let nextIndex = $(this).closest(".map-item").index() + 1;
console.log("This next is " + nextIndex);
$(".global-map").eq(nextIndex).find('.map-inr').addClass("active");
$(".global-map").eq(nextIndex).find('.global_map_location').addClass("scale_text");
if ($('.is--show').next('.map-item').length) {
$('.is--show').removeClass('is--show')
.next('.map-item')
.addClass('is--show');
}
});
But it just keeps adding classes to next div. How to remove the classes from prev sections/divs? Is there any proper way to do it?
When user click on Prev and Next anchor tag which have Yellow background then only it should work. It is not feasible solution to make all the prev and next anchor tag click work. Only yellow background prev and next click should work.
Below is the code which match up the scenario which is explained above and also it will give you the user friendly standard view:
$(".next").on('click', function(e) {
e.preventDefault();
if($(this).closest(".map-item.is--show").next().length > 0)
{
$(".contain .is--show").removeClass('is--show').next().addClass("is--show");
$(".map-inr.active").removeClass('active').parent().next().children(".map-inr").addClass("active");
}
});
$(".prev").on('click', function(e) {
e.preventDefault();
if($(this).closest(".map-item.is--show").prev().length > 0)
{
$(".contain .is--show").removeClass('is--show').prev().addClass("is--show");
$(".map-inr.active").removeClass('active').parent().prev().children(".map-inr").addClass("active");
}
Please replace it with your prev and next click jQuery.
Let me know if you have any issues or modification request.

Reducing fixed header on scroll from top of page

I have a website with a fixed header, on the home page the header contains additional content when you are at the top of the page, but I want to hide this content and have a reduced header as they scroll down the page.
So on the initial scroll i want to hide the additional header content and animate the margin of the content below but keep it so that the top of the content still shows underneath it and then scroll from normal from there.
The snippet below should show what I mean better:
var head_height = $('#header').outerHeight(true);
$('#page_content').css('margin-top', (head_height)+'px');
if($('#extra_header_content').length != 0){
$('#header').addClass('home');
var main_head_height = $("#main_header_content").outerHeight(true);
var extra_head_height = $('#header').outerHeight(true);
$(document).on("scroll", function(){
if($(document).scrollTop() >= main_head_height){
$("#extra_header_content").slideUp("slow");
$('#page_content').css('margin-top', (main_head_height)+'px');
$('#header').removeClass('home');
}else{
$("#extra_header_content").slideDown("slow");
$('#page_content').css('margin-top', (extra_head_height)+'px');
$('#header').addClass('home');
}
});
}else{
$('#header').removeClass('home');
}
div{padding:0px;margin:0px;}
#header{background-color:#d33;position:fixed;top:0px;width:100%;}
.home{background-color:#3d3 !important;}
#main_header_content{height:50px;width:100%;}
#extra_header_content{height:50px;width:100%;}
#page_content{background-color:#33d;height:5000px;width:100%;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="header">
<div id="main_header_content">Main header</div>
<div id="extra_header_content">Extra Header</div>
</div>
<div id="page_content">This should still be visible when header initially reduces</div>
You need to change in your JS code. Margin you are reducing when the page start scrolling need to adjust by padding. So you can try this:
var head_height = $('#header').outerHeight(true);
$('#page_content').css('margin-top', (head_height)+'px');
if($('#extra_header_content').length != 0){
$('#header').addClass('home');
var main_head_height = $("#main_header_content").outerHeight(true);
var extra_head_height = $('#header').outerHeight(true);
$(document).on("scroll", function(){
if($(document).scrollTop() >= main_head_height){
$("#extra_header_content").slideUp("slow");
// $('#page_content').css('margin-top', (main_head_height)+'px');
$('#page_content').css(
{'margin-top': (main_head_height)+'px', 'padding-top': (main_head_height)+'px'}
);
$('#header').removeClass('home');
}else{
$("#extra_header_content").slideDown("slow");
$('#page_content').css('margin-top', (extra_head_height)+'px');
$('#header').addClass('home');
}
});
}else{
$('#header').removeClass('home');
}
div{padding:0px;margin:0px;}
#header{background-color:#d33;position:fixed;top:0px;width:100%;}
.home{background-color:#3d3 !important;}
#main_header_content{height:50px;width:100%;}
#extra_header_content{height:50px;width:100%;}
#page_content{background-color:#33d;height:5000px;width:100%;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="header">
<div id="main_header_content">Main header</div>
<div id="extra_header_content">Extra Header</div>
</div>
<div id="page_content">This should still be visible when header initially reduces</div>
You can do it like this:
var head_height = $('#header').outerHeight(true);
$('#page_content').css('margin-top', (head_height)+'px');
if($('#extra_header_content').length != 0){
$('#header').addClass('home');
var main_head_height = $("#main_header_content").outerHeight(true);
var extra_head_height = $('#extra_header_content').outerHeight(true);
$(document).on("scroll", function() {
const scrollTop = $(document).scrollTop();
if (scrollTop >= head_height) {
$("#extra_header_content").css('height', 0);
$('#page_content').css('margin-top', main_head_height);
$('#header').removeClass('home');
} else if (scrollTop > 0) {
$("#extra_header_content").css('height', extra_head_height - scrollTop);
$('#page_content').css('margin-top', head_height);
$('#header').removeClass('home');
} else {
$("#extra_header_content").css('height', extra_head_height);
$('#page_content').css('margin-top', head_height);
$('#header').addClass('home');
}
});
}else{
$('#header').removeClass('home');
}
div{padding:0px;margin:0px;}
#header{background-color:#d33;position:fixed;top:0px;width:100%;}
.home{background-color:#3d3 !important;}
#main_header_content{height:100px;width:100%;}
#extra_header_content{height:100px;width:100%; overflow: hidden;}
#page_content{background-color:#33d;height:500px;width:100%;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="header">
<div id="main_header_content">Main header</div>
<div id="extra_header_content">Extra Header</div>
</div>
<div id="page_content">This should still be visible when header initially reduces</div>
I can offer you a different approach without JavaScript
body,html{
padding:0;
margin:0;
}
#main-header{
position:fixed;
top:0;
left:0;
right:0;
height: 50px;
background: green;
z-index:3;
}
#extra-header{
position:fixed;
top:50px;
left:0;
right:0;
height: 50px;
background: lime;
z-index: 0;
}
#content{
margin-top:100px;
height:2000px;
position:relative;
z-index:1;
background:blue;
}
#content>div{
height:200px;
background: #efefef;
}
#content>div:nth-of-type(2n){
background: red;
}
<div id="main-header">
Main
</div>
<div id="extra-header">
Extra
</div>
<div id="content">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
This could be a solution if you will use position sticky and not fixed, but this a bit jerky, So I will post one more solution here with smooth animation
var head_height = $('#header').outerHeight(true);
//$('#page_content').css('padding-top', (head_height)+'px');
if ($('#extra_header_content').length != 0) {
$('#header').addClass('home');
var main_head_height = $("#main_header_content").outerHeight(true);
var extra_head_height = $('#header').outerHeight(true);
$(document).on("scroll", function() {
if ($(document).scrollTop() >= main_head_height) {
$('#page_content').css('padding-top', (main_head_height) + 'px');
$("#extra_header_content").slideUp("slow");
//$('.page_content_wrapper').addClass('scrolled');
//$('.page_content_wrapper').css('top', (main_head_height)+'px');
$('#header').removeClass('home');
} else {
$("#extra_header_content").slideDown("slow");
$('#page_content').css('padding-top', 0);
//$('.page_content_wrapper').css('top', 0);
//$('#header').addClass('home');
}
});
} else {
$('#header').removeClass('home');
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
div {
padding: 0px;
margin: 0px;
}
#header {
background-color: #d33;
position: sticky;
top: 0px;
width: 100%;
z-index: 9;
}
.home {
background-color: #3d3 !important;
}
#main_header_content {
height: 50px;
width: 100%;
}
#extra_header_content {
height: 50px;
width: 100%;
}
#page_content {
background-color: #33d;
height: 5000px;
width: 100%;
}
.page_content_wrapper {
position: relative;
top: 0px;
}
#page_content .page_content_wrapper {
transition: top 1s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="header">
<div id="main_header_content">Main header</div>
<div id="extra_header_content">Extra Header</div>
</div>
<div id="page_content">
<div class="page_content_wrapper">This should still be visible when header initially reduces</div>
</div>
<span class="hamBurger"></span>

Making clone to swap to html elements with hammer.js

I'm trying to make swap between two divs, I mean, change one by other preserving events and everything.
Both have hammer events to detect swipe. When I make a swap elements in my project, they lost hammer events, but preserve other events like click.
To illustrate the behaviour I made this:
$(document).ready(function(){
$("#obj2").each(function(){
var $this = $(this);
var h = new Hammer(this);
h.get("swipe").set({ direction: Hammer.DIRECTION_ALL, threshold: 1, velocity:0.1 });
h.on("swipe",function(ev){
$this.text(ev.angle.toFixed(2));
});
});
$("#obj1").click(function(){
alert("this works");
});
$("#makeClone").click(function(){
$("#obj2").text("3. swipe again :(");
var aux = $("#obj2").clone(true);
$("#container2").html($("#container1").clone(true));
$("#container1").html(aux);
});
});
div.obj,#makeClone{
display:inline-block;
box-sizing:border-box;
width:300px;
height:150px;
text-align:center;
border-radius:10px;
background:#f44336;
font:18px/150px "Lato";
color:white;
margin-bottom:5px;
cursor:pointer;
}
#obj2{
background:#4caf50;
}
#makeClone{
background:#666;
height:50px;
font:12px/50px "hack";
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js"></script>
<script src="https://raw.githubusercontent.com/hammerjs/jquery.hammer.js/master/jquery.hammer.js"></script>
<div id="container1">
<div id="obj1" class="obj">click</div>
</div>
<div id="container2">
<div id="obj2" class="obj">1.swipe on me!</div>
</div>
<br><br>
<div id="makeClone">2.change with clone</div>
Do not clone your objects. Use .append instead of .html.
$(document).ready(function() {
$("#obj2").each(function() {
var $this = $(this);
var h = new Hammer(this);
h.get("swipe").set({
direction: Hammer.DIRECTION_ALL,
threshold: 1,
velocity: 0.1
});
h.on("swipe", function(ev) {
$this.text(ev.angle.toFixed(2));
});
});
$("#obj1").click(function() {
alert("this works");
});
$("#makeClone").click(function() {
$("#obj2").text("3. swipe again :(");
var d1 = $("#container1>div");
var d2 = $("#container2>div");
$("#container2").append(d1);
$("#container1").append(d2);
});
});
div.obj,
#makeClone {
display: inline-block;
box-sizing: border-box;
width: 300px;
height: 150px;
text-align: center;
border-radius: 10px;
background: #f44336;
font: 18px/150px "Lato";
color: white;
margin-bottom: 5px;
cursor: pointer;
}
#obj2 {
background: #4caf50;
}
#makeClone {
background: #666;
height: 50px;
font: 12px/50px "hack";
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js"></script>
<script src="https://raw.githubusercontent.com/hammerjs/jquery.hammer.js/master/jquery.hammer.js"></script>
<div id="container1">
<div id="obj1" class="obj">click</div>
</div>
<div id="container2">
<div id="obj2" class="obj">1.swipe on me!</div>
</div>
<br><br>
<div id="makeClone">2.change with clone</div>

jQuery calculate the number of line breaks in a div?

So I have a div wrap whose size is a percentage of the screen width. Inside this wrap is multiple .item divs. As the window gets smaller it breaks into new lines obviously.
I wrote some code which basically takes the width of the wrap and divides it by the sum of the widths of the .item boxes. But the flaw is that it looks at it thinking how many boxes could fit in total, were one to mix and match them perfectly like building blocks, but that's not how it works because the ordering is stagnant.
How could I make this logic work?
CodePen
jQuery:
var itemWidth = 0;
var lineCount = 1;
$(window).on('resize', function(){
var lineWidth = $('.line').width();
var itemWidthSum = 0;
lineCount=1;
$('.item').each(function(index, element) {
if(itemWidthSum < (lineWidth - $(element).outerWidth())) {
itemWidthSum = itemWidthSum + $(element).outerWidth();
} else {
lineCount++;
itemWidthSum = 0;
}
});
});
HTML:
<div id="container">
<div class="rect">
<div class="line">
</div>
<div class="item">Computer Science</div>
<div class="item">Language</div>
<div class="item">Marketing</div>
<div class="item">Biology</div>
<div class="item">Computer Science</div>
<div class="item">Language</div>
<div class="item">Marketing</div>
<div class="item">Biology</div>
<div class="item">Computer Science</div>
<div class="item">Language</div>
<div class="item">Marketing</div>
<div class="item">Biology</div>
<div class="item">Computer Science</div>
<div class="item">Language</div>
<div class="item">Marketing</div>
<div class="item">Biology</div>
</div>
<h1 class="answer"></h1>
CSS:
body {
padding:25px;
}
.answer {
position:fixed;
bottom:0;
left:0;
}
#container {
border: 1px solid rgb(200,200,200);
height: auto;
width: 30%;
margin:0 auto;
}
.item {
padding: 10px;
background-color: #aef2bd;
float: left;
}
.rect {
height: 100px;
width:100%;
position: relative;
}
.rect .line {
position:absolute;
height:50px;
width: 100%;
bottom:0;
border-top: 1px solid red;
}
Figured out my logic mistake by debugging each step.
The correct jQuery:
var itemWidth = 0;
var lineCount = 1;
$(window).on('resize', function(){
var lineWidth = $('.line').width();
var itemWidthSum = 0;
var list = [];
lineCount=1;
$('.item').each(function(index, element) {
if((lineWidth - itemWidthSum) > ($(element).outerWidth())) {
itemWidthSum = itemWidthSum + $(element).outerWidth();
} else {
lineCount++;
itemWidthSum = $(element).outerWidth();
}
});
});

jQuery slide animate div with toggle button works every other time instead of every time

I'm trying to get a simple side navigation bar which you can hide and unhide with a single button.
So far I have it worknig but only every other click, so click to hide works, then does nothing, next click unhides, nothing etc. Yet I have to button set to an image to change on every click, and that is working.
What I have so far is....
HTML:
<div id="navBar-control">
<a href="#" id="toggle-slide-button">
<img src="http://i.imgur.com/8BMxPsC.png" width="50px" height="50px" />
</a>
</div>
<div id="navBar">
<div class="navBtn navBtnText">
Calculator
</div>
<div class="navBtn navBtnText">
About
</div>
<div class="navBtn navBtnText">
Other Services
</div>
</div>
Script:
var state = false;
$("#toggle-slide-button").click(function () {
if (!state) {
$('#navBar').animate({width: "toggle"}, 1000);
$('#toggle-slide-button img').attr('src', 'http://i.imgur.com/K3MG7gT.png');
state = true;
}
else {
$('#mnavBar').animate({width: "toggle"}, 1000);
$('#toggle-slide-button img').attr('src', 'http://i.imgur.com/8BMxPsC.png');
state = false;
}
});
and if it matters, CSS:
#navBar{
background-color: #660000;
height: 780x;
width: 80px;
}
.navBtn{
background-color: #660000;
color: white;
width: 80px;
height: 70px;
cursor: pointer;
border-bottom: 1px solid rgba(255,255,255,.2);
opacity: 1;
font-size: 12px;
text-align: center;
}
.navBtnText {
line-height: 120px;
vertical-align: bottom;
}
.navBtn:hover{
background-color:#990000;
}
#navBar-control {
width: 50px;
height: 100%;
padding: 0 15px;
background-color: #000;
}
Fiddle of this: http://jsfiddle.net/GUjPA/91/
I have been basing this off this fiddle: http://jsfiddle.net/GUjPA/13/ This has the desired behavior only that it is on the right of the screen instead of the left. The script I'm using is exactly the same, and besides different colours and size of side bar, its essentially exactly the same.
You have a mistake here:
$('#mnavBar').animate({width: "toggle"}, 1000);
must be
$('#navBar').animate({width: "toggle"}, 1000);
http://jsfiddle.net/GUjPA/94/ here works
var state = false;
$("#toggle-slide-button").click(function () {
if (!state) {
$('#navBar').animate({width: "toggle"}, 1000);
$('#toggle-slide-button img').attr('src', 'http://i.imgur.com/K3MG7gT.png');
state = true;
}
else {
$('#navBar').animate({width: "toggle"}, 1000);
$('#toggle-slide-button img').attr('src', 'http://i.imgur.com/8BMxPsC.png');
state = false;
}
});
try this: you had added an m to the second call to #navbar
simplified in fiddle

Categories

Resources