My goal is to coding a slider in Javascript, with a Class inside. But I meet 2 issues :
the Autoplay does not work
if I click on the Pause Button, and then click again on the play button, the autoplay does not work either
The HTML page is located there :
http://p4547.phpnet.org/bikes/slider.html
Here is my Javascript code :
class Diaporama {
constructor() {
this.controls = document.querySelectorAll('.controls');
this.slides = document.querySelectorAll('#diaporama .slide');
this.currentSlide = 0;
this.n = null;
this.playing = true;
this.pauseButton = document.getElementById('pause');
this.next = document.getElementById('next');
this.previous = document.getElementById('previous');
}
// Afficher les boutons previous, play, pause, next :
controlling() {
for(let i=0; i < this.controls.length; i++){
this.controls[i].style.display = 'inline-block';
}
}
// Slider Automatique :
goToSlide(n) {
this.slides[this.currentSlide].className = 'slide';
this.currentSlide = (n + this.slides.length)%this.slides.length;
this.slides[this.currentSlide].className = 'slide showing';
console.log(this.currentSlide);
}
nextSlide() {
this.goToSlide(this.currentSlide + 1);
}
previousSlide() {
this.goToSlide(this.currentSlide - 1);
}
slideInterval() {
setInterval(this.nextSlide,5000);
}
pauseSlideshow() {
this.pauseButton.innerHTML = '<i class="fas fa-play"></i>';
this.playing = false;
clearInterval(this.slideInterval);
}
playSlideshow() {
this.pauseButton.innerHTML = '<i class="fas fa-pause"></i>';
this.playing = true;
this.slideInterval = setInterval(this.nextSlide,5000);
}
nextItem() {
next.onclick = () => {
this.pauseSlideshow();
this.nextSlide();
}
}
previousItem() {
previous.onclick = () => {
this.pauseSlideshow();
this.previousSlide();
}
}
// Changement de slide par les touches du clavier :
clickKeyboard() {
document.addEventListener("keydown", ({keyCode}) => {
if(keyCode === 37){
this.nextSlide();
}
else if(keyCode === 39){
this.previousSlide();
}
})
}
};
let slider = new Diaporama();
slider.controlling();
slider.goToSlide(0);
slider.nextSlide();
slider.previousSlide();
slider.pauseSlideshow();
slider.playSlideshow();
slider.nextItem();
slider.previousItem();
slider.clickKeyboard();
This issue is inside playslideShow. When it calls this.nextSlide inside setInterval, the scope of this has changed. this refers to the window.
You can use bind() in this case, to make sure it refers to the slider object:
playSlideshow() {
this.pauseButton.innerHTML = '<i class="fas fa-pause"></i>';
this.playing = true;
this.slideInterval = setInterval(this.nextSlide.bind(this),5000);
}
Oh no, sorry, I found out why my Pause button was bugging.
I just added a new function :
restart() {
this.pauseButton.onclick = () => {
if(this.playing){ this.pauseSlideshow(); }
else{ this.playSlideshow(); }
}
}
It works fine now !
Related
I want to make circle(army) with move when I drag it and when I click it, it should not move but do something else.
fucntion unit() {
this.circle = document.createElementNS(svgNs, "circle");
//Some attributes are added to this.circle
document.getElementById("svg1").appendChild(this.circle);
this.moving = false;
this.circle.onclick = function () {
showForm(this);
}
this.circle.onmousedown = function () {
this.moving = true;
}
}
Alright, I know that you didn't tag jQuery in your code, but if you have looked at my other posts, I tend to go full jQuery. If you wanted to do this, do this:
let's say this applies to your circle id element:
$("#circle").draggable( 'enable' )
var isDragging = 0;
var isUp = 1;
$("#circle").mousedown(function() {
isDragging = 0;
isUp = 0;
})
$("#circle").mousemove(function() {
isDragging = 1;
});
$("#circle").mouseup(function() {
isDragging = 0;
isUp = 1;
});
$("#circle").mousedown(function() {
if (isUp == 1) {
//click function
} else if (isDragging == 1) {
//drag function
}
});
This might be a little buggy, but I tried.
I have made this vanilla js image slider with three images. In the html i have three indicator dots at the bottom of the slider and a css active class for the active indicator. Can't figure out how to get the class to add to the current slide of the slide show, any help?
let sliderImages = document.querySelectorAll('.slides'),
prevArrow = document.querySelector('#prevBtn'),
nextArrow = document.querySelector('#nextBtn'),
dots = document.querySelectorAll('.indicator__dot'),
current = 0;
reset = () => {
for(let i = 0; i <sliderImages.length; i++) {
sliderImages[i].style.display = 'none';
}
}
startSlide = () => {
reset();
sliderImages[0].style.display = 'block'
}
prevSlide = () => {
reset();
sliderImages[current - 1].style.display = 'block';
current -- ;
}
nextSlide = () => {
reset();
sliderImages[current + 1].style.display = 'block';
current++;
}
prevArrow.addEventListener('click', () => {
if(current === 0 ) {
current = sliderImages.length;
}
prevSlide();
});
nextArrow.addEventListener('click', () => {
if(current === sliderImages.length - 1 ) {
current = -1
}
nextSlide();
});
startSlide()
No sorry I should have been more clear and included some html. I have 3 dots at the bottom of the slider. When slide one is the current image the first dot will have the css class added to it, when the second image is showing the second do will have the active class and the first dot wont any more. Hope that makes more sense?
<div class="indicator">
<span class="indicator__dot"> </span>
<span class="indicator__dot"> </span>
<span class="indicator__dot"> </span>
</div>
Haven't tested this so may have some bugs. setAnchor() function resets all the dots and add active class to the current dot.
setAnchor = () => {
for(let i = 0; i <dots.length; i++) {
sliderImages[i].classList.remove("active");
if(current === i){
sliderImages[i].classList.add("active");
}
}
}
startSlide = () => {
reset();
sliderImages[current].style.display = 'block'
setAnchor();
}
prevSlide = () => {
reset();
current -- ;
sliderImages[current].style.display = 'block';
setAnchor();
}
nextSlide = () => {
reset();
current++;
sliderImages[current].style.display = 'block';
setAnchor();
}
I have a function that checking board is there a searching element.
First script creating a board with different elements. Element in the square next to board is element that user has to find on the board and click them.
User has to click (as quick as possible) all searching elements. After click on element function checking a board, is there more elements. If yes then nothing happen and user has to click another one. If on board there isn’t searching elements then function display a time and new board create.
But some reason function works correct only first time after page load. Latter function ignore more then one element on board or see element that doesn’t exist on board any more.
Can you tell me what is wrong.
Part of code bellow and there is a link to testing page.
http://doomini2.linuxpl.info/font/
Thank you
function secondStage() {
createBoxes(59);
var usingSet = [];
var i = 0;
var boxList = document.querySelectorAll("#board > div");
createSet(usingSet, 20, shapes);
(function paint() {
if (i <= 59) {
var curentBox = boxList[i];
curentBox.className = usingSet[draw(20)];
curentBox.style.color = colors[draw(colors.length - 5)];
timeStop = setTimeout(paint, 50);
i++;
} else {
var findShape = boxList[draw(59)];
toFind.className = findShape.className;
toFind.style.color = findShape.style.color;
findBoxes(boxList);
clearTimeout(timeStop);
}
})();
}
//function checks boxes to find a proper shape
function findBoxes(boxList) {
startTime = Date.now();
board.addEventListener("mousedown", function (e) {
if ((e.target.className === toFind.className)) {
e.target.className = "correct";
e.target.innerHTML = "OK";
checkBoard();
} else if (e.target.id === "board" || e.target.className === "correct") {
} else {
e.target.className = "false";
e.target.innerHTML = "NO";
}
}, false);
function checkBoard() {
var condition = false;
console.log(condition);
for (var x = 0; x < boxList.length; x++) {
if ((boxList[x].className === toFind.className)) {
condition = true;
console.log(condition);
}
}
if (condition === false) {
var clickTime = Date.now();
var timeResult = parseFloat(((clickTime - startTime) / 1000).toFixed(3));
lastResult.innerHTML = timeResult + "s";
secondResult[secondResult.length] = timeResult;
console.log(secondResult);
displayResult(secondStage);
}
}
}
//function displaig results after every single round
function displayResult(stage) {
cover.className = "";
TweenMax.to("#lastResultDiv", 1, {ease: Back.easeOut, right: (winWidth / 4), });
TweenMax.to("#go", 1, {ease: Back.easeOut, top: (winWidth / 3), onComplete: function () {
goButton.addEventListener("click", function () {
clear();
}, false);
}});
//clear board and return to play
function clear() {
TweenMax.to("#lastResultDiv", 1, {ease: Back.easeIn, right: winWidth, });
TweenMax.to("#go", 1, {ease: Back.easeOut, top: -100, onComplete: function () {
cover.className = "hide";
lastResultDiv.style.right = "-592px";
toFind.className = "";
board.innerHTML = "";
if (firstStageRound === 10) {
secondStage();
} else if (secondStageRound === 5) {
thirdStage();
} else {
stage();
}
}});
}
}
Not Load this File http://cdnjs.cloudflare.com/ajax/libs/gsap/1.17.0/TweenMax.min.js
try to local path
i would like to ask for help in a simple task i really need to do at my work (I am a javascript newbie). I made a simple collapsible list with script provided by this guy http://code.stephenmorley.org/javascript/collapsible-lists/ but what i need right now are two simple buttons as stated in the title: expand all and collapse whole list. Do you guys know if something like that can be implemented in this certain script? Please help :)
var CollapsibleLists = new function () {
this.apply = function (_1) {
var _2 = document.getElementsByTagName("ul");
for (var _3 = 0; _3 < _2.length; _3++) {
if (_2[_3].className.match(/(^| )collapsibleList( |$)/)) {
this.applyTo(_2[_3], true);
if (!_1) {
var _4 = _2[_3].getElementsByTagName("ul");
for (var _5 = 0; _5 < _4.length; _5++) {
_4[_5].className += " collapsibleList";
}
}
}
}
};
this.applyTo = function (_6, _7) {
var _8 = _6.getElementsByTagName("li");
for (var _9 = 0; _9 < _8.length; _9++) {
if (!_7 || _6 == _8[_9].parentNode) {
if (_8[_9].addEventListener) {
_8[_9].addEventListener("mousedown", function (e) {
e.preventDefault();
}, false);
} else {
_8[_9].attachEvent("onselectstart", function () {
event.returnValue = false;
});
}
if (_8[_9].addEventListener) {
_8[_9].addEventListener("click", _a(_8[_9]), false);
} else {
_8[_9].attachEvent("onclick", _a(_8[_9]));
}
_b(_8[_9]);
}
}
};
function _a(_c) {
return function (e) {
if (!e) {
e = window.event;
}
var _d = (e.target ? e.target : e.srcElement);
while (_d.nodeName != "LI") {
_d = _d.parentNode;
}
if (_d == _c) {
_b(_c);
}
};
};
function _b(_e) {
var _f = _e.className.match(/(^| )collapsibleListClosed( |$)/);
var uls = _e.getElementsByTagName("ul");
for (var _10 = 0; _10 < uls.length; _10++) {
var li = uls[_10];
while (li.nodeName != "LI") {
li = li.parentNode;
}
if (li == _e) {
uls[_10].style.display = (_f ? "block" : "none");
}
}
_e.className = _e.className.replace(/(^| )collapsibleList(Open|Closed)( |$)/, "");
if (uls.length > 0) {
_e.className += " collapsibleList" + (_f ? "Open" : "Closed");
}
};
}();
It is important to understand why a post-order traversal is used. If you were to just iterate through from the first collapsible list li, it's 'children' may (will) change when expanded/collapsed, causing them to be undefined when you go to click() them.
In your .html
<head>
...
<script>
function listExpansion() {
var element = document.getElementById('listHeader');
if (element.innerText == 'Expand All') {
element.innerHTML = 'Collapse All';
CollapsibleLists.collapse(false);
} else {
element.innerHTML = 'Expand All';
CollapsibleLists.collapse(true);
}
}
</script>
...
</head>
<body>
<div class="header" id="listHeader" onClick="listExpansion()">Expand All</div>
<div class="content">
<ul class="collapsibleList" id="hubList"></ul>
</div>
</body>
In your collapsibleLists.js
var CollapsibleLists =
new function(){
...
// Post-order traversal of the collapsible list(s)
// if collapse is true, then all list items implode, else they explode.
this.collapse = function(collapse){
// find all elements with class collapsibleList(Open|Closed) and click them
var elements = document.getElementsByClassName('collapsibleList' + (collapse ? 'Open' : 'Closed'));
for (var i = elements.length; i--;) {
elements[i].click();
}
};
...
}();
I am using this method to play audio files when you click on an image:
http://jsfiddle.net/v97Kq/3/
function imageSwitch(_imgID, _imgStart, _imgStop, _soundFileMp3, _soundFileOgg) {
this.imgID = _imgID;
this.imgStart = _imgStart;
this.imgStop = _imgStop;
this.song = new Audio();
if (this.song.canPlayType("audio/mpeg"))
this.song.src = _soundFileMp3;
else
this.song.src = _soundFileOgg;
this.song.loop = true;
this.pos = 0;
this.e;
this.change = function () {
if (this.pos == 0) {
this.pos = 1;
document.getElementById(this.imgID).src = this.imgStop;
this.song.play();
} else {
this.pos = 0;
document.getElementById(this.imgID).src = this.imgStart;
this.song.pause();
}
}
}
It works good! - but how can I get it to stop playing the currently playing sound when another link is clicked and another sound begins?
I found this solution to my issue above, works perfectly.
which I eventually found here:
<script>
var currentPlayer;
function EvalSound(soundobj) {
var thissound=document.getElementById(soundobj);
if(currentPlayer && currentPlayer != thissound) {
currentPlayer.pause();
}
if (thissound.paused)
thissound.play();
else
thissound.pause();
thissound.currentTime = 0;
currentPlayer = thissound;
}
</script>