I currently have it so that a block of text changes when you click on the "page" number, but I'd like to add previous and next buttons.
Check out my current version here: http://jsfiddle.net/ZBWqS/
Every solution I've thought of turns into a mess of non-working code when I start going.
Sorry for the noob-JS question.
<div id="1" style="display: block;">
<p>This is the first block of text</p>
<p class="page">
1 of 3
</p>
</div>
<div id="2" style="display: none;">
<p class="red">This is the second block of text</p>
<p class="page">
2 of 3
</p>
</div>
<div id="3" style="display: none;">
<span>This is the third block of text</span>
<p class="page">
3 of 3
</p>
</div>
<div class="bottom">
1 2 3
</div>
<script>
function show(id) {
document.getElementById(id).style.display = 'block';
}
function hide(id) {
document.getElementById(id).style.display = 'none';
}
</script>
I have also build a refactored version of your code, you decide which one you like more ;)
http://jsfiddle.net/haDAj/
HTML
<div id="1" class="pagecontainer" style="display: block;">
<p>This is the first block of text</p>
<p class="page">
1 of 3
</p>
</div>
<div id="2" class="pagecontainer" style="display: none;">
<p class="red">This is the second block of text</p>
<p class="page">
2 of 3
</p>
</div>
<div id="3" class="pagecontainer" style="display: none;">
<span>This is the third block of text</span>
<p class="page">
3 of 3
</p>
</div>
<div class="bottom">
‹
1
2
3
›
</div>
SCRIPT
var currentPage = 1;
function page(pg)
{
var els = document.getElementsByClassName("pagecontainer");
for (var i = 0; i < els.length; i++)
{
var page_of_container = els[i].getAttribute("id");
els[i].style.display = page_of_container == pg ? 'block' : 'none';
}
currentPage = pg;
}
function prev()
{
if (currentPage <= 1) return;
page(currentPage -1);
}
function next()
{
if (currentPage >= document.getElementsByClassName("pagecontainer").length) return;
page(currentPage + 1);
}
Keep a variable to store where you are, increment/decrement it, then show content based on that variable.
http://jsfiddle.net/ZBWqS/3/
// hold where we are right now. For previous and next to make sense,
// you have to know where you are.
var current = 1;
// function to go to previous
var prev = function() {
current -= 1;
if (current < 1) current = 1; // can't go too far previous
showContent();
};
// function to go next
var next = function() {
current += 1;
if (current > 3) current = 3; // can't go too far next
showContent();
};
// Update what content we are showing based on the "current" index
var showContent = function() {
var display;
for (var i = 1; i <= 3; i++) {
if (i == current) {
display = 'block';
} else {
display = 'none';
}
document.getElementById(i).style.display = display;
}
};
// bind the prev and next function to the links
document.getElementById('prev').onclick = prev;
document.getElementById('next').onclick = next;
// Setup the initial state of the content
showContent();
Related
I am working on a website that should have image sliders with clickable buttons that flip to the next image.
I was able to make a single slider / page, but as I have no experience in coding yet, I ran into difficulties when I was trying make multiple sliders following each other directly. The buttons of a certain slider started to mix up, and target other sliders too, or only the first one, but not the way I wanted..
So I started copying and repeating the same lines of code and applying them to groups of images separately.
I also want some text to flip together with the images, so I grouped the text and images together with the buttons, and finally I ended up having a lot of repetition, and way too long codes. :-)
Right now it works, but I assume that there is a much easier, solution, that would make my code a lot shorter.
Can someone help me with:
Having one good java script, that doesn't mix up the targets, when having multiple sliders?
Having only one "buttons"/slider instead of copying them to all the "containergrid"s groups, but still flipping the text together with the image?
Thanks, and sorry for the long code. :)
<div class="content">
<!---THE FIRST SLIDER--->
<div class="slider_1">
<div class="slides_1">
<div class="containergrid">
<div class="description">
<p class="maindescription">Description</p>
<p class="year">2017</p>
</div>
<div class="imgbutton">
<img class="img_1_1">
<div class="button">
<button class="prev"
onclick="plusDivs1(-1)"></button>
<button class="next"
onclick="plusDivs1(1)"></button>
</div>
</div>
</div>
</div>
<div class="slides_1">
<div class="containergrid">
<div class="description">
<p class="maindescription">Description</p>
<p class="year">2017</p>
</div>
<div class="imgbutton">
<img class="img_1_2">
<div class="button">
<button class="prev"
onclick="plusDivs1(-1)"></button>
<button class="next"
onclick="plusDivs1(1)"></button>
</div>
</div>
</div>
</div>
</div>
<!---THE SECOND SLIDER--->
<div class="slider_2">
<div class="slides_2">
<div class="containergrid">
<div class="description">
<p class="maindescription">Description</p>
<p class="year">2017</p>
</div>
<div class="imgbutton">
<img class="img_2_1">
<div class="button">
<button class="prev"
onclick="plusDivs1(-1)"></button>
<button class="next"
onclick="plusDivs1(1)"></button>
</div>
</div>
</div>
</div>
<div class="slides_2">
<div class="containergrid">
<div class="description">
<p class="maindescription">Description</p>
<p class="year">2017</p>
</div>
<div class="imgbutton">
<img class="img_2_2">
<div class="button">
<button class="prev"
onclick="plusDivs1(-1)"></button>
<button class="next"
onclick="plusDivs1(1)"></button>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
var slideIndex = 1;
showDivs1(slideIndex);
function plusDivs1(n) {
showDivs1(slideIndex += n);
}
function showDivs1(n) {
var i;
var x = document.getElementsByClassName("slides_1");
if (n > x.length) { slideIndex = 1 }
if (n < 1) { slideIndex = x.length }
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
x[slideIndex - 1].style.display = "flex";
}
</script>
<script>
var slideIndex = 1;
showDivs2(slideIndex);
function plusDivs2(n) {
showDivs2(slideIndex += n);
}
function showDivs2(n) {
var i;
var x = document.getElementsByClassName("slides_2");
if (n > x.length) { slideIndex = 1 }
if (n < 1) { slideIndex = x.length }
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
x[slideIndex - 1].style.display = "flex";
}
</script>
So you would just have to pass a reference to your slides into the showDivs function, so you can keep the clicks independent of one another. You'd still have to initialize each slider separately.
function plusDivs(slider, n) {
showDivs(slider, slideIndex += n);
}
function showDivs(slider, index) {
var i;
var x = document.getElementsByClassName(slider);
if (index > x.length) {
slideIndex = 1
}
if (index < 1) {
slideIndex = x.length
}
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
x[slideIndex - 1].style.display = "flex";
}
// Initialize the sliders
var slideIndex = 1;
showDivs('slides_1', slideIndex);
showDivs('slides_2', slideIndex);
In your HTML you just need to pass the reference to the plusDivs function:
onclick="plusDivs('slides_1', 1)"
Here is a fiddle showing a working example
I'm trying to set up pagination for some blog posts. It works with the first page, and I check my tests to see if the loop is actually populating the "postsToDisplay" array (which it does), but when I click the second-page button, nothing shows up. I can click the first-page button and it brings the first page of posts back up. For some reason, it won't push the new arrays to the page though.
I've tried adding and taking away tests to see what is working. The array is definitely being populated, and the loop is going through the correct "i" values just fine.
Here's some edited code to reproduce my problem:
//Use this as "scripts.js"
$(document).ready(function() {
var realBlog = document.getElementsByClassName("realBlog");
var postsPerPage = 2;
var $pagination = $(".pagination")
function showPage(page) {
$(realBlog).hide();
let postsToDisplay = [];
for (let i = 0; i < realBlog.length; i += 1) {
if (i >= page * postsPerPage && i <= page * postsPerPage + postsPerPage - 1) {
postsToDisplay.push(realBlog[i]);
console.log(i); //Test to see if the loop is running the correct numbers
$(postsToDisplay[i]).show();
}
}
console.log(postsToDisplay); //Test to see if the array is full
return postsToDisplay;
}
showPage(0);
function createPageNumbers() {
let createUl = document.createElement("ul");
createUl.className = "pageNumbers";
for (let i = 1; i <= Math.ceil(realBlog.length/2); i += 1) {
let createLi = document.createElement("li");
let createA = document.createElement("a");
createA.href = "#" + i;
createA.textContent = i;
createLi.className = "pageButton";
createLi.append(createA);
createUl.append(createLi);
$(".pagination").append(createUl);
createA.addEventListener("click", () => {
showPage(i-1);
});
}
}
createPageNumbers();
});
//Use this as index.html
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="scripts.js"></script>
</head>
<body>
<div class="container realBlog">
<h1 class="realBlogTitle threeDText">Title</h1>
<p class="entry"></p>
<div class="entryInfo">
<span class="tag1"></span>
<span class="tag2"></span>
<span class="date"></span>
<span class="time"></span>
</div>
<div class="borderBottom"></div>
</div>
<div class="container realBlog">
<h1 class="realBlogTitle threeDText">Title</h1>
<p class="entry"></p>
<div class="entryInfo">
<span class="tag1"></span>
<span class="tag2"></span>
<span class="date"></span>
<span class="time"></span>
</div>
<div class="borderBottom"></div>
</div>
<div class="container realBlog">
<h1 class="realBlogTitle threeDText">Title</h1>
<p class="entry"></p>
<div class="entryInfo">
<span class="tag1"></span>
<span class="tag2"></span>
<span class="date"></span>
<span class="time"></span>
</div>
<div class="borderBottom"></div>
</div>
<div class="pagination"></div>
</body>
</html>
Page 1 should show posts 1 and 2, page 2 should show post 3.
Alright, I found the answer, and of course, it's a silly mistake. I have this little snippet: $(postsToDisplay[i]).show();
I'm not sure why I'm trying to show each 'i' when I can just show the whole array... So the fix is $(postsToDisplay).show();
I have the following HTML code and I'm really struggling to come up with a solution for the following: (pseudo code, javascript or jquery answers please, but would prefer jquery)
When the page loads, hide all of the list items except for the first
5 (display only the first five, select by unique id)
Two buttons on
the bottom of the list, one for "older" one for "newer".
When older btn is
pressed, show the next 5 on the list (might just be one list-item if
there is 6 altogether)
When "newer" is pressed, show the 5 in front of the current list-items
Hide newer button if already on the first page 5
code:
<div class="container">
<div class="list-item" id="13">
<p>First Item</p>
</div>
<div class="list-item" id="12">
<p>Second Item</p>
</div>
<div class="list-item" id="11">
<p>Third Item</p>
</div>
<div class="list-item" id="10">
<p>Fourth Item</p>
</div>
<div class="list-item" id="9">
<p>Fifth Item</p>
</div>
<div class="list-item" id="8">
<p>Sixth Item</p>
</div>
… ( more list-items)
</div>
<button onclick="showOlder()">Older</button>
<button onclick="showNewer()">Newer</button>
After further research and trial and error I Was able to come up with a solution. I thought I'd post it if anyone else is looking for something similar. Please note I'm not an expert in jQuery and this code can probably be done in a more optimised way.
$(document).ready(function () {
btnNewer.hide();
for (i = numOfItems; i >= 1; i--) {
if (i == numOfItems - (5 * page)) {
page++;
}
$("#" + i).addClass("Page-" + page);
}
for (i = 0; i <= numOfPages; i++) {
if (i != 1) {
hidePage(i);
}
}
});
var numOfItems = $('div.list-item').length;
var numOfPages = Math.ceil(numOfItems / 5);
var page = 1;
var currentPage = 1;
var btnOlder = $("#showOlder")
var btnNewer = $("#showNewer")
function hidePage(pageNum) {
$('.Page-' + pageNum).hide();
}
function showPage(pageNum) {
$('.Page-' + pageNum).show();
}
btnOlder.on("click", function () {
hidePage(currentPage);
currentPage++;
showPage(currentPage);
CheckIfOnLastPage();
CheckIfOnFirstPage();
})
btnNewer.on("click", function () {
hidePage(currentPage);
currentPage--;
showPage(currentPage);
CheckIfOnFirstPage();
CheckIfOnLastPage();
})
function CheckIfOnFirstPage() {
if (currentPage == 1) {
btnNewer.hide();
} else {
btnNewer.show();
}
}
function CheckIfOnLastPage() {
if (currentPage == numOfPages) {
btnOlder.hide();
} else {
btnOlder.show();
}
}
I have 3 sliders on my page I'm a building but i am just curious to know the best way to go about targeting only the active one so the javascript below would work for all of them. Everything seems to work fine if i disable the other 2 sliders. First time I have done something like this.
I'm guessing my javascript selectors may need to change some what to get it to work.
Appreciate any advice on the best way forward.
var sliderSlide = document.querySelectorAll('.slider__slide');
var nextSlide = document.querySelector('.slider__button--next');
var previousSlide = document.querySelector('.slider__button--previous');
var currentSlide = 0;
var currentSlideImg = 0;
//Reset slides
function resetSlides() {
for (var s = 0; s < sliderSlide.length; s++) {
sliderSlide[s].classList.remove('active');
}
for (var i = 0; i < sliderSlideImg.length; i++) {
sliderSlideImg[i].classList.remove('active');
}
}
//Start slides
function startSlide() {
resetSlides();
sliderSlide[0].classList.add('active');
sliderSlideImg[0].classList.add('active');
}
//Previous slide
function slidePrevious() {
resetSlides();
sliderSlide[currentSlide - 1].classList.add('active');
currentSlide--;
sliderSlideImg[currentSlideImg - 1].classList.add('active');
currentSlideImg--;
}
previousSlide.addEventListener('click', function() {
if (currentSlide === 0 && currentSlideImg === 0) {
currentSlide = sliderSlide.length;
currentSlideImg = sliderSlideImg.length;
}
slidePrevious();
});
//Next slide
function slideNext() {
resetSlides();
sliderSlide[currentSlide + 1].classList.add('active');
currentSlide++;
sliderSlideImg[currentSlideImg + 1].classList.add('active');
currentSlideImg++;
}
nextSlide.addEventListener('click', function() {
if (currentSlide === sliderSlide.length - 1 && currentSlideImg === sliderSlideImg.length - 1) {
currentSlide = -1;
currentSlideImg = -1;
}
slideNext();
});
<div class="slider slider--1 active">
<div class="slider__slide">
<p class="slider__text">some text</p>
</div>
<div class="slider__slide">
<p class="slider__text">some text</p>
</div>
<div class="slider__slide">
<p class="slider__text">some text</p>
</div>
<div class="slider__buttons">
<span class="slider__button--previous">Previous</span>
<span class="slider__button--next">Next</span>
</div>
</div>
<div class="slider slider--2">
<div class="slider__slide">
<p class="slider__text">some text</p>
</div>
<div class="slider__slide">
<p class="slider__text">some text</p>
</div>
<div class="slider__slide">
<p class="slider__text">some text</p>
</div>
<div class="slider__buttons">
<span class="slider__button--previous">Previous</span>
<span class="slider__button--next">Next</span>
</div>
</div>
<div class="slider slider--3">
<div class="slider__slide">
<p class="slider__text">some text</p>
</div>
<div class="slider__slide">
<p class="slider__text">some text</p>
</div>
<div class="slider__slide">
<p class="slider__text">some text</p>
</div>
<div class="slider__buttons">
<span class="slider__button--previous">Previous</span>
<span class="slider__button--next">Next</span>
</div>
</div>
You can create loop over .slider and then use querySelector on each item, that way you will have variables for each slider
Array.from(document.querySelectorAll('.slider')).forEach(function(slider) {
var sliderSlide = slider.querySelectorAll('.slider__slide');
var nextSlide = slider.querySelector('.slider__buttons--next');
var previousSlide = slider.querySelector('.slider__buttons--previous');
...
});
or if you prefer for loop:
var sliders = document.querySelectorAll('.slider');
for (var i = 0; i < sliders.length; ++i) {
var slider = sliders[i];
...
}
document.querySelector('.slider--3 .slider__slide')
but I would recommend to put id's on your sliders and then select
document.querySelector('#slider--3')
when i press any key i need to display first div "d1" others hide and i press any key again it display secound div "d2" others hide and press any key again it display third div "d3" others hide ..till six div..not repeating the process again.
<div class="objects" id="d1">
<img src="images/d1.jpg" />
</div>
<div class="objects" id="d2">
<img src="images/d2.jpg" />
</div>
<div class="objects" id="d3">
<img src="images/d3.jpg" />
</div>
.......
.......
<div class="objects" id="d6">
<img src="images/d6.jpg" />
</div>
when i press any key i need to display 1st div then i press any key display 2nd div..till 6th div..
how to do it in javascript?
<html>
<head>
<style type="text/css">
.Div
{
display: none;
}
</style>
<script type="text/javascript">
var i = 0;
function KeyHandler() {
i++;
var divs = document.getElementsByClassName("Div");
for (var div = 0; div < divs.length - 1; div++) {
divs[div].style.display = 'none';
}
var ele = document.getElementById("d" + i);
ele.style.display = "block";
}
</script>
</head>
<body onkeyup="KeyHandler()">
Press any key..
<div id="d1" class="Div">
<h5>
Div1</h5>
</div>
<div id="d2" class="Div">
<h5>
Div2</h5>
</div>
<div id="d3" class="Div">
<h5>
Div3</h5>
</div>
<div id="d4" class="Div">
<h5>
Div4</h5>
</div>
<div id="d5" class="Div">
<h5>
Div5</h5>
</div>
<div id="d6" class="Div">
<h5>
Div6</h5>
</div>
</body>
</html>
Try this out
var currentVisible = 0;
document.onkeyup = function() {
// First hide all by class 'objects'
// Requires IE9+ FF3+, others are supported
var objs = document.getElementsByClassName('objects');
for (var i=0; i<objs.length; i++) {
objs[i].style.display = 'none';
}
// Show the one we are supposed to show
if (++currentVisible == 7)
currentVisible = 1;
var el = document.getElementById('d' + currentVisible);
el.style.display = 'block';
}
100% untested tho, since I have no access to any fiddle atm.