good day everyone... badly needed help
how can I trigger the next prev function if I press the left and right arrow keys. this is for the slider/lightbox that I was assign into.
this is the code
$(document).ready(function() {
var currentIndex = 0,
navItems = $(".navindex");
function setSlide(index) {...}
$(".navindex").click(function() {
var index = $(".navindex").index($(this));
currentIndex = index;
setSlide(currentIndex);
});
function next() {
if (currentIndex < navItems.length - 1) {
currentIndex++;
setSlide(currentIndex);
}
}
$(".next").click(function() {
next();
});
function prev() {
if (currentIndex > 0) {
currentIndex--;
setSlide(currentIndex);
}
}
$(".prev").click(function() {
prev();
});
function slide() {
if (currentIndex < navItems.length - 1) {
currentIndex++;
setSlide(currentIndex);
} else {
currentIndex = 0;
setSlide(currentIndex);
}
}
});
You want to handle key events. Something along the lines of:
$(document).keyup((evt) => {
if (evt.key === 'ArrowLeft')
return prev();
if (evt.key === 'ArrowRight')
return next();
});
Related
need some help. When I click the yellow tape on the page it disappears (granting access up the stairs. However I'm struggling to program it so that when all three are clicked, it progresses to the next page. Any help appreciated.
var counter = 0;
function del1()
if (counter == 0) {
{
document.getElementById("img3").style.display = 'none';
counter++;
}
}
function del2()
if (counter == 1) {
{
document.getElementById("img4").style.display = 'none';
counter++;
}
}
function del3()
if (counter == 2) {
{
document.getElementById("img5").style.display = 'none';
counter++;
}
}
function win()
if (counter === 3) {
clearInterval(timer);
sessionStorage.setItem('timerem', rem);
window.open('page2.html', "_self");
}
You are better off using delegation
Wrap the tape images in a div with id = stairs and give each of them a class of tape
Let me know if you must cut them in order
const tapes = 3;
document.getElementById("stairs").addEventListener("click", function(e) {
const tgt = e.target; // whatever clicked in the div
if (tgt.className.contains("tape")) { // we clicked a tape
tgt.className.add("hide"); // hide it
const allSnipped = tgt.closest("div").querySelectorAll(".tape.hide").length === tapes; // count .hide's
if (allSnipped) {
clearInterval(timer);
sessionStorage.setItem('timerem', rem);
location = 'page2.html';
}
}
})
.hide {
display: none;
}
Your code fixed
var counter = 0;
function del1() {
if (counter == 0) {
document.getElementById("img3").style.display = 'none';
counter++;
}
}
function del2() {
if (counter == 1) {
document.getElementById("img4").style.display = 'none';
counter++;
}
}
function del3() {
if (counter == 2) {
document.getElementById("img5").style.display = 'none';
win();
}
}
function win() {
clearInterval(timer);
sessionStorage.setItem('timerem', rem);
location = 'page2.html';
}
The following is my handleSubmit function which is fired when the form full of questions is submitted. The trouble is, even if all 21 questions are answered, filledAll does not change to true. But when I click submit for the second time, filledAll is set to true.
handleSubmit(event){
event.preventDefault();
let sum = 0;
this.state.score.forEach(function(value, index){
if (value !== undefined) {
sum += Number(value);
}
});
console.log(sum);
if (this.state.score.length === 0) {
this.setState({filledAll: false});
console.log('Scroll to question 1')
this.doScrolling("#question-1", 1000)
} else {
for (let i = 1; i <= 21; i++) {
console.log('Score of all 21 questions', this.state.score[i]);
// wherever the score is undefined
if (this.state.score[i] === undefined) {
console.log('if score is undefined, set filledAll to false.')
this.setState({filledAll: false});
console.log('Scroll to #question-' + i)
this.doScrolling("#question-" + i, 1000)
break;
}
else {
this.setState({filledAll: true});
console.log('else block', this.state.filledAll);
localStorage.setItem('total', sum)
// window.location.replace("/index");
}
}
}
}
I am using filledAll so I could know when all the questions are answered and to redirect to another page when it is true.
I wouldn't use state for filledAll as it shouldn't re-render the component.
I would suggest something like -
handleSubmit(event){
event.preventDefault();
let sum = 0;
let filledAll = true;
this.state.score.forEach(function(value, index){
if (value !== undefined) {
sum += Number(value);
}
});
console.log(sum);
if (this.state.score.length === 0) {
console.log('Scroll to question 1')
this.doScrolling("#question-1", 1000)
} else {
for (let i = 1; i <= 21 && filledAll; i++) {
console.log('Score of all 21 questions', this.state.score[i]);
// wherever the score is undefined
if (this.state.score[i] === undefined) {
console.log('if score is undefined, set filledAll to false.')
filledAll = false;
console.log('Scroll to #question-' + i)
this.doScrolling("#question-" + i, 1000)
break;
}
}
}
if (filledAll) {
console.log('filled all');
localStorage.setItem('total', sum)
window.location.replace("/index");
}
}
this.setState is an asynchronous function. So updation of state will only happens eventually. In your case the code below the this.setState will run immediately after this.setState is invoked. By moving your code below this.setState to the call back of this.setState will do the work.
handleSubmit(event){
event.preventDefault();
let sum = 0;
this.state.score.forEach(function(value, index){
if (value !== undefined) {
sum += Number(value);
}
});
console.log(sum);
if (this.state.score.length === 0) {
this.setState({filledAll: false}, () => {
console.log('Scroll to question 1')
this.doScrolling("#question-1", 1000)
});
} else {
for (let i = 1; i <= 21; i++) {
console.log('Score of all 21 questions', this.state.score[i]);
// wherever the score is undefined
if (this.state.score[i] === undefined) {
console.log('if score is undefined, set filledAll to false.')
this.setState({filledAll: false}, () => {
console.log('Scroll to #question-' + i)
this.doScrolling("#question-" + i, 1000)
});
break;
}
else {
this.setState({filledAll: true}, () => {
console.log('else block', this.state.filledAll);
localStorage.setItem('total', sum)
// window.location.replace("/index");
});
}
}
}
}
I want to add automatic scrolling time to my slider code but unable to do it can you please suggest me something to help me out with the code to make this slider slide automatic with a set interval of time.
'use strict';
$(document).ready(function () {
var $slides = $('.con__slide').length,
topAnimSpd = 650,
textAnimSpd = 1000,
nextSlideSpd = topAnimSpd + textAnimSpd,
animating = true,
animTime = 4000,
curSlide = 1,
nextSlide,
scrolledUp;
setTimeout(function () {
animating = false;
}, 2300);
//navigation up function
function navigateUp() {
if (curSlide > 1) {
scrolledUp = true;
pagination(curSlide);
curSlide--;
}
}
//navigation down function
function navigateDown() {
if (curSlide < $slides) {
scrolledUp = false;
pagination(curSlide);
curSlide++;
console.log(curSlide);
}
}
$(window).on('load', function () {
$('.con__slide--1').addClass('active');
});
//pagination function
function pagination(slide, target) {
animating = true;
// Check if pagination was triggered by scroll/keys/arrows or direct click. If scroll/keys/arrows then check if scrolling was up or down.
if (target === undefined) {
nextSlide = scrolledUp ? slide - 1 : slide + 1;
} else {
nextSlide = target;
}
////////// Slides //////////
$('.con__slide--' + slide).removeClass('active');
setTimeout(function () {
$('.con__slide--' + nextSlide).addClass('active');
}, nextSlideSpd);
////////// Nav //////////
$('.con__nav-item--' + slide).removeClass('nav-active');
$('.con__nav-item--' + nextSlide).addClass('nav-active');
setTimeout(function () {
animating = false;
}, animTime);
}
// Mouse wheel trigger
$(document).on('mousewheel DOMMouseScroll', function (e) {
var delta = e.originalEvent.wheelDelta;
if (animating) return;
// Mouse Up
if (delta > 0 || e.originalEvent.detail < 0) {
navigateUp();
} else {
navigateDown();
}
});
// Direct trigger
$(document).on("click", ".con__nav-item:not(.nav-active)", function () {
// Essential to convert target to a number with +, so curSlide would be a number
var target = +$(this).attr('data-target');
if (animating) return;
pagination(curSlide, target);
curSlide = target;
});
// Arrow trigger
$(document).on('click', '.con__nav-scroll', function () {
var target = $(this).attr('data-target');
if (animating) return;
if (target === 'up') {
navigateUp();
} else {
navigateDown();
}
});
// Key trigger
$(document).on("keydown", function (e) {
if (animating) return;
if (e.which === 38) {
navigateUp();
} else if (e.which === 40) {
navigateDown();
}
});
var topLink = $(".con__slide--4-top-h-link"),
botLink = $(".con__slide--4-bot-h-link");
$(".con__slide--4-top-h-link, .con__slide--4-bot-h-link").on({
mouseenter: function mouseenter() {
topLink.css('text-decoration', 'underline');
botLink.css('text-decoration', 'underline');
},
mouseleave: function mouseleave() {
topLink.css('text-decoration', 'none');
botLink.css('text-decoration', 'none');
}
});
});
Hope you understand the above code if you have any query in it feel free to ask me and please help me out as soon as possible.
Added setInterval in your code.
setInterval(() => {
if (curSlide >= $slides){
if (animating) return;
pagination(4, 1);
curSlide = 1;
}
else
navigateDown();
}, 10000);
Check updated fiddle.
update below navigateDown code.
//navigation down function
function navigateDown() {
if (curSlide < $slides) {
scrolledUp = false;
pagination(curSlide);
curSlide++;
console.log(curSlide);
}else{
curSlide=1;
pagination(4,1)
}
}
Add this below line
setInterval(navigateDown,7000);
I have a cycle of links and I determined click event on them. And I want to define if navbar[1].clicked == true {doing something} else if navbar[2].cliked == true {doing something} etc. "By if else in " reveal functional callbackFn".
Here is the code:
var navbar = document.getElementById("navbar").getElementsByTagName("a");
for (var i = 0; i < navbar.length; i++) {
navbar[i].addEventListener('click', function() { reveal('top'); });
}
function reveal(direction) {
callbackFn = function() {
// this is the part where is running the turning of pages
classie.remove(pages[currentPage], 'page--current');
if (navbar[1].clicked == true) {
currentPage = 0;
} else if(navbar[1].clicked == true) {
currentPage = 1;
} else if(navbar[2].clicked == true) {
currentPage = 2;
} else if(navbar[3].clicked == true) {
currentPage = 3;
} else if(navbar[4].clicked == true) {
currentPage = 4;
};
classie.add(pages[currentPage], 'page--current');
};
}
This is typically a problem of closure.
You can make the following change
Here the call back function of the addEventListener is an IIFE, & in the reveal function pass the value of i
var navbar = document.getElementById("navbar").getElementsByTagName("a");
for (var i = 0; i < navbar.length; i++) {
navbar[i].addEventListener('click', (function(x) {
reveal('top',x);
}(i))};
}
In this function you will have access to
function reveal(direction,index) {
// not sure what this function is mean by, but you will have the value of `i` which is denote the clicked element
callbackFn = function() {
// this is the part where is running the turning of pages
classie.remove(pages[currentPage], 'page--current');
if (index == 1) {
currentPage = 0;
} else if (index == 1) {
currentPage = 1;
} else if (index == 2) {
currentPage = 2;
} else if (index == 3) {
currentPage = 3;
} else if (index == 4) {
currentPage = 4;
};
classie.add(pages[currentPage], 'page--current');
};
}
Here is the solution in my case.
Thank you brk for helping in any case, thanks again.
// determine clicked item
var n;
$('#navbar a').click(function(){
if($(this).attr('id') == 'a') {
n = 0;
} else if($(this).attr('id') == 'b') {
n = 1;
} else if($(this).attr('id') == 'c') {
n = 2;
} else if($(this).attr('id') == 'd') {
n = 3;
} else if($(this).attr('id') == 'e') {
n = 4;
};
});
var pages = [].slice.call(document.querySelectorAll('.pages > .page')),
currentPage = 0,
revealerOpts = {
// the layers are the elements that move from the sides
nmbLayers : 3,
// bg color of each layer
bgcolor : ['#52b7b9', '#ffffff', '#53b7eb'],
// effect classname
effect : 'anim--effect-3'
};
revealer = new Revealer(revealerOpts);
// clicking the page nav
document.querySelector("#a").addEventListener('click', function() { reveal('cornertopleft'); });
document.querySelector("#b").addEventListener('click', function() { reveal('bottom'); });
document.querySelector("#c").addEventListener('click', function() { reveal('left'); });
document.querySelector("#d").addEventListener('click', function() { reveal('right'); });
document.querySelector("#e").addEventListener('click', function() { reveal('top'); });
// moving clicked item's `n` into the function
function reveal(direction) {
var callbackTime = 750;
callbackFn = function() {
classie.remove(pages[currentPage], 'page--current');
currentPage = n;
classie.add(pages[currentPage], 'page--current');
};
revealer.reveal(direction, callbackTime, callbackFn);
}
All,
I have three cards which can be shuffled by the user, upon hover, the target card pops to the top, the last card on top should sit in the second position. While with the code below, I can have this effect in one direction (left to right), I am struggling to come up with logic & code for getting the effect to work in both directions without having to write multiple scenarios in js (which doesnt sound like very good logic).
Hopefully the demo will do a better explanation.
Code:
$(".cBBTemplates").on (
{
hover: function (e)
{
var aBBTemplates = document.getElementsByClassName ("cBBTemplates");
var i = 2;
while (i < aBBTemplates.length && i >= 0)
{
var eCurVar = aBBTemplates[i];
if (eCurVar === e.target)
{
eCurVar.style.zIndex = 3;
} else if (eCurVar.style.zIndex === 3) {
console.log (eCurVar);
eCurVar.style.zIndex = 3-1;
} else
{
eCurVar.style.zIndex = i;
}
i--;
}
}
});
Try this:
$(function(){
var current = 2;
$(".cBBTemplates").on (
{
hover: function ()
{
var target = this,
newCurrent, templates = $(".cBBTemplates");
templates.each(
function(idx){
if(this === target){
newCurrent = idx;
}
});
if(newCurrent === current){return;}
templates.each(function(index){
var zIndex = 0;
if(this === target) {
zIndex = 2;
}
else if (index == current) {
zIndex = 1;
}
$(this).css('zIndex', zIndex);
});
current = newCurrent;
}
});
});