I have a slideshow all put together but I'm having trouble using an onClick to insert an additional image. What am I missing?
function newDivs(n) {
var i;
var x = document.getElementsById("photo");
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 = "block";
}
<input type="text" name="photo" id="photo" value="http://static.boredpanda.com/blog/wp-content/uuuploads/cute-baby-animals/cute-baby-animals-23.jpg" />
<button id="addPicture" onclick="newDivs(+1)">Add New Image</button>
You have many mistakes to begin with:
wrong:
var x = document.getElementsById("photo");
right:
var x = document.getElementById("photo").val;
There a few things you need to understand.
When you want to perform action on multiple element never try id. (ID always return only single element. and it can not be run with multiple element.
Your Javascript function is wrong getElementsById. correct is getElementById. just because of as i said ID return single element ( getElementById - just remove (s) from the function.
try to use query selector. like i have used in your example.(querySelectorAll)
Query selector function will help you a lot !. and if you are new in javascript. if you can try jQuery it will be really easy for you.
If you want to display image you need to play with img tag. right now you are getting URL from input tag and trying to hide them doesn't make sense ;
Here is the your solution
var i= 0;
var slideIndex = 0;
function newDivs(n) {
var i;
var x = document.querySelectorAll(".photo");
console.log(x);
if (n > x.length) {
slideIndex = 1
}
if (n < 1) {
slideIndex = x.length
};
for (var index = 0; index < x.length; index++) {
console.log(x[index].style);
x[index].style.display = 'none';
}
console.log(slideIndex);
x[slideIndex].style.display = "block";
}
<input type="text" class="photo" name="photo" id="photo" value="http://static.boredpanda.com/blog/wp-content/uuuploads/cute-baby-animals/cute-baby-animals-23.jpg" />
<button id="addPicture" onclick="newDivs(+1)">Add New Image</button>
Related
I am trying to understand why this code isn't going back to slideIndex = 0;
Can someone please explain, at the forth click I am getting undefined instead of jumping back to the first index of the slide?
Thank you for explaining.
slideIndex = 0;
function nextSlide() {
console.log(slides[slideIndex]);
slideIndex++;
if(slideIndex > slides.length){
slideIndex = 0;
}
}
Actually this the whole code, so I am trying to understand why the slideIndex is not jumping back to slideIndex=0;
One the slideIndex > myArray.length; it needs to jump back to the initializes slideIndex, but I am getting this error:
Uncaught TypeError: Cannot read properties of undefined (reading 'style')
at HTMLButtonElement.
Please help:
slideIndex=0;
const prevbtn = document.querySelector(".prev");
const nextbtn = document.querySelector(".next");
let myArray = document.querySelectorAll("img");
let i = 0;
for (i = 0; i < myArray.length; i++) {
myArray[i].style.display = "none";
}
myArray[slideIndex].style.display = "block";
nextbtn.addEventListener("click", function(){
myArray[slideIndex+1].style.display="block";
slideIndex++;
if(slideIndex >= myArray.length-1){
console.log("yes");
slideIndex=0;
}
});
prevbtn.addEventListener("click", function(){
});
(this answer refers to code supplied by the author within another answer)
the problem is this line: myArray[slideIndex+1].style.display="block";
let's say there are 9 items in myArray and slideIndex is 8. then the above tries to set the style on myArray[9] which does not exist.
you can fix this by either moving the style change to after you've adjusted and validated the slideIndex (in your next two lines), or you can use a modulus adjustment such as this: myArray[(slideIndex+1)%myArray.length].style.display="block";
This is working, but I am not sure if this a good written code, except that I can simplify the code.
let slideIndex=0;
const prevbtn = document.querySelector(".prev");
const nextbtn = document.querySelector(".next");
let myArray = document.querySelectorAll("img");
let i = 0;
for (i = 0; i < myArray.length; i++) {
myArray[i].style.display = "none";
}
myArray[slideIndex].style.display = "block";
nextbtn.addEventListener("click", function(){
if(slideIndex == 0){
slideIndex = slideIndex + 1;
}
if(slideIndex > myArray.length-1){
slideIndex = 0;
for (i = 0; i < myArray.length; i++) {
myArray[i].style.display = "none";
}
myArray[slideIndex].style.display = "block";
}
if(slideIndex<myArray.length){
myArray[slideIndex].style.display = "block";
console.log(slideIndex);
}
slideIndex++;
});
prevbtn.addEventListener("click", function(){
});
Thank you for answering, but I am using this: myArray[slideIndex+1].style.display="block"; for jumping by first click to next image otherwise you have to click twice before going to next image.
I have now this code which seems to work except that I have to click twice when page load to get the next image.
How can that be fixed?
let slideIndex=0;
const prevbtn = document.querySelector(".prev");
const nextbtn = document.querySelector(".next");
let myArray = document.querySelectorAll("img");
let i = 0;
for (i = 0; i < myArray.length; i++) {
myArray[i].style.display = "none";
}
myArray[slideIndex].style.display = "block";
nextbtn.addEventListener("click", function(){
if(slideIndex > myArray.length-1){
slideIndex = 0;
for (i = 0; i < myArray.length; i++) {
myArray[i].style.display = "none";
}
myArray[slideIndex].style.display = "block";
}
myArray[slideIndex].style.display = "block";
console.log(slideIndex);
slideIndex++;
});
prevbtn.addEventListener("click", function(){
});
I'm trying to add manual control to an auto slider: https://jsfiddle.net/t8ap0gvz/ The auto play works but the manual controls (prev/next & dots) don't function. What am I doing wrong?
var slideIndex = 0;
var slides = document.getElementsByClassName("mySlides");
showSlides();
function showSlides() {
var i;
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
slideIndex++;
if (slideIndex> slides.length) {slideIndex = 1}
slides[slideIndex-1].style.display = "block";
setTimeout(showSlides, 5000); // Change image every 5 seconds
}
function currentSlide(no) {
var i;
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
slideIndex = no;
slides[no-1].style.display = "block";
}
function plusSlides(n) {
var newslideIndex = slideIndex + n;
if(newslideIndex < 4 && newslideIndex > 0){
currentSlide(newslideIndex);
}
}
In the answer above,he said about the DOM to load, in JSfiddle in the option of the javascript change the order in where the javascript is write. For functions in onclick is better put after all the html, by default JSfiddle put in windows.onload so only change the order in No wrap - bottom of and this will work.
In LOAD TYPE select that option
In a real code HTML the script tag will be in the end of your HTML body. In a script tag.
I think it's loading the functions before the html. When I move the call of showSlides() to like below it works:
// Await DOM to be loaded
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', () => {
showSlides();
});
} else {
showSlides();
}
I've been trying to add multiple slideshows on one page using HTML 5, CSS and JS to my Django app from this example.
I get that this piece of code was not meant for multiple slideshows on one page, however, I can't seem to find out how to get it to work.
More specifically when I add a second slideshow It doesn't change the proper image gallery.
That script wasn't written to support multiple slideshows on the same page however if you create an object and pass the wrapping div's id you can make it work.
function SlideShow(id) {
this.container = document.getElementById(id);
this.leftBtn = this.container.querySelector('.w3-display-left');
this.rightBtn = this.container.querySelector('.w3-display-right');
this.slideIndex = 1;
var that = this;
this.init = function() {
this.showDivs(this.slideIndex);
};
this.plusDivs = function(n) {
this.showDivs(this.slideIndex += n);
};
this.showDivs = function(n) {
var x = this.container.getElementsByClassName("mySlides");
if (n > x.length) {this.slideIndex = 1}
if (n < 1) {this.slideIndex = x.length}
for (var i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
x[this.slideIndex-1].style.display = "block";
};
this.leftBtn.addEventListener('click', function() {
that.plusDivs(-1);
});
this.rightBtn.addEventListener('click', function() {
that.plusDivs(1);
});
}
var foo = new SlideShow('foo');
foo.init();
var bar = new SlideShow('bar');
bar.init();
HTML
<div id="foo" class="w3-content w3-display-container">...</div>
<div id="bar" class="w3-content w3-display-container">...</div>
Demo: http://jsfiddle.net/zwsmcn3q/31/
Note: the slideshow code can be improved but that's out of scope for this answer.
Note: you can also write this as a class with ES6: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes
I'm trying to create an image gallery. Most of it is working as intended, however, the thing I want to change on this gallery is so that when I click on the next picture or previous picture, I want the thumbnails to show the next 8 pictures. At the moment it's showing the next picture
PHP code:
<?php
$pics = glob("img/2016/*/*.{JPG,PNG,GIF,jpg,png,gif}", GLOB_BRACE);
if(count($pics)) {
rsort($pics);
foreach($pics as $pictures) {
echo "<a href='$pictures' target='_blank'><img class='Gallery' src='$pictures'></a>";
}
echo '<a class="button-floating lbutton" onclick="plusDivs(-1);plusThumbs(-1)"><div class="gall_nav">❮</div></a>';
echo '<a class="button-floating rbutton" onclick="plusDivs(1);plusThumbs(1)"><div class="gall_nav">❯</div></a>';
echo '</div>';
echo '<div class="thumbs_container">';
foreach(array_slice($pics, 1) as $thumbs)
if ($thumb++ < 8){
echo "<a href='$thumbs' target='_blank'><img class='thumbs' src='$thumbs'></a>";
}
} else {
echo "Sorry, no images to display!";
}
?>
The code is showing 1 thumbnail which updates correctly, but I want 8 thumbnails at least..
var slideIndex = 1;
showDivs(slideIndex);
function plusDivs(n) {
showDivs(slideIndex += n);
}
function showDivs(n) {
var i;
var x = document.getElementsByClassName("Gallery");
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 = "block";
var thumbIndex = slideIndex +1;
showThumbs(thumbIndex);
function plusThumbs(t){
showThumbs(thumbIndex += t);
}
function showThumbs(t){
var g;
var getThumb = document.getElementsByClassName("thumbs");
if (t > getThumb.length) {thumbIndex = 1}
if (t < 1) {thumbIndex = getThumb.length};
for (g = 0; g < getThumb.length; g++){
getThumb[g].style.display = "none";
}
getThumb[thumbIndex-1].style.display = "block";
}
}
Any ideas on how I achieve this?
I hope, I understood your idea and what you want to do. Anyway here is my advises. At first I would like to say, that building html tags using php is not even a good idea. It's always a better way to separate code, instead of making some kind of mix. So, I'll advice you to use your php script only to find all images and send an array of src to client side (in JSON format). When you get an array of src, you could make a gallery only using javascript or jQuery. With jQuery you could make a simple GET Ajax Request, in order to get an array of img's src. Then you could init your gallery.
The gallery you can make in this way:
So you have an id an change it by clicking prev or next buttons. After clicking you regenerate the current image and thumbs container.
Here is the working example (jQuery):
<!DOCTYPE html>
<html>
<head>
<title>Test App</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
</head>
<body>
<div class="galery">
<div class="image_wrapper">
<button class="prev">Prev</button>
<img src="" alt="curr_image" class="curr_image" />
<button class="next">Next</button>
</div>
<div class="thumbs_wrapper"></div>
</div>
<script type="text/javascript">
$(document).ready(function() {
var fakeSrc =
['src1', 'src2', 'src3', 'src4', 'src5', 'src6','src7', 'src8', 'src9', 'src10', 'src11'];
var cId = 0;
var thumbs_wrapper = $('.thumbs_wrapper');
var curr_image = $('.curr_image');
var prev = $('.prev');
var next = $('.next');
var updateThumbs = function() {
var max = ( (cId + 9) > fakeSrc.length) ? fakeSrc.length : cId + 9;
thumbs_wrapper.html('');
for (var i = cId+1; i < max; ++i) {
var img = document.createElement('img');
img.className = 'thumb_image';
var src = fakeSrc[i];
img.alt = src;
img.src = src;
thumbs_wrapper.append(img);
}
}
var setCurrImg = function() {
curr_image.src = fakeSrc[cId];
curr_image.prop('src', fakeSrc[cId]);
curr_image.prop('alt', fakeSrc[cId]);
}
var updateGalery = function() {
setCurrImg();
updateThumbs();
}
prev.click(function() {
--cId;
if (cId < 0) cId = 0;
updateGalery();
});
next.click(function() {
++cId;
if (cId > fakeSrc.length - 1) cId = fakeSrc.length - 1;
updateGalery();
});
updateGalery();
});
</script>
</body>
</html>
Hope, that I've helped you to find the solution.
I have an history feature for a particular,div on my website. Everything worked fine up to now, I was inserting HTML as strings from javascript and re-display them with .innerHTML. Now I try to clean up the javascript from all HTML strings and I have this problem: history browsing of the div works in FF, Chrome and some other, but not IE (8 to 11), can't understand why. Is it a cloneNode() or a reference issue I don't see ?
Below is a small script to reproduce the behaviour, you can play with here: http://jsfiddle.net/yvecai/7e8tksm3/
My code works as follow: each time I display something in Mydiv, I clone it and append it in an array.
The function prev() or next() append the corresponding nodes from the array for display.
The script first create 5 contents '1' ... '5' that the user can display with the functions prev() and next(). In IE, when you go prev(), then next(), only the first and last records are shown. In other browsers, no problem.
var cache = [];
var i = 0;
function next() {
var hist = document.getElementById('history');
i += 1;
if (i > 4) {
i = 4
};
hist.innerHTML = '';
hist.appendChild(cache[i]);
}
function prev() {
var hist = document.getElementById('history');
i -= 1;
if (i < 0) {
i = 0
};
hist.innerHTML = '';
hist.appendChild(cache[i]);
}
function cacheInHistory(div) {
cache.push(div.cloneNode(true));
}
function populate() {
for (i = 0; i < 5; i++) {
var hist = document.getElementById('history');
hist.innerHTML = '';
var Mydiv = document.createElement('div');
Mydiv.innerHTML = i;
hist.appendChild(Mydiv);
cacheInHistory(Mydiv);
}
i = 4
}
I tried to simplify your code:
In the function populate (onload) create and populate the array cache. As last operation append your child.
In your next or previous function use replaceChild instead of append and remove innerHTML.
var cache=[];
var i = 0;
function next(){
var hist = document.getElementById('history');
i = (++i > 4) ? 4 : i;
hist.replaceChild(cache[i], hist.children[0]);
}
function prev(){
var hist = document.getElementById('history');
i = (--i < 0) ? 0 : i;
hist.replaceChild(cache[i], hist.children[0]);
}
function cacheInHistory(div){
cache.push(div.cloneNode(true));
}
function populate(){
var hist = document.getElementById('history');
for (i=0 ; i<5 ; i++){
hist.innerHTML='';
var Mydiv = document.createElement('div');
Mydiv.innerHTML = i;
cacheInHistory(Mydiv);
}
i = 4
hist.appendChild(cache[i]);
}
<body onload="populate();">
<div id="prev" onclick="prev()">
prev
</div>
<div id="next" onclick="next()">
next
</div>
<hr/>
<div id="history">
</div>
</body>