I've done a research on this question and found some solutions. However, not every one of them worked. As I understand, async false makes a UI block, which shouldn't be. I could use an overlay until ajax request is completed and on the request success, hide the overlay.
That was my try using a callback argument in the getNewQuote() function (only a small snippet of it):
var getNewQuote = function(callback) {
var quote = {};
setTimeout(function() {
quote.text = 'Example';
quote.author = 'Example';
callback();
return quote;
}, 4000);
};
getNewQuote(function() {
console.log("DONE");
var getRandomColor = function() {
var colors = [
"#ff9966",
"#7f00ff",
"#396afc",
"#0cebeb",
"#06beb6",
"#642b73",
"#36d1dc",
"#cb356b",
"#3a1c71",
"#ef3b36",
"#159957",
"#000046",
"#007991",
"#56ccf2",
"#f2994a",
"#e44d26",
"#4ac29a",
"#f7971e",
"#34e89e",
"#6190e8",
"#3494e6",
"#ee0979"
],
randomNumber = Math.floor(Math.random() * colors.length);
return colors[randomNumber];
};
var updateText = function($t, qt) {
var twitter = "https://twitter.com/intent/tweet?hashtags=quotes&related=freecodecamp&text=";
twitter += '"' + qt.text + '" ';
twitter += qt.author;
var tumblr = "https://www.tumblr.com/widgets/share/tool?posttype=quote&tags=quotes,freecodecamp&caption=";
tumblr += qt.author;
tumblr += "&content=";
tumblr += qt.text;
tumblr += "&canonicalUrl=https%3A%2F%2Fwww.tumblr.com%2Fbuttons&shareSource=tumblr_share_button";
var $icon = $("<i class='fa fa-quote-left'>")
.prop("aria-hidden", true);
$t.find(".quote-text").html("").append($icon, qt.text);
$t.find(".quote-author").html("- " + qt.author);
$("#tweet-quote").attr("href", twitter);
$("#tumblr-quote").attr("href", tumblr);
};
var calcNewHeight = function(q) {
var $temp = $("<div>", {
class: "quote-container temp",
}).appendTo($("body"));
$temp.append($("<div>", {
class: "quote-text"
}), $("<div>", {
class: "quote-author"
}));
updateText($temp, q);
var h = $temp.height() + 40;
$temp.remove();
return h;
};
var changeColor = function(newColor) {
$("body, .button:not(#new-quote)").animate({
backgroundColor: newColor
});
$("#new-quote").animate({
color: newColor
});
$(".quote-text, .quote-author").css("color", newColor);
if ($("#modStyle").length === 0) {
$("head").append(
"<style id='modStyle'>#new-quote:before {background:" + newColor + ";}</style>"
);
} else {
$("head style#modStyle").html("#new-quote:before {background:" + newColor + ";}");
}
};
var getQuote = function() {
var nq, nc, nh = 0;
nq = getNewQuote();
nc = getRandomColor();
nh = calcNewHeight(nq);
$(".quote-container").children().css("opacity", 0);
changeColor(nc);
$(".quote-container, #new-quote").animate({
height: nh,
}, {
duration: 1000,
queue: false
});
$(".quote-container").animate({
padding: "2.5em"
}, {
duration: 1000,
queue: false
});
$("#new-quote").animate({
padding: "2.5em .75em"
}, {
duration: 1000,
queue: false
});
updateText($(".quote-container"), nq);
$(".quote-container").children().fadeTo(750, 1);
};
$("#new-quote").on("click", getQuote);
$(".quote-container, #new-quote").css({
visibility: "visible",
height: 0
});
$("#new-quote").css("padding", "0 .75em");
getQuote();
});
html,
body {
height: 100%;
width: 100%;
}
body {
margin: 0;
padding: 0;
background: #333;
color: #333;
font-family: sans-serif;
}
.v-wrap {
height: 100%;
text-align: center;
}
.v-wrap:before {
content: "";
display: inline-block;
vertical-align: middle;
width: 0;
height: 100%;
}
.quote-container {
width: 31.25rem;
background: #fff;
margin: 0;
display: inline-block;
vertical-align: middle;
border-radius: 0.1875rem;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
visibility: hidden;
padding: 0 2.5rem;
}
.quote-text {
font-size: 1.625rem;
}
.quote-text i {
margin-right: 0.6rem;
}
.quote-text p {
display: inline;
}
.quote-author {
font-size: 1rem;
margin: 0 0.4rem 2rem 0;
text-align: right;
}
.button {
padding: 0.75rem;
text-align: center;
font-size: 1rem;
color: #fff;
border-radius: .1875rem;
display: inline-block;
cursor: pointer;
-webkit-user-select: none;
user-select: none;
}
.button:not(#new-quote):hover {
opacity: .8 !important;
}
.button:not(#new-quote) {
min-width: 1rem;
min-height: 1rem;
}
.button i {
vertical-align: middle;
}
#new-quote {
white-space: nowrap;
writing-mode: vertical-lr;
height: 50%;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
vertical-align: middle;
background: #fff !important;
margin: 0;
position: relative;
right: 0.25625rem;
color: #333;
visibility: hidden;
}
#new-quote:before {
content: "";
position: absolute;
height: 100%;
width: 0.0625rem;
bottom: 0;
left: 0;
visibility: hidden;
-webkit-transform: scaleY(0);
transform: scaleY(0);
-webkit-transition: all .3s ease-in-out;
transition: all .3s ease-in-out;
}
#new-quote:hover:before {
visibility: visible;
-webkit-transform: scaleY(1);
transform: scaleY(1);
}
footer {
font-size: 0.85rem;
margin-bottom: 1rem;
}
footer a {
text-decoration: none;
color: #fff;
position: relative;
}
footer a:before {
content: "";
position: absolute;
width: 100%;
height: .0625rem;
bottom: 0;
left: 0;
background: #fff;
visibility: hidden;
-webkit-transform: scaleX(0);
transform: scaleX(0);
-webkit-transition: all .3s ease-in-out 0s;
transition: all .3s ease-in-out 0s;
}
footer a:hover:before {
visibility: visible;
-webkit-transform: scaleX(1);
transform: scaleX(1);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="v-wrap">
<div class="quote-container" style="">
<div class="quote-text">
</div>
<div class="quote-author"></div>
<a id="tweet-quote" class="button"><i class="fa fa-twitter"></i></a>
<a id="tumblr-quote" class="button"><i class="fa fa-tumblr"></i></a>
</div>
<div id="new-quote" class="button">New quote</div>
<footer>
Created by LukasLSC
</footer>
</div>
Code output:
As you can see, ajax wasn't success
Uncaught TypeError: callback is not a function and Uncaught TypeError: Cannot read property 'text' of undefined (only in the stack snippet).
I found out this error disappears if I remove the getQuote(); function call. However, I need to call it, overwise, my project won't work. I also tried to use return $.ajax but there was a return quote line so I couldn't use it. The full code can be found here on codepen: https://codepen.io/Kestis500/pen/ZvyxKB?editors=0110.
Then I switched to another method using jQuery promises and used information in this thread: https://stackoverflow.com/a/40658281/8889739. Full code: https://codepen.io/Kestis500/pen/qpjxoq?editors=0110.
var MyFirstFunction = function() {
var getNewQuote = function(callback) {
var quote = {};
setTimeout(function() {
quote.text = 'Example';
quote.author = 'Example';
return quote;
}, 4000);
};
}
var MySecondFunction = function() {
console.log("DONE");
var getRandomColor = function() {
var colors = [
"#ff9966",
"#7f00ff",
"#396afc",
"#0cebeb",
"#06beb6",
"#642b73",
"#36d1dc",
"#cb356b",
"#3a1c71",
"#ef3b36",
"#159957",
"#000046",
"#007991",
"#56ccf2",
"#f2994a",
"#e44d26",
"#4ac29a",
"#f7971e",
"#34e89e",
"#6190e8",
"#3494e6",
"#ee0979"
],
randomNumber = Math.floor(Math.random() * colors.length);
return colors[randomNumber];
};
var updateText = function($t, qt) {
var twitter = "https://twitter.com/intent/tweet?hashtags=quotes&related=freecodecamp&text=";
twitter += '"' + qt.text + '" ';
twitter += qt.author;
var tumblr = "https://www.tumblr.com/widgets/share/tool?posttype=quote&tags=quotes,freecodecamp&caption=";
tumblr += qt.author;
tumblr += "&content=";
tumblr += qt.text;
tumblr += "&canonicalUrl=https%3A%2F%2Fwww.tumblr.com%2Fbuttons&shareSource=tumblr_share_button";
var $icon = $("<i class='fa fa-quote-left'>")
.prop("aria-hidden", true);
$t.find(".quote-text").html("").append($icon, qt.text);
$t.find(".quote-author").html("- " + qt.author);
$("#tweet-quote").attr("href", twitter);
$("#tumblr-quote").attr("href", tumblr);
};
var calcNewHeight = function(q) {
var $temp = $("<div>", {
class: "quote-container temp",
}).appendTo($("body"));
$temp.append($("<div>", {
class: "quote-text"
}), $("<div>", {
class: "quote-author"
}));
updateText($temp, q);
var h = $temp.height() + 40;
$temp.remove();
return h;
};
var changeColor = function(newColor) {
$("body, .button:not(#new-quote)").animate({
backgroundColor: newColor
});
$("#new-quote").animate({
color: newColor
});
$(".quote-text, .quote-author").css("color", newColor);
if ($("#modStyle").length === 0) {
$("head").append(
"<style id='modStyle'>#new-quote:before {background:" + newColor + ";}</style>"
);
} else {
$("head style#modStyle").html("#new-quote:before {background:" + newColor + ";}");
}
};
var getQuote = function() {
var nq, nc, nh = 0;
nq = getNewQuote();
nc = getRandomColor();
nh = calcNewHeight(nq);
$(".quote-container").children().css("opacity", 0);
changeColor(nc);
$(".quote-container, #new-quote").animate({
height: nh,
}, {
duration: 1000,
queue: false
});
$(".quote-container").animate({
padding: "2.5em"
}, {
duration: 1000,
queue: false
});
$("#new-quote").animate({
padding: "2.5em .75em"
}, {
duration: 1000,
queue: false
});
updateText($(".quote-container"), nq);
$(".quote-container").children().fadeTo(750, 1);
};
$("#new-quote").on("click", getQuote);
$(".quote-container, #new-quote").css({
visibility: "visible",
height: 0
});
$("#new-quote").css("padding", "0 .75em");
getQuote();
}
MyFirstFunction().done(MySecondFunction);
html,
body {
height: 100%;
width: 100%;
}
body {
margin: 0;
padding: 0;
background: #333;
color: #333;
font-family: sans-serif;
}
.v-wrap {
height: 100%;
text-align: center;
}
.v-wrap:before {
content: "";
display: inline-block;
vertical-align: middle;
width: 0;
height: 100%;
}
.quote-container {
width: 31.25rem;
background: #fff;
margin: 0;
display: inline-block;
vertical-align: middle;
border-radius: 0.1875rem;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
visibility: hidden;
padding: 0 2.5rem;
}
.quote-text {
font-size: 1.625rem;
}
.quote-text i {
margin-right: 0.6rem;
}
.quote-text p {
display: inline;
}
.quote-author {
font-size: 1rem;
margin: 0 0.4rem 2rem 0;
text-align: right;
}
.button {
padding: 0.75rem;
text-align: center;
font-size: 1rem;
color: #fff;
border-radius: .1875rem;
display: inline-block;
cursor: pointer;
-webkit-user-select: none;
user-select: none;
}
.button:not(#new-quote):hover {
opacity: .8 !important;
}
.button:not(#new-quote) {
min-width: 1rem;
min-height: 1rem;
}
.button i {
vertical-align: middle;
}
#new-quote {
white-space: nowrap;
writing-mode: vertical-lr;
height: 50%;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
vertical-align: middle;
background: #fff !important;
margin: 0;
position: relative;
right: 0.25625rem;
color: #333;
visibility: hidden;
}
#new-quote:before {
content: "";
position: absolute;
height: 100%;
width: 0.0625rem;
bottom: 0;
left: 0;
visibility: hidden;
-webkit-transform: scaleY(0);
transform: scaleY(0);
-webkit-transition: all .3s ease-in-out;
transition: all .3s ease-in-out;
}
#new-quote:hover:before {
visibility: visible;
-webkit-transform: scaleY(1);
transform: scaleY(1);
}
footer {
font-size: 0.85rem;
margin-bottom: 1rem;
}
footer a {
text-decoration: none;
color: #fff;
position: relative;
}
footer a:before {
content: "";
position: absolute;
width: 100%;
height: .0625rem;
bottom: 0;
left: 0;
background: #fff;
visibility: hidden;
-webkit-transform: scaleX(0);
transform: scaleX(0);
-webkit-transition: all .3s ease-in-out 0s;
transition: all .3s ease-in-out 0s;
}
footer a:hover:before {
visibility: visible;
-webkit-transform: scaleX(1);
transform: scaleX(1);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="v-wrap">
<div class="quote-container" style="">
<div class="quote-text">
</div>
<div class="quote-author"></div>
<a id="tweet-quote" class="button"><i class="fa fa-twitter"></i></a>
<a id="tumblr-quote" class="button"><i class="fa fa-tumblr"></i></a>
</div>
<div id="new-quote" class="button">New quote</div>
<footer>
Created by LukasLSC
</footer>
</div>
Code output:
It broke everything, the gray screen is because of the default codepen background
Uncaught TypeError: Cannot read property 'done' of undefined
You're using return from the asynchronous operation's callback. That just sets the return value of that callback (which is ignored in the case of setTimeout's or XHR's callback), it doesn't set the return value of your function.
You can't return the value from your function, which is why you're adding a callback. Instead:
var getNewQuote = function(callback) {
var quote = {};
setTimeout(function() {
quote.text = 'Example';
quote.author = 'Example';
callback(quote); // <====
}, 4000);
};
...and use the parameter of the callback, e.g.:
getNewQuote(function(quote) {
// Use quote here...
});
Live Example:
var getNewQuote = function(callback) {
var quote = {};
setTimeout(function() {
quote.text = 'Example';
quote.author = 'Example';
callback(quote); // <====
}, 1000);
};
getNewQuote(function(quote) {
console.log("quote:", quote);
});
Related
I'm just learning how to use VUE and I’m trying to separate my HTML, CSS and JS files to get more organized. But something is going wrong, I think with the CSS file but I’m not sure.
Just to get a basic understanding what my code is supposed to do:
There is a welcome screen where 2 rows of text are displayed which are being faded in and out
HTML:
<template>
<header id="mainHeader">
<div class="logo-container"><img src="../Logo/LogoIND.png" alt="Logo IND" id="logo"></div>
</header>
<main>
<div class="loop-text">
<p>BIER</p>
<p>Hoşgeldiniz</p>
<p>Ласкаво просимо</p>
<p>ښه راغلاست</p>
<p>أهلا بك</p>
<p>Welkom</p>
</div>
<div class="loop-text2">
<p>DRINK to Start</p>
<p>Başlatmak için dokunun</p>
<p>Торкніться, щоб почати</p>
<p>مسکارا پیل دی</p>
<p>المس للبدء</p>
<p>Aanraken om te beginnen</p>
</div>
</main>
</template>
<script src="./Welkom.js"></script>
<style scoped>
#import './CSS.css';
</style>
Here at the bottom i have my references to my CSS and JS.
CSS:
template {
background-color: #452170;
color: #ffff;
font-family: Arial, Helvetica, sans-serif;
font-size: 16px;
line-height: 1.6em;
margin: 0;
height: 1080px;
}
.logo-container {
text-align: center;
width: 100%;
}
#logo {
height: 17em;
}
.containter {
height: auto;
}
#keyframes fade {
0% {
opacity: 0;
}
50% {
opacity: 1;
}
100% {
opacity: 0;
}
}
.loop-text {
width: 100%;
text-align: center;
position: relative;
height: 25em;
}
.loop-text p {
font-family: 'PT Serif';
opacity: 0;
transition: 1.75s ease-out;
width: inherit;
position: absolute;
height: inherit;
font-size: 16em;
top: 0.6em;
margin: 0;
padding: 0;
}
.loop-text .show {
opacity: 1;
}
.loop-text2 {
width: 100%;
text-align: center;
position: relative;
height: 25em;
}
.loop-text2 p {
font-family: 'PT Serif';
opacity: 0;
transition: 1.75s ease-out;
width: inherit;
position: absolute;
height: inherit;
font-size: 9em;
top: 0.6em;
margin: 0;
padding: 0;
}
.loop-text2 .Afbeelden {
opacity: 1;
}
And my javascript:
let texts = document.querySelectorAll(".loop-text p");
let prev = null;
let animate = (curr, currIndex) => {
let index = (currIndex + 1) % texts.length
setTimeout(() => {
if(prev) {
prev.className = "";
}
curr.className = "show";
prev = curr;
animate(texts[index], index);
}, 3500);
}
animate(texts[0], 0);
let texts2 = document.querySelectorAll(".loop-text2 p");
let prev2 = null;
let animate2 = (curr, currIndex) => {
let index = (currIndex + 1) % texts2.length
setTimeout(() => {
if(prev2) {
prev2.className = "";
}
curr.className = "Afbeelden";
prev2 = curr;
animate2(texts2[index], index);
}, 3500);
}
I'm trying to get to grips with javascript, and have followed a tutorial for a simple image slider. I'm trying to add to it and have the background fade to different colours as the slides move. I've managed to figure it out with the right and left arrows (not sure on best practise), but I can't seem to get it right when selecting the indicators. Can anyone advise on a solution?
Thanks in advance.
const left = document.querySelector('.left');
const right = document.querySelector('.right');
const slider = document.querySelector('.carousel__slider');
const indicatorParent = document.querySelector('.carousel__controls ol');
const indicators = document.querySelectorAll('.carousel__controls li');
index = 0;
var background = 1;
function indicatorBg(val){
var background = val;
changeBg();
}
indicators.forEach((indicator, i) => {
indicator.addEventListener('click', () => {
document.querySelector('.carousel__controls .selected').classList.remove('selected');
indicator.classList.add('selected');
slider.style.transform = 'translateX(' + (i) * -25 + '%)';
index = i;
});
});
left.addEventListener('click', function() {
index = (index > 0) ? index -1 : 0;
document.querySelector('.carousel__controls .selected').classList.remove('selected');
indicatorParent.children[index].classList.add('selected');
slider.style.transform = 'translateX(' + (index) * -25 + '%)';
if (background <= 1) {
return false;
} else {
background--;
}
changeBg();
});
right.addEventListener('click', function() {
index = (index < 4 - 1) ? index+1 : 3;
document.querySelector('.carousel__controls .selected').classList.remove('selected');
indicatorParent.children[index].classList.add('selected');
slider.style.transform = 'translateX(' + (index) * -25 + '%)';
if (background >= 4) {
return false;
} else {
background++;
}
changeBg();
});
function changeBg (){
if (background == 1) {
document.getElementById("carousel__track").className = 'slide-1';
} else if (background == 2) {
document.getElementById("carousel__track").className = 'slide-2';
} else if (background == 3) {
document.getElementById("carousel__track").className = 'slide-3';
} else if (background == 4) {
document.getElementById("carousel__track").className = 'slide-4';
}
}
window.onload = changeBg;
.carousel {
height: 80vh;
width: 100%;
margin: 0 auto;
}
#carousel__track {
height: 100%;
position: relative;
overflow: hidden;
}
.background {
background: red;
}
.carousel__slider {
height: 100%;
display: flex;
width: 400%;
transition: all 0.3s;
}
.carousel__slider div {
flex-basis: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.carousel__controls .carousel__arrow {
position: absolute;
top: 50%;
transform: translateY(-50%);
cursor: pointer;
z-index: 8888
}
.carousel__controls .carousel__arrow i {
font-size: 2.6rem;
}
.carousel__arrow.left {
left: 1em;
}
.carousel__arrow.right {
right: 1em;
}
.carousel__controls ol {
position: absolute;
bottom: 15%;
left: 50%;
transform: translateX(-50%);
list-style: none;
display: flex;
margin: 0;
padding: 0;
}
.carousel__controls ol li {
width: 14px;
height: 14px;
border-radius: 50px;
margin: .5em;
padding: 0;
background: white;
transform: scale(.6);
cursor: pointer;
}
.carousel__controls ol li.selected {
background: black;
transform: scale(1);
transition: all .2s;
transition-delay: .3s;
}
.slide-1 {
background: pink;
transition: all 0.4s;
}
.slide-2 {
background: coral;
transition: all 0.4s;
}
.slide-3 {
background: green;
transition: all 0.4s;
}
.slide-4 {
background: orange;
transition: all 0.4s;
}
<section class="carousel">
<div id="carousel__track">
<div class="carousel__slider">
<div>Slide 1</div>
<div>Slide 2</div>
<div>Slide 3</div>
<div>Slide 4</div>
</div>
<div id="left" class="carousel__controls"><span class="carousel__arrow left"><</span> <span id="right" class="carousel__arrow right">></span>
<ol>
<li value="1" onclick="indicatorBg(this.value)" class="selected"></li>
<li value="2" onclick="indicatorBg(this.value)"></li>
<li value="3" onclick="indicatorBg(this.value)"></li>
<li value="4" onclick="indicatorBg(this.value)"></li>
</ol>
</div>
</div>
</section>
You forgot to change the background inside the click event handler of the indicators.
indicators.forEach((indicator, i) => {
indicator.addEventListener('click', () => {
document.querySelector('.carousel__controls .selected').classList.remove('selected');
indicator.classList.add('selected');
slider.style.transform = 'translateX(' + (i) * -25 + '%)';
index = i;
background = index + 1;
changeBg();
});
});
As far as best practice goes, I typically use class names for CSS and IDs for JavaScript. Personally, I wouldn't recommend you worry about best practices at this stage, but instead, focus on getting the code working and understanding what's going on line-by-line.
There is a lot of solutions, but the simplest solution that I advice is to use odd and even numbers to style the divs in the carousel (meaning that eg. first is green second is orange third is green and so on...
.carousel__slider div:nth-child(2n) /*Selects even numbered elements*/
.carousel__slider div:nth-child(2n+1) /*Selects odd numbered elements*/
Check out the snippet
const left = document.querySelector('.left');
const right = document.querySelector('.right');
const slider = document.querySelector('.carousel__slider');
const indicatorParent = document.querySelector('.carousel__controls ol');
const indicators = document.querySelectorAll('.carousel__controls li');
index = 0;
//var background = 1;
//function indicatorBg(val){
// var background = val;
// changeBg();
//}
indicators.forEach((indicator, i) => {
indicator.addEventListener('click', () => {
document.querySelector('.carousel__controls .selected').classList.remove('selected');
indicator.classList.add('selected');
slider.style.transform = 'translateX(' + (i) * -25 + '%)';
index = i;
});
});
left.addEventListener('click', function() {
index = (index > 0) ? index -1 : 0;
document.querySelector('.carousel__controls .selected').classList.remove('selected');
indicatorParent.children[index].classList.add('selected');
slider.style.transform = 'translateX(' + (index) * -25 + '%)';
// if (background <= 1) {
// return false;
// } else {
// background--;
// }
// changeBg();
});
right.addEventListener('click', function() {
index = (index < 4 - 1) ? index+1 : 3;
document.querySelector('.carousel__controls .selected').classList.remove('selected');
indicatorParent.children[index].classList.add('selected');
slider.style.transform = 'translateX(' + (index) * -25 + '%)';
// if (background >= 4) {
// return false;
// } else {
// background++;
// }
// changeBg();
});
//function changeBg (){
// if (background == 1) {
// document.getElementById("carousel__track").className = 'slide-1';
// } else if (background == 2) {
// document.getElementById("carousel__track").className = 'slide-2';
// } else if (background == 3) {
// document.getElementById("carousel__track").className = 'slide-3';
// } else if (background == 4) {
// document.getElementById("carousel__track").className = 'slide-4';
// }
//}
//window.onload = changeBg;
.carousel {
height: 80vh;
width: 100%;
margin: 0 auto;
}
#carousel__track {
height: 100%;
position: relative;
overflow: hidden;
}
.background {
background: red;
}
.carousel__slider {
height: 100%;
display: flex;
width: 400%;
transition: all 0.3s;
}
.carousel__slider div {
flex-basis: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.carousel__controls .carousel__arrow {
position: absolute;
top: 50%;
transform: translateY(-50%);
cursor: pointer;
z-index: 8888
}
.carousel__controls .carousel__arrow i {
font-size: 2.6rem;
}
.carousel__arrow.left {
left: 1em;
}
.carousel__arrow.right {
right: 1em;
}
.carousel__controls ol {
position: absolute;
bottom: 15%;
left: 50%;
transform: translateX(-50%);
list-style: none;
display: flex;
margin: 0;
padding: 0;
}
.carousel__controls ol li {
width: 14px;
height: 14px;
border-radius: 50px;
margin: .5em;
padding: 0;
background: white;
transform: scale(.6);
cursor: pointer;
}
.carousel__controls ol li.selected {
background: black;
transform: scale(1);
transition: all .2s;
transition-delay: .3s;
}
/*.slide-1 {
background: pink;
transition: all 0.4s;
}
.slide-2 {
background: coral;
transition: all 0.4s;
}
.slide-3 {
background: green;
transition: all 0.4s;
}
.slide-4 {
background: orange;
transition: all 0.4s;
}*/
.carousel__slider div:nth-child(2n) {
background-color:orange;
}
.carousel__slider div:nth-child(2n+1) {
background-color:green;
}
<section class="carousel">
<div id="carousel__track">
<div class="carousel__slider">
<div>Slide 1</div>
<div>Slide 2</div>
<div>Slide 3</div>
<div>Slide 4</div>
</div>
<div id="left" class="carousel__controls"><span class="carousel__arrow left"><</span> <span id="right" class="carousel__arrow right">></span>
<ol>
<li value="1" class="selected"></li>
<li value="2" ></li>
<li value="3" ></li>
<li value="4" ></li>
</ol>
</div>
</div>
</section>
I'm trying to debug a small program that I have on codepen and I'm having a problem with the sequence of the program. If you show the console you will see the steps that the program is following.
After the second, third... search the program doesn't follow the steps as it should do it. I would appreciate some help.
Please, run the code on codepen because it doesn't run the same way on stackoverflow's snippets.
http://codepen.io/rafahuelin/pen/JEdqOa?editors=0011
$( document ).ready(function() {
//1 Appears the magnifier icon
console.log("1");
$("#created").addClass("created-start");
$("#search").html("<div id='magnifier' class='search-init animated fadeIn'> <div id='magnifier-stick' class='stick-appears'></div> </div>");
//2 When clicking on the icon appears the input form
console.log("2");
$("#magnifier").on("click", function() {
$("#magnifier-stick").addClass("animated fadeOut stick-disappears").removeClass("stick-appears");
$(".search-init").addClass("search-input").removeClass("search-init");
setTimeout(function() { //waits for 1s
readyToSearch();
}, 1000);
});
//3/9 input area prepared to search
function readyToSearch() {
console.log("3/9");
$("#search").html("<div class='search-input'><form><input id='input-form' class='animated fadeIn' type='text' name='searchContent' placeholder='Type Your Search Here...'></form></div>");
$("#input-form").prop('disabled', false); //trying to debug *******************************
$("#input-form").focus();
//4 After pressing Enter,
$("#search").on("submit", function(e) {
console.log("4");
var searchText = $("#input-form").val(); //<---JQuery /// var searchText = document.getElementById("input-form").value; <---In javascript
$("#input-form").prop('disabled', true); //Disable textbox to prevent multiple submit // trying to debug *****************************************
moveSearchUp(searchText);
sendToAPI(searchText);
return false;
});
} // input area prepared to search
//6 send request to API
function sendToAPI(searchText) {
console.log("6");
var searchRequest = "https://en.wikipedia.org/w/api.php?action=opensearch&format=json&search=" + searchText + "&namespace=&limit=10&callback=?";
var tmp = $.ajax({
url: searchRequest,
type: "GET",
async: false,
dataType: "json",
success: function (data, status, jqXHR) {
showList( data );
console.log("6 searchRequest: " + searchRequest);
console.log("6 searchText: " + searchText);
console.log("6 data[1]: " + data[1] );
},
error: function (errorMessage) {
console.log(errorMessage);
}
});
}
//7 show the results
function showList (data) {
console.log("7");
$("#results").addClass("results").html("<ul>");
for (i = 0; i < data[1].length; i++) {
$("#results").append("<div class='result-item'><a href='" + data[3][i] + "' target='blank_'><li> <h2 class='title'>" + data[1][i] + "</h2><p class='description'>" + data[2][i] + "</p></li></a></div>");
if(i != data[1].length - 1){
$("#results").append("<hr>")
}
}
$("#results").append("</ul>");
//8 click on the close X
$("#close").on("click", function() {
console.log("8");
$("#results").remove();
$("#created").addClass("created-start");
readyToSearch();
});
}
//5 search-input moves up
function moveSearchUp(searchText) {
console.log("5");
$("#created").removeClass("created-start");
$(".search-input").removeClass("search-input").addClass("search-top");
setTimeout(function() { //waits for 1s
$("#input-form").css({'width': searchText.length * 12 + 'px'});
}, 500);
if ($("#close > i").hasClass("fa-times") === false) {
$("form").append("<div id='close'><i class='fa fa-times' aria-hidden='true'></i></div>");
}
if ($("#created").hasClass("created-start") === false) {
$("#created").addClass("created-start");
}
} // end function moveSearchUp
}); // $(document).ready
.search-init {
height: 70px;
width: 70px;
border: 4px solid rgba(185, 18, 27, 1);
border-radius: 35px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
position: absolute;
-webkit-animation-duration: 3s;
-ms-animation-duration: 3s;
-moz-animation-duration: 3s;
}
#magnifier-stick.stick-appears {
height: 20px;
width: 0;
border: 2px solid rgba(185, 18, 27, 1);
transform: rotate(-45deg);
top: 54px;
left: 54px;
position: absolute;
transition: all 0.2s ease;
}
#magnifier-stick.stick-disappears {
height: 0;
width: 0;
border: 2px solid rgba(185, 18, 27, 1);
transform: rotate(-95deg);
top: 54px;
left: 54px;
position: absolute;
transition: all 200ms ease;
-webkit-animation-duration: 0.2s;
-ms-animation-duration: 0.2s;
-moz-animation-duration: 0.2s;
}
#input-form, #input-form:focus {
width: 100%;
min-width: 120px;
border-radius: 35px;
outline: none;
border: none;
padding-left: 20px;
padding-right: 20px;
transition: all 500ms 500ms ease;
background-color: rgba(255,255,255,0);
}
.search-input{
line-height: 56px;
height: 70px;
width: 570px;
border: 4px solid rgba(185, 18, 27, 1);
border-radius: 35px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
position: absolute;
transition: all 500ms 500ms ease;
background-color: rgba(255,255,255,0);
}
/* Change the background color of the input */
input:-webkit-autofill {
-webkit-box-shadow: 0 0 0px 1000px #F6E497 inset;
}
.search-top {
line-height: 40px;
height: 54px;
border: 4px solid rgba(185, 18, 27, 1);
border-radius: 27px;
top: 0;
left: 50%;
transform: translate(-50%, 0);
position: absolute;
transition: all 500ms 500ms ease;
}
input:-webkit-autofill{
background: none;
}
.results {
margin-left: auto;
margin-right: auto;
margin-top: 90px;
padding: 30px;
list-style: none;
letter-spacing: 2px;
}
.results a:hover {
text-decoration: none;
}
.result-item {
border-left: solid 7px rgba(185, 18, 27, 0);
margin-bottom: 15px;
padding: 15px;
}
.result-item:hover {
border-left: solid 7px rgba(185, 18, 27, 1);
transition: all ease 0.8s;
padding: 15px;
background-color: rgba(255,255,255,0.05);
}
.title {
font-size: 2.5rem;
font-weight: 500;
margin-top: 0;
color: #4C1B1B;
}
.description {
margin-bottom: 0;
color: #BD8D46;
}
hr {
border: 0;
height: 2px;
background-image: linear-gradient(to right, rgba(185, 18, 27, 0), rgba(185, 18, 27, 0.45), rgba(185, 18, 27, 0));
}
.created {
text-align: center;
margin: 40px;
font-size: 2.4rem;
letter-spacing: 2px;
text-decoration: none;
font-style: italic;
color: #B9121B;
}
.created-start {
position: absolute;
bottom: 45px;
left: 50%;
transform: translatex(-60%);
margin-bottom: 0;
}
.created a {
color: #B9121B;
font-size: 3.5rem;
text-decoration: none;
}
.name {
font-size: 2rem;
}
.created a:hover, .created a:visited {
color: #B9121B;
text-decoration: none;
}
/* .delete-search::after {
content: "<div id='close'><i class="fa fa-times" aria-hidden="true"></i></div>";
} */
#close {
float: right;
display: inline-block;
padding: 2px 10px;
background: none;
color: #B9121B;
font-size: 20px;
font-weight: 100;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
<body>
<div id="search">
</div>
<div id="results">
</div>
<footer>
<div id="created" class="created">
<span class="by">— </span> <a target="_blank" href="https://github.com/rafahuelin/"><span class="name">Rafa Huelin</span> <i class="fa fa-github" aria-hidden="true"></i></a> <span class="by"> —</span>
</div>
</footer>
</body>
</html>
The issue is that each time you call the readyToSearch function, you are binding the submit event.
As you call readyToSearch each time you click the close button, the submit is being bind again.
If you move the submit the event binding out of the readyToSearch function it works as supposed.
$( document ).ready(function() {
//1 Appears the magnifier icon
console.log("1");
$("#created").addClass("created-start");
$("#search").html("<div id='magnifier' class='search-init animated fadeIn'> <div id='magnifier-stick' class='stick-appears'></div> </div>");
//4 After pressing Enter,
$("#search").on("submit", function(e) {
console.log("4");
var searchText = $("#input-form").val(); //<---JQuery /// var searchText = document.getElementById("input-form").value; <---In javascript
$("#input-form").prop('disabled', true); //Disable textbox to prevent multiple submit // trying to debug *****************************************
moveSearchUp(searchText);
sendToAPI(searchText);
return false;
});
//2 When clicking on the icon appears the input form
console.log("2");
$("#magnifier").on("click", function() {
$("#magnifier-stick").addClass("animated fadeOut stick-disappears").removeClass("stick-appears");
$(".search-init").addClass("search-input").removeClass("search-init");
setTimeout(function() { //waits for 1s
readyToSearch();
}, 1000);
});
//3/9 input area prepared to search
function readyToSearch() {
console.log("3/9");
$("#search").html("<div class='search-input'><form><input id='input-form' class='animated fadeIn' type='text' name='searchContent' placeholder='Type Your Search Here...'></form></div>");
$("#input-form").prop('disabled', false); //trying to debug *******************************
$("#input-form").focus();
} // input area prepared to search
//6 send request to API
function sendToAPI(searchText) {
console.log("6");
var searchRequest = "https://en.wikipedia.org/w/api.php?action=opensearch&format=json&search=" + searchText + "&namespace=&limit=10&callback=?";
var tmp = $.ajax({
url: searchRequest,
type: "GET",
async: false,
dataType: "json",
success: function (data, status, jqXHR) {
showList( data );
console.log("6 searchRequest: " + searchRequest);
console.log("6 searchText: " + searchText);
console.log("6 data[1]: " + data[1] );
},
error: function (errorMessage) {
console.log(errorMessage);
}
});
}
//7 show the results
function showList (data) {
console.log("7");
$("#results").addClass("results").html("<ul>");
for (i = 0; i < data[1].length; i++) {
$("#results").append("<div class='result-item'><a href='" + data[3][i] + "' target='blank_'><li> <h2 class='title'>" + data[1][i] + "</h2><p class='description'>" + data[2][i] + "</p></li></a></div>");
if(i != data[1].length - 1){
$("#results").append("<hr>")
}
}
$("#results").append("</ul>");
//8 click on the close X
$("#close").on("click", function() {
console.log("8");
$("#results").remove();
$("#created").addClass("created-start");
readyToSearch();
});
}
//5 search-input moves up
function moveSearchUp(searchText) {
console.log("5");
$("#created").removeClass("created-start");
$(".search-input").removeClass("search-input").addClass("search-top");
setTimeout(function() { //waits for 1s
$("#input-form").css({'width': searchText.length * 12 + 'px'});
}, 500);
if ($("#close > i").hasClass("fa-times") === false) {
$("form").append("<div id='close'><i class='fa fa-times' aria-hidden='true'></i></div>");
}
if ($("#created").hasClass("created-start") === false) {
$("#created").addClass("created-start");
}
} // end function moveSearchUp
}); // $(document).ready
I am using a button that triggers 4-5 other buttons with animation. its working fine in Chrome but not in FireFox
I have used a fullscreen background video in my current project, with this button, but in firefox, when i inspect elements, it shows there, but the browser is not displaying the element at all.
inspiration taken by - http://codepen.io/phenax/
'use strict';
(function (document, win) {
var animation_time = 600;
var btn_move_limit = 30;
var item_showing = false;
var className = {
show_items: 'menu--list__show',
revolve: 'menu--list__revolve',
button_cross: 'bar__crossy'
};
var $el = {
toggle_btn: document.querySelector('.js-menu--toggle'),
menu_items: document.querySelector('.js-menu--list'),
items: document.querySelectorAll('.js-item')
};
var constrain = function constrain(val, lim) {
return val > lim ? lim : val < -lim ? -lim : val;
};
var setButtonPosition = function setButtonPosition(left, top) {
$el.toggle_btn.style.left = constrain(left, btn_move_limit) + 'px';
$el.toggle_btn.style.top = constrain(top, btn_move_limit) + 'px';
};
var showAllItems = function showAllItems() {
var item_menu = $el.menu_items.classList;
item_menu.add(className.show_items);
setTimeout(function () {
item_menu.add(className.revolve);
$el.toggle_btn.classList.add(className.button_cross);
item_showing = true;
}, animation_time);
};
var hideAllItems = function hideAllItems() {
var item_menu = $el.menu_items.classList;
item_menu.remove(className.revolve);
$el.toggle_btn.classList.remove(className.button_cross);
setTimeout(function () {
item_menu.remove(className.show_items);
item_showing = false;
setButtonPosition(0, 0);
}, animation_time);
};
var findPosRelative = function findPosRelative(e) {
e = e.pageX ? {
pageX: e.pageX,
pageY: e.pageY
} : e.touches[0];
var offset = {
x: win.innerWidth / 2,
y: win.innerHeight / 2
};
e.pageX = e.pageX - offset.x;
e.pageY = e.pageY - offset.y;
return e;
};
var menuBtnClickHandler = function menuBtnClickHandler() {
if (item_showing)
hideAllItems();
else
showAllItems();
};
var itemClick = function itemClick(e) {
var item_id = e.target.dataset.id;
console.log('Item ID: ' + item_id);
hideAllItems();
};
var mouseMoveMent = function mouseMoveMent(e) {
var left, top;
if (item_showing) {
e = findPosRelative(e);
left = 140 * e.pageX / win.innerWidth;
top = 140 * e.pageY / win.innerHeight;
} else {
left = 0;
top = 0;
}
setButtonPosition(left, top);
};
document.addEventListener('DOMContentLoaded', function () {
$el.toggle_btn.addEventListener('click', menuBtnClickHandler);
for (var i = 0; i < $el.items.length; i++) {
if (window.CP.shouldStopExecution(1)) {
break;
}
$el.items[i].addEventListener('click', itemClick);
}
window.CP.exitedLoop(1);
win.addEventListener('mousemove', mouseMoveMent);
win.addEventListener('touchmove', mouseMoveMent);
});
}(document, window));
.menu--toggle {
position: absolute;
width: 80px;
height: 80px;
border-radius: 50%;
transform: translateX(-50%);
border: none;
outline: none;
cursor: pointer;
left: 0;
top: 0;
color: #222;
z-index: 1;
background-image: url("../images/logo/logo.jpg");
background-position: center;
background-size: cover;
box-shadow: 0 0 0 rgba(204, 169, 44, 0.4);
}
.menu {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
margin-top: -80px;
filter: url("#svgFilter"); }
.menu .item {
position: absolute;
width: 80px;
height: 80px;
border-radius: 50%;
transform: translateX(-50%);
border: none;
outline: none;
cursor: pointer;
left: 0;
top: 0;
background-color: #FFEB3B;
color: #222; }
.menu .item {
transition: all 0.6s ease-in-out; }
.menu--toggle {
transition: all .2s linear; }
.menu--toggle .bar {
width: 20px;
height: 2px;
background-color: #222;
margin: 5px auto;
transition: all 0.6s ease-in-out; }
.menu--toggle.bar__crossy .bar:nth-child(2) {
opacity: 0; }
.menu--toggle.bar__crossy .bar:nth-child(1) {
transform: translateY(7px) rotate(45deg); }
.menu--toggle.bar__crossy .bar:nth-child(3) {
transform: translateY(-7px) rotate(-45deg); }
.menu--list ul {
list-style-type: none;
padding: 0;
margin: 0; }
.menu--list li {
position: absolute;
width: 60px;
height: 80px;
transition: all 0.6s ease-in-out;
transform-origin: 0% 50%; }
.menu--list__show .item {
margin-left: 60px; }
.menu--list__revolve li:nth-child(1) {
transform: rotate(90deg); }
.menu--list__revolve li:nth-child(1) .item {
transform: rotate(270deg); }
.menu--list__revolve li:nth-child(2) {
transform: rotate(180deg); }
.menu--list__revolve li:nth-child(2) .item {
transform: rotate(180deg); }
.menu--list__revolve li:nth-child(3) {
transform: rotate(270deg); }
.menu--list__revolve li:nth-child(3) .item {
transform: rotate(90deg); }
.menu--list__revolve li:nth-child(4) {
transform: rotate(360deg); }
.menu--list__revolve li:nth-child(4) .item {
transform: rotate(0deg); }
<div class="menu">
<nav class="menu--list js-menu--list">
<ul>
<li><button type="button" onClick="window.open('https://www.facebook.com/themadhousecafe', '_blank')" class="fa fa-facebook item js-item" data-id="1"></button></li>
<li><button type="button" onClick="window.open('http://blog.nomadbaker.com/', '_blank')" class="fa item js-item" data-id="2">Blog</button></li>
<li><button type="button" onClick="window.open('#', '_blank')" class="item js-item" data-id="3">Menu</button></li>
<li><button type="button" onClick="window.open('#', '_blank')" class="fa fa-phone item js-item" data-id="4"></button></li>
</ul>
</nav>
<button type="button" class='logo_button menu--toggle js-menu--toggle'>
<div class="bar"></div>
<div class="bar"></div>
<div class="bar"></div>
</button>
</div>
My web application is made of various panels and a dashboard that has buttons to access each panel. So each button is a toggle between the purposed panel and the main panel.
For example, if we have 3 panels, panel1 is the default one and two buttons to toggle between other two panels the the default one:
button.panel2 should switch between panel1 and panel2
button.panel3 should switch between panel1 and panel3
I have almost achieved it but my code shows both panel2 and panel3 overlapping.
$(function () {
$(".panel2").on("click", function() {
var visibleObj = $('.mainSection div:visible');
var inVisibleObj = $('.mainSection div:hidden');
visibleObj.fadeOut(500, function() {
inVisibleObj.fadeIn(500);
});
});
$(".panel3").on("click", function() {
var visibleObj = $('.mainSection div:visible');
var inVisibleObj = $('.mainSection div:hidden');
visibleObj.fadeOut(500, function() {
inVisibleObj.fadeIn(500);
});
});
});
div.app {
margin:50px auto;
width: 400px;
height: 400px;
border-radius:10px;
overflow: hidden;
position: relative;
}
div.app > .blur {
width: 100%;
height: 100%;
background: url(http://goo.gl/0VTd9W);
-webkit-filter: blur(5px);
}
div.mainSection, div.dashboard{
position: absolute;
left: 0px;
text-align:center;
color:#fff;
font-size:20px;
}
div.mainSection{
width:100%;
height:85%;
background:rgba(0,0,0,0.5);
top:0;
}
div.dashboard{
width:100%;
height:15%;
background:rgba(255,0,0,0.5);
bottom:0;
}
div.mainSection > .panel1,
div.mainSection > .panel2,
div.mainSection > .panel3 {
width: 100%;
Height: 100%;
Background: rgba(0, 0, 0, 0.5);
position: absolute;
left: 0px;
top: 0px;
}
div.mainSection > .panel3 > p{
margin-top:80px;
}
.grid-button {
background: none;
border: none;
padding: 3px;
width: 100%;
}
.grid {
display: inline-block;
height: 4px;
position: relative;
width: 32px;
transition: all 0.3s ease-in-out;
}
.grid:after, .grid:before {
content: '';
position: absolute;
background-color: #FFF;
display: inline-block;
height: 4px;
left: 0;
width: 32px;
transition: all 0.3s ease-in-out;
}
.grid.open {
background-color: #FFF;
}
.grid.open:after {
top: 10px;
}
.grid.open:before {
top: -10px;
}
.grid.close {
background-color: transparent;
transform: scale(0.9);
}
.grid.close:after, .grid.close:before {
top: 0;
transform-origin: 50% 50%;
}
.grid.close:before {
transform: rotate(135deg);
}
.grid.close:after {
transform: rotate(45deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="app">
<div class="blur"></div>
<div class="mainSection">
<div class="panel1">Panel1</div>
<div class="panel2" style="display: none;">Panel2</div>
<div class="panel3" style="display: none;"><p>Panel3</p></div>
</div>
<div class="dashboard">
<button class="panel2">button1</button>
<button class="panel3">button2</button>
</div>
</div>
So I want to make button1 responsible to switch between panel 1 and 2. and button2 to switch between panel 1 and 3.
Any idea how to do it?
I think you need something like this. just these jquery code will be useful.
var currentPanel = 1;
$('.panelControlBtn').on("click", function() {
var ID = $(this).attr('data-id');
if (ID != currentPanel) {
$(".panel").fadeOut('fast', function() {
$("#panel" + ID).fadeIn('fast');
});
currentPanel = ID;
}
});
How about this? https://jsfiddle.net/oez0488h/53/
$("button.panel2").on("click", function() {
var visibleObj = $('.mainSection div:visible');
if ($("div.panel2").css("display") == "none") {
var inVisibleObj = $("div.panel2")
}
else {
var inVisibleObj = $("div.panel1")
}
visibleObj.fadeOut(500, function() {
inVisibleObj.fadeIn(500);
})
});
$("button.panel3").on("click", function() {
var visibleObj = $('.mainSection div:visible');
if ($("div.panel3").css("display") == "none") {
var inVisibleObj = $("div.panel3")
}
else {
var inVisibleObj = $("div.panel1")
}
visibleObj.fadeOut(500, function() {
inVisibleObj.fadeIn(500);
})
});