I want to show and hide a div on click of previous and next. I am using jQuery toggle to achieve this. Below is what I have tried so far.
HTML code
<div id="one">a</div>
<div id="two">b</div>
<div id="three">c</div>
<div id="prev">prev</div>
<div id="next">next</div>
jQuery Script
jQuery(function(){
jQuery("#two, #three").hide();
jQuery("#next").on("click", function(){
jQuery("#one, #two, #three").toggle();
});
});
Fiddle link
https://jsfiddle.net/mqns2hy4/
So as you can see from the above, when I click on "next", I want only b to come and then when I click again, I wish to have c only and so on. Similarly on click of "Prev", I want the above to move in reverse and so on.
You could create one variable that holds index of active element and change that variable on click. Then you can hide all elements except one with the current active index.
let active = 0;
let el = $("div");
let total = el.length - 1;
const toggle = (el, index) => {
el.hide()
el.eq(index).show()
}
toggle(el, active)
$('button').on('click', function() {
this.id === 'prev' ? active -= 1 : active += 1;
if(active > total) active = 0;
if(active < 0) active = total
toggle(el, active)
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="one">a</div>
<div id="two">b</div>
<div id="three">c</div>
<button id="prev">prev</button>
<button id="next">next</button>
You could keep the index of the currently shown div:
jQuery(function(){
let index = 0;
// you could also use a class to select them:
let divs = ["#one", "#two", "#three"].map(it => jQuery(it));
divs.forEach(it => it.hide());
jQuery("#next").on("click", function(){
divs[index].show();
if(index > 0) divs[index - 1].hide();
index++;
});
});
$(document).ready(function() {
$(".page").hide();
$("#page1").show();
});
$(document).on('click', "#next", function(){
var pageCount = $(".page").length;
var position = $(".page:visible").data('position');
$(".page:visible").hide();
if(position < pageCount){
$("#page" + (position+1)).show();
}
else
{
$("#page1").show();
}
});
$(document).on('click', "#prev", function(){
var position = $(".page:visible").data('position');
var pageCount = $(".page").length;
$(".page:visible").hide();
if(position > 1){
$("#page" + (position-1)).show();
}
else
{
$("#page" + pageCount).show();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="page1" data-position="1" class="page">a</div>
<div id="page2" data-position="2" class="page">b</div>
<div id="page3" data-position="3" class="page">c</div>
<div id="prev">prev</div>
<div id="next">next</div>
Related
-- I'm new to jQuery disclaimer --
I have two images:
https://i.imgur.com/l2H17fn.jpg
https://i.imgur.com/5nlOoyc.jpg
I'd like to show the second one in place of the first one after it's been clicked on five times.
To get the image to replace after one click, I have this:
HTML:
<div class = "dog">
<img id="happy" src="https://i.imgur.com/l2H17fn.jpg">
</div>
jQUERY:
$('.dog').click(function(e){
e.preventDefault();
$("#happy").attr('src',"https://i.imgur.com/5nlOoyc.jpg");
return false;
});
Link to codepen.
Now what if I want to replace the image after the fifth click? What would that look like?
You can keep track of clicks with a variable:
// initialize click count to zero.
var clicks = 0;
$('.dog').on('click', function() {
// increment click count.
clicks++;
// FOR DEMO - output the click count to the console.
// console.log(clicks);
// if clicks is greater than or equal to 5...
if (clicks >= 5) {
// ... change the image ...
$("#happy").attr('src', "https://i.imgur.com/5nlOoyc.jpg");
// .. and remove this click handler.
$(this).off('click');
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="dog">
<img id="happy" src="https://i.imgur.com/l2H17fn.jpg">
</div>
Here you go...I think the trick is to have a global semaphore variable...This one toggles between though...:)
var clicks = 0;
$('.dog').on('click', function(e){
clicks++;
if(clicks >= 5){
if($('#happy').attr('src') !== 'https://i.imgur.com/5nlOoyc.jpg'){
$("#happy").attr('src',"https://i.imgur.com/5nlOoyc.jpg");
}else{
$("#happy").attr('src',"https://i.imgur.com/l2H17fn.jpg");
}
clicks = 0;
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class = "dog">
<img id="happy" src="https://i.imgur.com/l2H17fn.jpg">
</div>
I have a few click handler events on my page that simply add an active class to an element. I only want the event to trigger if the current section has the class active. I have this working ok but what I am doing is running the same for loop and if statement check for the active class on my section for the different click events. Looking for the simplest way to re-use it using just javascript not jquery.
<section class="section section-1 active">
<div class="button">
<div class="hidden-background"></div>
</div>
<div class="hidden-content"></div>
</section>
<section class="section section-2">
<div class="button">
<div class="hidden-background"></div>
</div>
<div class="hidden-content"></div>
</section>
<section class="section section-3">
<div class="button">
<div class="hidden-background"></div>
</div>
<div class="hidden-content"></div>
</section>
The button click event checks for the active section and just finds the first div tag (hidden-background) and applies an active class to it.
var section = document.querySelectorAll('.section');
var button = document.querySelectorAll('.button');
for (var s = 0; s < section.length; s++) {
if (section[s].classList.contains('active')) {
for (var b = 0; b < button.length; b++) {
button[b].addEventListener('click', function(){
this.getElementsByTagName('div')[0].classList.add('active');
});
}
}
}
The second click event again checks for the active section class and then adds the class active to the hidden-content div.
var section = document.querySelectorAll('.section');
var hiddenContent = document.querySelectorAll('.hidden-content');
for (var s = 0; s < section.length; s++) {
if (section[s].classList.contains('active')) {
for (var h = 0; h < hiddenContent.length; h++) {
hiddenContent[h].addEventListener('click', function(){
this.classList.add('active');
});
}
}
}
Thank you
I would do something like this:
const makeActive = function(evt) {
evt.target.parentElement
.querySelectorAll('.hidden-background, .hidden-content')
.forEach( el => el.classList.add('active'));
};
document
.querySelectorAll('.section.active .button')
.forEach( btn => btn.addEventListener('click', makeActive) );
And assuming the active sections also are toggled by javascript. (The above would no longer work if someone changed the active section, since the eventListener is still bound to the old section)
const makeActive = function(evt) {
if(
evt.target.className.contains('button') &&
evt.target.parentElement.className.contains('active')
){
evt.target.parentElement
.querySelectorAll('.hidden-background, .hidden-content')
.forEach( el => el.classList.add('active'));
}
};
document
.querySelectorAll('.section')
.forEach( section => section.addEventListener('click', makeActive) );
Of course, this whole thing would be easier with only css:
.hidden-background, .hidden-content { display: none; }
.active .hidden-background, .active .hidden-content { display: block; }
but I suppose that is a different question altogether...
I'm making a non responsive site responsive. For the mobile view I'm trying to show 3 li elements on landing, click "show more" another 3 load and so forth. Hit show less and 3 li items should be removed.
I'm working on a project with a lot more li items but was wondering if the issue I am experiencing is a scope problem? And if there is a way to fix it.
The project I'm working on features a scrollable div displaying the li items in one div and hiding the rest until the user clicks an arrow. (this is why I havent rewritten the code from my predecessor original site is here to illustrate what I mean http://www.asla.org/sustainablelandscapes/index.html)
Is there a solution here?
I have recreated my issue (simplified) in a fiddle
http://jsfiddle.net/gward90/xgmdkpb8/
EDIT: To further clarify, as seen with the fiddle all the li elements show on landing this should not be the case. Show less removes more than 3 items as well.
<div class="row">
<div class="col-md-12">
<ul class="thumbnails">
<li><div class="red"></div></li>
<li><div class="red"></div></li>
<li><div class="red"></div></li>
</ul>
</div>
</div>
<div class="row">
<div class="col-md-12">
<ul class="thumbnails">
<li><div class="blue"></div></li>
<li><div class="blue"></div></li>
<li><div class="blue"></div></li>
</ul>
</div>
</div>
<div class="row">
<div class="col-md-12">
<ul class="thumbnails">
<li><div class="green"></div></li>
<li><div class="green"></div></li>
<li><div class="green"></div></li>
</ul>
</div>
</div>
<div id="loadMore">Load more</div>
<div id="showLess">Show less</div>
$(document).ready(function () {
$('.thumbnails li:lt(3)').show();
$('#showLess').hide();
var items = 9;
var shown = 3;
$('#loadMore').click(function () {
$('#showLess').show();
shown = $('.thumbnails li:visible').size()+3;
if(shown< items) {$('.thumbnails li:lt('+shown+')').show();}
else {$('.thumbnails li:lt('+items+')').show();
$('#loadMore').hide();
}
});
$('#showLess').click(function () {
$('.thumbnails li').not(':lt(3)').hide();
});
});
Not sure if this is what you are aiming for, but this does something at least:
var totalCount; //Keeps track of the total number of li's, shown or hidden.
var currentCount; //Keeps track of the number of li's currently shown.
$(document).ready(function () {
//Count how many li's there are in total.
totalCount = $('.thumbnails li').size();
//Start by showing three of them.
currentCount = 3;
adjustLiShown();
$('#loadMore').click(function () {
//Increase by three and update.
currentCount += 3;
adjustLiShown()
});
$('#showLess').click(function () {
//Decrease by three and update.
currentCount -= 3;
adjustLiShown()
});
});
function adjustLiShown() {
//Hide all and then show the one with index under total count.
$('.thumbnails li').hide().filter(':lt(' + currentCount + ')').show();
//Only show "load more" if we haven't reached the total yet.
$('#loadMore').toggle(currentCount < totalCount);
//Only show "show less" if we are above the starting number.
$('#showLess').toggle(currentCount > 3);
}
Fiddle.
Try utilizing .slice()
$(document).ready(function () {
$('.thumbnails li:lt(3)').show();
// hide `.thumbnails` greater than 3
$('.thumbnails li:gt(2)').hide();
$('#showLess').hide();
var items = 9;
var shown = 3;
$('#loadMore').click(function (e) {
$('#showLess').show();
$(".thumbnails li:not(:visible)").slice(0, 3)
.show(function() {
if ($(".thumbnails li:visible").length === items) {
$(e.target).hide()
}
})
});
$('#showLess').click(function (e) {
$('.thumbnails li:visible').slice(-3).hide(function() {
if ($(".thumbnails li:visible").length === 0) {
$(e.target).hide()
};
if ($('.thumbnails li:visible').length < items) {
$("#loadMore").show()
}
});
});
});
jsfiddle http://jsfiddle.net/xgmdkpb8/6/
Try this,
$(document).ready(function () {
$('.row').hide();
$('.row:eq(0)').show();
var totalElements = $(".thumbnails li").length;
var elementsInEachRow = 3;
$('#loadMore').click(function () {
var lastVisibleElement = $(".thumbnails li").index($(".thumbnails li:visible").last()) + 1;
var indexOfRowToHide = (lastVisibleElement / 3);
$(".row:eq("+indexOfRowToHide+")").show();
$('#showLess').show();
});
$('#showLess').click(function () {
var lastVisibleElement = $(".thumbnails li").index($(".thumbnails li:visible").last()) + 1;
var indexOfRowToHide = (lastVisibleElement / 3) - 1;
$(".row:eq("+indexOfRowToHide+")").hide();
$('#loadMore').show();
});
});
Pen: http://codepen.io/vbrmnd/pen/ZbWEYW
I have the folowing code:
html:
<div class="container">
<div class="selected">A</div>
<div>B</div>
<div>C</div>
<div>D</div>
</div>
<button id="next">next!</button>
jQuery:
$("#next").click(function() {
$(".selected").removeClass("selected").next().addClass("selected");
});
What i want is loop through the divs in the container. I can do this to cycle:
$("#next").click(function() {
if ($(".selected").next().length == 0) {
$(".selected").removeClass("selected").siblings(":nth-child(1)").addClass("selected");
}
else {
$(".selected").removeClass("selected").next().addClass("selected");
}
});
But i think there is a simpler way. How can i make it simpler ? (I don't mind if you don't use the next() function).
jsFiddle: http://jsfiddle.net/S28uC/
I 'd prefer siblings.first() instead of siblings(":nth-child(1)"), but in essence you won't be able to wrap around without using some variant of next().length.
Update: If I were writing this from scratch, this is how I 'd do it:
$("#next").click(function() {
var $selected = $(".selected").removeClass("selected");
var divs = $selected.parent().children();
divs.eq((divs.index($selected) + 1) % divs.length).addClass("selected");
});
This approach is motivated by two factors:
When you want to cycle over a collection indefinitely, modulo comes to mind
Getting rid of the if makes for smarter-looking code
When setting the value of divs I preferred $selected.parent().children() over the equivalent $selected.siblings().add($selected) as a matter of taste -- there are practically endless possibilities.
One simple way is this :
$("#container").find("div:eq(0)").addClass("selected");
how about this.
...
var selected = $(".selected").removeClass("selected");
if (jQuery(selected).next().addClass("selected").length == 0
{jQuery(selected).siblings().first().addClass("selected");};
...
In old good AI manner you try to do the deed (addClass), if it worked (length <> 0) nothing more to do, otherwise you try again on the first of the siblings.
You can try this
var cont = $('.container'),
i = 0;
$("#next").on('click', function() {
cont.children().removeClass('selected');
i += 1;
if ( i === document.querySelectorAll('.container div').length ) { i = 0; }
cont.children().eq(i).addClass('selected');
});
var cont = $('.container'),
i = 0;
$("#next").on('click', function() {
cont.children().removeClass('selected');
// increase index for each click
i += 1;
// reset i if it reached to last index
//(hack to force next to go back to first element when we are at the end)
if ( i === document.querySelectorAll('.container div').length ) {
i = 0;
}
cont.children().eq(i).addClass('selected');
});
.selected {
background-color: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="selected">A</div>
<div>B</div>
<div>C</div>
<div>D</div>
</div>
<button id="next">next!</button>
simply you will increase i for each click and when it reach the end (divs length ) it will be reset.
I have 2 tabs at the top of a page. When one tab is clicked, I would like that tab to have an "active" class and the other tab to have an "inactive" class so that the user can see what tab is currently selected. How can I go about doing this with javascript/css?
<div class="tabActive">
Option 1
</div>
<div id="tabInactive">
Option 2
</div>
another non-jQuery solution could be the following that works with more than two div:
function changeClass(elClass) {
var divsLenght = document.getElementsByTagName("div").length;
for (var i = 0; i < divsLenght; i++) {
document.getElementsByTagName("div")[i].className = "tabInactive";
}
elClass.className = "tabActive";
}
Demo: http://jsbin.com/opetec/2
<div class="tabInactive" onclick="this.classname='tabActive'"></div>
if using jquery:
$("div.tabInactive").click(function() {
$("div.tabInactive").removeClass("tabActive");
$(this).addClass("tabActive");
});
here's a solution that doesn't use any jQuery! it does assume there is only 2 tabs thought.
http://jsfiddle.net/nYpV3/
<div id="tab1" onclick="setToActive(this, 'tab2');">
Option 1
</div>
<div id="tab2" onclick="setToActive(this, 'tab1');">
Option 2
</div>
function setToActive(me, otherId){
me.className='active';
document.getElementById(otherId).className='inactive';
}
Give your tabs a class of "tab"...
HTML:
<div class="tab">
...
</div>
<div class="tab">
...
</div>
JS:
function getByClass(_class, elem) {
var i, result = [], elems = document.getElementsByTagName("div"); //get the elements
for (i = 0; i < elems.length; i++) {
if (elems[i].className.indexOf(_class) !== -1) { //if the elements have the class passed in, add it to the result array
result.push(elems[i]);
}
}
return result;
}
var i, tabs = getByClass("tab", "div"); //get all divs with class tab
for (i = 0; i < tabs.length; i++) { //for each tab...
tabs[i].onclick = function() { //wire up it's click event...
//to clear the other tabs...
var j;
for(j=0; j < tabs.length; j++) {
tabs[j].className = tabs[j].className.replace(" active", "");
}
this.className += " active"; //where active is a class predefined in the CSS
};
}
http://jsfiddle.net/thomas4g/pqMq2/12/
Try this using jQuery
<div class="tab active">
Option 1
</div>
<div class="tab">
Option 2
</div>
<script>
$(function(){
$(".tab").live("click", function(){
$(".tab").removeClass("active");
$(this).addClass("active");
});
});
</script>
This is my guess:
$('.tabActive, #tabInactive').click(function() {
$(this).toggleClass('active');
}