Automatic Slideshow not stop when i use javascript event - javascript

I wrote a script to make an automatic slideshow, and i want it to stop when i onlick (or onmouseover) the image (or the content) but it not work for me. Someone please show me if there're any error in my code. Thank you!
This is my code:
var slideIndex =1;
showslides(slideIndex);
function plusslide(n){
showslides(slideIndex+=n);
};
function showslides(n){
var i;
var slides = document.getElementsByClassName("fade");
if (n>slides.length){ slideIndex=1};
if(n<1){slideIndex=slides.length};
for (i=0; i<slides.length; i++){
slides[i].style.display = "none";
}
slides[slideIndex-1].style.display = "block";
};
var interval=setInterval(function(){slideIndex+=1; showslides(slideIndex);},1000);
document.getElementsByClassName("fade").onclick=function(){stop()};
function stop(){
clearInterval(interval);
};
<body>
<div class="page">
<div class="container">
<div class="content">
<div class="fade">
<img src="#" />
<p>1/3</p>
</div>
<div class="fade">
<img src="#" />
<p>2/3</p>
</div>
<div class="fade">
<img src="#" />
<p>3/3</p>
</div>
<a class="prev" onclick="plusslide(-1)">❮</a>
<a class="next" onclick="plusslide(1)">❯</a>
</div>
</div>
</div>
<script type="text/javascript" src="slide.js"></script>
</body>

There's a small typo in your code. Replace getElementsbyClassName with getElementsByClassName.
You can catch errors like this in the future by using your browser's developer console, where it will tell you where's an error in your code and what type. Just search for Developer Tools, it will help you find and fix errors like this yourself.
Edit:
Oh yes, didn't see that one. There is indeed also an error in this line:
document.getElementsByClassName("fade").onclick=function(){stop()};
Here's the issue. getElementsByClassName does not return a DOM element, but rather an array of elements, since there are multiple elements with that class name. You'll have to loop through each one in order to access onclick on them, just like you did in your function above, like this:
var slides = document.getElementsByClassName("fade");
for (var i = 0; i < slides.length; i++) {
slides[i].onclick = stop;
}
Also, small sidenote: I shortened function(){stop()} to just stop in my answer. Since you only call that function without any arguments in onclick, you can just directly bind stop to onclick.

Related

addEventListener to multiple elements, using Event Delegation (JavaScript)

I'm trying to add an event to multiple elements. For now, I have this code and it works. But, I want to use Event Delegation and move the listener to the parent element (deck). I've tried so many solutions found here on Stack, but none of them it's working.
Question, which will be the best way to delegate the event?
HTML
<section class="deck">
<div class="card">
<div class="front"></div>
<div class="back">
<img src="#" alt="">
</div>
</div>
<div class="card">
<div class="front"></div>
<div class="back">
<img src="#" alt="">
</div>
</div>
...
JavaScript
var card = document.querySelectorAll(".card");
var len = card.length;
for (let i = 0; i <= len; i++) {
card[i].onclick = function () {
this.classList.add("foo");
}
}
Simple event delegation could look like this in your case:
var deck = document.querySelector(".deck");
deck.addEventListener('click', function (e) {
var target = e.target
if (target.classList.contains('card')) {
target.classList.add('foo')
}
})
Note, this check target.classList.contains('card') is necessary so that you add class foo only to elements with class .card.
var deck = document.querySelector('.deck');
deck.onclick = function(clickevent)
{
if (clicked.target.closest('.card'))
clickevent.target.closest('.card').classList.add('foo');
}
The element that is clicked (the target of the click event) might be the img for example. You want to add foo to the card element that is an ancestor of the target. The closest() method finds that element.

Hide only on certain elements

I'm using a script that checks for any tag that also has a SRC="self". My function should function like this:
Check if img src="self"
If true, hide the parent div
If false, do nothing
Currently the function actually hides every img regardless of src. If I replace the jQuery hide() action then the function works perfectly. It just seems like it isn't quite performing the hide function like I anticipated.
function changeSourceAll() {
var images = document.getElementsByTagName('img');
for (var i = 0; i < images.length; i++) {
if (images[i].src.indexOf('self') !== -1) {
$(".redditThumbnail").hide();
}
else (){}
}
}
changeSourceAll();
Sample HTML is below. I have multiple .listrow div elements identical to this and the function removes all the .redditThumbnail divs.
<div class="listrow news">
<div class="newscontainer">
<div class="redditThumbnail"></div>
<div class="articleheader news">
<div class="actionmenu">
<p class="mediumtext floatleft alignleft">
author
</p>
<div id="redditUsername"></div>
<div class="floatright">
<div class="redditPermalink material-icons"></div>
</div>
</div>
<p class="redditTitle mediatitle news"></p>
</div>
</div>
</div>
Thanks!
You could use an attribute-equals selector to find all of the <img> elements that point to "self" and then hide their parents :
// Hide the closest thumbnail for elements that match this constraint
$('img[src="self"]').closest('.redditThumbnail');
Example
$(function() {
$('button').click(function(){
$('img[src="self"]').closest('.redditThumbnail').hide();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='redditThumbnail'>
A (has self)
<img src='self' />
</div>
<div class='redditThumbnail'>
B (doesn't have self)
<img src='self-test' />
</div>
<div class='redditThumbnail'>
C (has self)
<img src='self' />
</div>
<hr />
<button>Hide Self-Referencing Images</button>
The issue with hiding every img is because you select and hide all .redditThumbnail elements for every matching item. To fix this you could use this:
$(images[i]).closest('.redditThumbnail').hide();
However a better approach entirely would be to use filter() and find only the .redditThumbnail elements which match the requirements. Try this:
$('.redditThumbnail').filter(function() {
return $(this).find('img[src="self"]').length != 0;
}).hide();
You are hiding all: $(".redditThumbnail").hide();. I guess you should do something like $(images[i]).hide();

Is there any way to pass an argument to addEventListener?

I'm trying to hide all elements in a class (logos) except the element that is clicked on. So I wrote this out only to realize that it's impossible to pass arguments to functions activated by addEventListener! This seems... inflexible to say the least. Is there another obvious way to pass an argument that I'm blind to (I'm pretty new to Javascript)?
<!DOCTYPE html>
<head>
<link rel="stylesheet" type="text/css" href="index.css">
<title>Sexism in Silicon Valley</title>
</head>
<body id="body1">
<div class="parent">
<img src="kstartup.png" class="logos" id="id1">
<img src="uber.png" class="logos" id="id2">
<img src="kpcb.png" class="logos" id="id3">
<img id="id4" src="r1startup.png" class="logos">
</div>
<div class="parent" id="parent2">
<img src="zillow.png" class="logos" id="id5">
<img src="github.png" class="logos" id="id6">
<img src="tinde.png" class="logos" id="id7">
<img src="snapchat.png" class="logos" id="id8">
</div>
<script src="index.js"></script>
</body>
</html>
Javascript:
function click(x) {
for (var i = 0; i < logos.length; i++) {
if (x !== i) {
logos[i].style.display = "hidden";
}
}
}
var logos = document.getElementsByClassName("logos");
for (var i = 0; i < logos.length; i++) {
logos[i].addEventListener('click', click(i));
}
The literal answer to your question:
logos[i].addEventListener('click', (function(i) { return function() { click(i); } })(i));
will do what you want. You need a function to wrap click(i), since you don't want to execute click(i) immediately; and you need another function to close over i, or you will get seemingly weird results (i.e. getting click(logos.length) always).
What you want to do instead is not use the iterator at all. Attach a listener to #logos itself; in the handler (which will get an event parameter), iterate over its children and compare to event.target.

Javascript: Change background of all images inside div

I would like to change the background of all images inside a div with a JS function:
My div:
<div>
<div id="avatar_container">
<img src="a.png" onclick="myfunction()" />
<img src="b.png" onclick="myfunction()" />
</div>
</div>
My function:
function myfunction(){
//I tried this two methods
document.getElementById("avatar_container").getElementsByTagName('img').css({'background' : 'green'});
document.getElementById("avatar_container").getElementsByTagName('img').style.backgroundColor = "green";
}
that's solve your problem
<div id="avatar_container">
<img src="a.png" class="myClass1" />
<img src="b.png" class="myClass1" />
</div>
Js: (important Notice: use js code after html codes)
var elems = document.getElementsByClassName('myClass1'), i;
for (i in elems) {
elems[i].style.backgroundColor = "green";
}
}
but i suggestion you to use and learn Jquery ,
jquery is a Javascript Framework witch make everything's very easy for you with less coding
with Jquery You can do it simplest like this
$('#avatar_container .myClass1').css('backgroundcolor','green');
and if you wanna attach click event
$('#avatar_container .myClass1').click(function() {
$(this).css('backgroundcolor','green');
});

change innerhtml javascript

I'm new to javascript and can't figure out the best way to solve this problem.
I have a div called info.
I have dozens of videos, and am constantly adding new videos.
When I click a video, I want to update info.
So I was thinking I need a hidden div with the text, and getElementsByClassName for something like this:
<div class="video"><a href="./video1.mp4" target="videoplayer" onclick="showDescription()><div class="description"><p>description for video1</div>
<div class="video"><a href=./video2.mp4 target="videoplayer" onclick="showDescription()><div class="description"><p>description for video2</div>
<div class="video"><a href=./video3.mp4 target="videoplayer" onclick="showDescription()><div class="description"><p>description for video3</div>
and
function showDescription(){
var description = this.getElementsByClassName("description");
document.getElementById("info").innerHTML = description;
{
That doesn't work. Is using getElementsByClassName a good way to do this, or can anyone suggest another way?
Here's the actual html I'm using:
<div id="videoplayer">
<iframe name="VideoPlayer" width="80%" height="100%" src="http://www.youtube.com/embed/videoseries?list=PL5A2FB27789F71E63> </iframe>
</div>
<div id="info">
<p>Welcome</p>
</div>
<div class="thumb"><p>
<img src="http://discolemonade.com/roku/images/thumbs/MusicVideos/MV-ThumbSmallPlaylist.jpg">
Hours of music videos, refreshed often.
</p>
<div class="longinfodiv">
<p class="longinfo">this is the long version of the music video playlist info</p>
</div>
</div>
And the javascript:
function changeInfo() {
var longinfo = document.getElementsByClassName("longinfo");
document.getElementById("info").innerHTML = longinfo;
}
First structure your HTML file properly:
<div class="video">
Link
<div class="description">description for video1</div>
</div>
Then use the following script:
function showDescription(){
var video = this.parentNode;
var desc = video.children[1];
document.getElementById("info").innerHTML = desc.innerHTML;
}

Categories