Unable to add an onclick event to element using JS - javascript

Hey I have a span element that I am creating with JS and I want it to also have an onclick event that calls a function. I am referring to the function fillSlides() and dotFunction(), but I will show all of my functions.
function openModal() {
document.getElementById('myModal').style.display = "block";
}
function closeModal() {
document.getElementById('myModal').style.display = "none";
}
var slideIndex = 1;
showSlides(slideIndex);
function plusSlides(n) {
showSlides(slideIndex += n);
}
function currentSlide(n) {
showSlides(slideIndex = n);
}
function fillSlides(modalID){
var container = document.getElementsByClassName("modal-content");
var bcontainer = document.getElementById("myModal");
var dcontainer = document.createElement('dot_content');
var slides = {
"1": ["Images/LS_01.jpg", "Images/LS_02.jpg", "Images/LS_03.jpg", "Images/LS_04.jpg" ],
"2": ["Images/LS_05.jpg", "Images/LS_06.jpg", "Images/LS_07.jpg", "Images/LS_08.jpg" ],
"3": ["Images/img1.jpg", "Images/img2.jpg", "Images/img3.jpg", "Images/2.jpg" ]
};
var modal_num = modalID.getAttribute('data-modal');
//alert(slides[modal_num].length);
for (var i = 0 ; i < slides[modal_num].length; i++) {
var the_divs = document.createElement('div');
var s_img = document.createElement('img');
var s_dot = document.createElement('span');
the_divs.className = 'mySlides';
s_img.src = slides[modal_num][i];
the_divs.appendChild(s_img);
container[0].appendChild(the_divs);
dcontainer.className = 'dot-content';
dcontainer.id = 'dot_content';
s_dot.className = 'demo';
dcontainer.appendChild(s_dot);
container[0].appendChild(dcontainer);
s_dot.onclick = currentSlide(i);
}
}
/*
function clearSlides(){
var myNode = document.getElementById("modal_content");
while (myNode.firstChild) {
myNode.removeChild(myNode.firstChild);
}
}*/
function clearSlides() {
var myNode = document.getElementById("modal_content");
//use spread operator to convert nodelist to array for using
// array methods
var c = [...myNode.children];
c.forEach(function(item, index) {
console.log(item)
// check if the current element have a class using 'contains'
if (!item.classList.contains('elbutton')) {
//use remove method to remove the element
item.remove();
}
})
}
/*
function clearSlides(){
var myNode = document.getElementById("modal_content");
var childNodes = myNode.childNodes;
for(var i=0; i<childNodes.length; i++){
if(childNodes[i].className === "mySlides"){
myNode.removeChild(childNodes[i])
}
}
}
*/
function showSlides(n) {
var i;
var slides = document.getElementsByClassName("mySlides");
var dots = document.getElementsByClassName("demo");
var captionText = document.getElementById("caption");
if (n > slides.length) {slideIndex = 1}
if (n < 1) {slideIndex = slides.length}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
for (i = 0; i < dots.length; i++) {
dots[i].className = dots[i].className.replace(" active", "");
}
slides[slideIndex-1].style.display = "block";
dots[slideIndex-1].className += " active";
//captionText.innerHTML = dots[slideIndex-1].alt;
}
function dotfunction() {
var slides = document.getElementsByClassName("mySlides");
var dotfunctionadder = document.getElementsByClassName("demo");
for (var i = 0; i < slides.length; i++) {
dotfunctionadder.onclick = currentSlide(i);
}
}
<body id="modal-2">
<h2 id="title" style="text-align:center">hellkkko</h2>
<div class="row">
<div class="column">
<img id="modal-1" src="https://www.yosemitehikes.com/images/wallpaper/yosemitehikes.com-bridalveil-winter-1200x800.jpg" style="max-width:100%" data-modal="1" onclick="fillSlides(this); openModal(); currentSlide(1); " class="hover-shadow cursor">
</div>
</div>
<div class="row">
<div class="column">
<img id="modal-2" src="https://www.yosemitehikes.com/images/wallpaper/yosemitehikes.com-bridalveil-winter-1200x800.jpg" style="max-width:100%" data-modal="2" onclick="fillSlides(this); openModal(); currentSlide(1); " class="hover-shadow cursor">
</div>
</div>
<div class="row">
<div class="column">
<img id="modal-3" src="https://www.yosemitehikes.com/images/wallpaper/yosemitehikes.com-bridalveil-winter-1200x800.jpg" style="max-width:100%" data-modal="3" onclick="fillSlides(this); openModal(); currentSlide(1); " class="hover-shadow cursor">
</div>
</div>
<div id="myModal" class="modal">
<span class="close cursor" onclick="clearSlides(); closeModal();">×</span>
<div class="modal-content" id="modal_content">
<a class="elbutton prev" onclick="plusSlides(-1)">❮</a>
<a class="elbutton next" onclick="plusSlides(1)">❯</a>
</div>
</div>
I tried calling dot function from the onclick of a different element (because the span I want to add it to is being created with JS) within the html but nothing happened. How do I do this and what am I doing wrong?

Try putting your script in the head section if you want to bind click handler inside html.
Below is the fiddle that i tested with your chanegs.
<head>
<script>
function openModal() {
document.getElementById('myModal').style.display = "block";
}
function closeModal() {
document.getElementById('myModal').style.display = "none";
}
..........
</script>
<head>
"https://jsfiddle.net/ajaygandhi06/smca56fv/"
It works when you put your js inside head tag.

Related

I can't get the actual number of elements

I'm having a problem returning elements from my object array.
I have a slideshow in which an image (photo of the book) and a text (title of the book) must appear.
For the creation of the slideshow I have no problems because I am using querySelectors as shown in the code below.
The problem lies in showing the images with their titles.
In the first part of the code I have an array of objects that gives me the total number of elements present and based on this I create the slideshow (to create the scroll points and the "container" to contain the images) and then subsequently I call the function myFunction with id argument to return the single element (identified by an id).
What I notice is that the urls with the ids are returned to me, but the url with that id is returned multiple times (so it gets copied) and not just once as expected; I should have only 4 url ​​in total (each with the specific id of the element, since only 4 elements). The same happens when I return the array of objects, it does not return 4 but many more.
Referring to url1:
If I click on the arrows of the slideshow I only receive one image, the other images I do not receive.
I have no mistakes.
var slideIndex = 1;
var outerXmlhttp = new XMLHttpRequest();
var url = "https://wjko8t4509.execute-api.us-east-2.amazonaws.com/books";
outerXmlhttp.onreadystatechange = function () {
var innerXmlhttp;
if (this.readyState == 4 && this.status == 200) {
var allbook = JSON.parse(this.responseText);
for (var i = 0, len = allbook.Items.length; i < len; i++) {
id = allbook.Items[i].id
showSlides(slideIndex);
myFunction(id);
}
}
};
outerXmlhttp.open("GET", url, true);
outerXmlhttp.send();
function plusSlides(n) {
showSlides(slideIndex += n);
}
function currentSlide(n) {
showSlides(slideIndex = n);
}
function showSlides(n) {
var i;
var slides = document.getElementsByClassName("mySlides fade");
var dots = document.getElementsByClassName("dot");
if (n > slides.length) { slideIndex = 1 }
if (n < 1) { slideIndex = slides.length }
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
for (i = 0; i < dots.length; i++) {
dots[i].className = dots[i].className.replace(" active", "");
}
slides[slideIndex - 1].style.display = "block";
dots[slideIndex - 1].className += " active";
}
function myFunction(id) {
var url1 = "https://wjko8t4509.execute-api.us-east-2.amazonaws.com/books/" + id;
innerXmlhttp = new XMLHttpRequest();
innerXmlhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
var myArr = JSON.parse(this.responseText);
document.getElementById("img").src = "book_img/" + myArr.Item.immagine;
document.getElementById("title").innerHTML = `${myArr.Item.titolo}`;
}
};
innerXmlhttp.open("GET", url1, true);
innerXmlhttp.send();
}
<div class="slideshow-container" id="slideshow">
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
</div>
<br>
<div id="punt" style="text-align:center">
</div>
EDIT
Array allbook with error:
Several things I noticed:
Doesn't define the id
As you state, the data structure from api will look like {"Item":{"marca":"Love","titolo":"You will be missed indefinitely","id":"123456","immagine":"ind.jpg","data":"27/11/2021"}}, but are trying to loop over all the item inside item which will be incorrect, you should loop over allbook.
It should be allbook[i].Items.length instead of allbook.Items.length
var slideIndex = 1;
let id;
var outerXmlhttp = new XMLHttpRequest();
var url = "https://wjko8t4509.execute-api.us-east-2.amazonaws.com/books";
outerXmlhttp.onreadystatechange = function() {
var innerXmlhttp;
if (this.readyState == 4 && this.status == 200) {
var allbook = JSON.parse(this.responseText);
for (var i = 0, len = allbook.length; i < len; i++) {
id = allbook[i].Items.id
document.querySelector('.slideshow-container').innerHTML += `
<div class="mySlides fade">
<div class="numbertext">${i+1}/${allbook[i].Items.length}</div>
<img id="img" src onerror="this.onerror=null; this.src=myFunction(${id});" style="width:100%">
<div class="text" id="title" onclick="myFunction(${id})"></div>
</div>`;
document.querySelector('#punt').innerHTML += `
<span class="dot" onclick=currentSlide(${i+1})></span>`;
myFunction(id);
}
showSlides(0);
}
};
outerXmlhttp.open("GET", url, true);
outerXmlhttp.send();
function plusSlides(n) {
showSlides(slideIndex += n);
}
function currentSlide(n) {
showSlides(slideIndex = n);
}
function showSlides(n) {
var i;
var slides = document.getElementsByClassName("mySlides fade");
var dots = document.getElementsByClassName("dot");
if (n > slides.length) {
slideIndex = 1
}
if (n < 1) {
slideIndex = slides.length
}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
for (i = 0; i < dots.length; i++) {
dots[i].className = dots[i].className.replace(" active", "");
}
slides[slideIndex - 1].style.display = "block";
dots[slideIndex - 1].className += " active";
}
function myFunction(id) {
var url1 = "https://wjko8t4509.execute-api.us-east-2.amazonaws.com/books/" + id;
innerXmlhttp = new XMLHttpRequest();
innerXmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var myArr = JSON.parse(this.responseText);
document.getElementById("img").src = "book_img/" + myArr.Item.immagine;
document.getElementById("title").innerHTML = `${myArr.Item.titolo}`;
}
};
innerXmlhttp.open("GET", url1, true);
innerXmlhttp.send();
}
<div class="slideshow-container" id="slideshow">
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
</div>
<br>
<div id="punt" style="text-align:center">
</div>

Add pause: "hover" to existing js

New here so forgive any blunders. I've searched stackoverflow but cannot find a way to add pause on hover to an existing script I got from W3Schools, can anyone tell me how? This is the code I'm using:
<script>
var myIndex = 0;
carousel();
function carousel() {
var i;
var x = document.getElementsByClassName("mySlides");
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
myIndex++;
if (myIndex > x.length) {myIndex = 1}
x[myIndex-1].style.display = "block";
setTimeout(carousel, 3000);
}
</script>
html
<!DOCTYPE html>
<html>
<head>
<title>flytipping</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta content="text/html; charset=iso-8859-2" http-equiv="Content-Type">
<link href="style.css" rel="stylesheet" type="text/css">
</head>
<body>
<h2 class="w3-center">Flytipping_5</h2>
<div class="w3-content w3-section" style="max-width:70%">
<img class="mySlides" src="1.JPG" style="width:100%" alt="">
<img class="mySlides" src="2.JPG" style="width:100%" alt="">
<img class="mySlides" src="3.JPG" style="width:100%" alt="">
</div>
<script>
var myIndex = 0;
carousel();
function carousel() {
var i;
var x = document.getElementsByClassName("mySlides");
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
myIndex++;
if (myIndex > x.length) {myIndex = 1}
x[myIndex-1].style.display = "block";
setTimeout(carousel, 3000);
}
</script>
</body>
</html>
Try this.
In your HTML file:
<div class="mySlides" onhover="myFunction" />
In your JS file:
function myFunction() {
... do something
}
You can create a variable in your script. Set it to true on element hover, and in your function check if that variable is true then don't move your image. But you must unset this variable on mouse out.
Something like this:
<div onmouseover="stopCarousel()" onmouseout="startCarousel()"></div>
var doCarousel = true;
function stopCarousel() {
doCarousel=false;
}
function startCarousel() {
doCarousel=true;
}
function carousel() {
if(!doCarousel) return;
var i;
var x = document.getElementsByClassName("mySlides");
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
myIndex++;
if (myIndex > x.length) {myIndex = 1}
x[myIndex-1].style.display = "block";
setTimeout(carousel, 3000);
}
Store the timeout-id in a variable and call window.clearTimeout(...) on it like
<script>
var myIndex = 0;
var timeout;
carousel();
function carousel() {
var i;
var x = document.getElementsByClassName("mySlides");
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
myIndex++;
if (myIndex > x.length) {
myIndex = 1
}
x[myIndex - 1].style.display = "block";
timeout = setTimeout(carousel, 3000);
}
function stopCarousel() {
window.clearTimeout(timeout);
}
</script>
Of course you need to call the stopCarousel-function on the event you like the carousel to stop.

Get pictures from folder with javascript to my website

I have a local website with .html file and I want my slideshow to automatically display pictures from a folder and display them without the need to add it manually one by one.
Right now I have to add for every new image I want.
Here is my code:
<img class="mySlides myImg" src="Images/Image_01.jpeg" alt="01" width="620" height="340">
<img class="mySlides myImg" src="Images/Image_02.jpeg" alt="02" width="620" height="340">
<!-- Slider Image Script -->
<script>
var slideIndex = 1;
showDivs(slideIndex);
function plusDivs(n) {
showDivs(slideIndex += n);
}
function currentDiv(n) {
showDivs(slideIndex = n);
}
function showDivs(n) {
var i;
var x = document.getElementsByClassName("mySlides");
var dots = document.getElementsByClassName("demo");
if (n > x.length) {slideIndex = 1}
if (n < 1) {slideIndex = x.length}
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
for (i = 0; i < dots.length; i++) {
dots[i].className = dots[i].className.replace(" w3-white", "");
}
x[slideIndex-1].style.display = "block";
dots[slideIndex-1].className += " w3-white";
}
</script>

Add Play/Pause Button To Image slider

I'm trying to add a play and pause button to my image viewer. I have next and prev buttons working fine but would love a play and pause button integrated into my JavaScript.
Can anyone please help out?
Here is a working demo via link Demo
Script:
<div class="w3-container">
</div>
<div class="w3-content" style="max-width:800px">
<img class="mySlides" src="http://www.chorleyweather.com/forecast-charts/ecmwfcharts/na500hpa_1.png" style="width:95%"></li>
<img class="mySlides" src="http://www.chorleyweather.com/forecast-charts/ecmwfcharts/na500hpa_2.png" style="width:95%"></li>
</div>
<div class="w3-section">
<button class="w3-btn" onclick="plusDivs(-1)"><h6> Prev Image<h6/></button>
<button class="w3-btn" onclick="plusDivs(1)"><h6>Next Image<h6/> </button><h6/>
</div>
</div>
<script>
var slideIndex = 1;
showDivs(slideIndex);
function plusDivs(n) {
showDivs(slideIndex += n);
}
function currentDiv(n) {
showDivs(slideIndex = n);
}
function showDivs(n) {
var i;
var x = document.getElementsByClassName("mySlides");
var dots = document.getElementsByClassName("demo");
if (n > x.length) {slideIndex = 1}
if (n < 1) {slideIndex = x.length}
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
for (i = 0; i < dots.length; i++) {
dots[i].className = dots[i].className.replace(" w3-red", "");
}
x[slideIndex-1].style.display = "block";
dots[slideIndex-1].className += " w3-red";
}
window.onload = function() {
var image = document.getElementById("img");
function updateImage() {
image.src = image.src.split("?")[0] + "?" + new Date().getTime();
}
setInterval(updateImage, 1000);
}
</script>
A way would be with a boolean which determines if it should be playing or not, and a button that changes the value of that boolean.
button:
<button id="playpause"></button>
updated window.onload = function
window.onload = function() {
var image = document.getElementById("img");
var playing = true;
function updateImage() {
if (playing) {
image.src = image.src.split("?")[0] + "?" + new Date().getTime();
}
}
var playpause = document.getElementById("playpause");
playpause.onclick = function() {
if (playing) {
playing = false;
} else {
playng = true;
}
};
setInterval(updateImage, 1000);
}
Didn't try this, but it should do the trick.

Javascript slideshow controls don't take any action

I've made a slideshow in native javascript but the next and previous buttons don't work. Also the pagination dots should follow the respective slide.
When pressing the next button, the next slide should display and so on. In devTools it shows the first slide has the style set to display and the first dot has the active class added but when pressing the next/prev buttons nothing happens.
Here is my code:
window.onload = function() {
document.getElementById("nextSlide").addEventListener("click",nextSlide());
document.getElementById("prevSlide").addEventListener("click",prevSlide());
};
var slideIndex = 0;
function nextSlide() {
var slideList = document.getElementsByClassName("imgSlide");
var dots = document.getElementsByClassName("dots");
slideIndex += 1;
if (slideIndex >= slideList.length) {
slideIndex = 0;
}
for(var i = 0; i < slideList.length; i++) {
slideList[i].style.display = "none";
}
for(var d = 0; d < dots.length; d++) {
dots[d].classList.remove("active");
}
slideList[slideIndex].style.display = "block";
dots[slideIndex].classList.add("active");
return false;
}
function prevSlide() {
var slideList = document.getElementsByClassName("imgSlide");
var dots = document.getElementsByClassName("dots");
slideIndex -= 1;
if (slideIndex < 0) (slideList.length - 1);
for(var i = 0; i < slideList.length; i++) {
slideList[i].style.display = "none";
}
for(var d = 0; d < dots.length; d++) {
dots[d].classList.remove("active");
}
slideList[slideIndex].style.display = "block";
dots[slideIndex].classList.add("active");
}
And my HTML
<div id="slides-container">
<ul class="slides">
<li class="imgSlide"><img
src="/BackOffice/viagens_header_images/blobid1508696899148.jpg"
alt="Alpine
Scenery" /></li>
<li class="imgSlide"><img
src="/BackOffice/viagens_header_images/blobid1509065118446.jpg"
alt="Kalte
Rinne" /></li>
<li class="imgSlide"><img
src="/BackOffice/viagens_header_images/blobid1508696913346.jpg"
alt="Adiltzgraben" /></li>
</ul>
<div class="controls"><button type="button" id="prevSlide" role="button">
</button>
<ul class="dot-navigation">
<li class="dots"></li>
<li class="dots"></li>
<li class="dots"></li>
</ul>
<button type="button" id="nextSlide" role="button"></button></div>
</div>
Listener parameter in addEventListener for a named function must be a function name without quotes and brackets:
document.getElementById("nextSlide").addEventListener("click", nextSlide);
document.getElementById("prevSlide").addEventListener("click", prevSlide);
And also another small bug. Instead of the line if (slideIndex < 0) (slideList.length - 1);
must be:
if (slideIndex < 0) {
slideIndex = slideList.length;
}
window.onload = function() {
document.getElementById("nextSlide").addEventListener("click", nextSlide);
document.getElementById("prevSlide").addEventListener("click", prevSlide);
};
var slideIndex = 0;
function nextSlide() {
var slideList = document.getElementsByClassName("imgSlide");
var dots = document.getElementsByClassName("dots");
slideIndex += 1;
if (slideIndex >= slideList.length) {
slideIndex = 0;
}
for (var i = 0; i < slideList.length; i++) {
slideList[i].style.display = "none";
}
for (var d = 0; d < dots.length; d++) {
dots[d].classList.remove("active");
}
slideList[slideIndex].style.display = "block";
dots[slideIndex].classList.add("active");
return false;
}
function prevSlide() {
var slideList = document.getElementsByClassName("imgSlide");
var dots = document.getElementsByClassName("dots");
slideIndex -= 1;
if (slideIndex < 0) {
slideIndex = slideList.length - 1;
}
for (var i = 0; i < slideList.length; i++) {
slideList[i].style.display = "none";
}
for (var d = 0; d < dots.length; d++) {
dots[d].classList.remove("active");
}
slideList[slideIndex].style.display = "block";
dots[slideIndex].classList.add("active");
}
.imgSlide:not(:first-child) {
display: none;
}
.slides {
list-style-type: none;
}
<div id="slides-container">
<ul class="slides">
<li class="imgSlide"><img src="http://via.placeholder.com/350x150" alt="350x150"></li>
<li class="imgSlide"><img src="http://via.placeholder.com/300x200" alt="300x200"></li>
<li class="imgSlide"><img src="http://via.placeholder.com/400x300" alt="400x300"></li>
</ul>
<div class="controls">
<button type="button" id="prevSlide" role="button">Back</button>
<ul class="dot-navigation">
<li class="dots"></li>
<li class="dots"></li>
<li class="dots"></li>
</ul>
<button type="button" id="nextSlide" role="button">Next</button></div>
</div>

Categories