I'm looking to create a random name picker with HTML, JS and CSS which has gone quite well as you can see here... http://clients.random.agency/namepicker/
However, the client has asked for it to have a similar animation to this with ...
https://www.dropbox.com/s/3likecb0ld30som/Jv0Gp4XkhQ.mp4?dl=0
I've search google but I can't seem to find any examples of what I'm looking for and would really appreciate if anyone could point me in the right direction.
This is a simple example, hope be helpful.
var names =['John', 'David', 'Joe', 'Sara'];
var nameCount= names.length;
var p = document.getElementById("container");
var randTimer = setInterval(function(){ p.innerHTML = names[Math.floor(Math.random() * nameCount)]; }, 200);
function stop(){
clearInterval(randTimer);
}
#container{
color: red;
font-size:2rem;
text-align:center;
cursor: pointer;
}
<p id="container" onClick="stop()"></p>
<p>click on random names to pick one!</P>
Here's a pretty similar example I was able to find. Using Javascript seems to be the most straightforward way to go about doing this. https://codepen.io/maerianne/pen/pRQbQr
var myScrollTop = function(elem, delay){
elem.animate({ scrollTop: 0 }, delay, function(){
myScrollBottom(elem, delay);
});
};
var myScrollBottom = function(elem, delay){
elem.animate({ scrollTop: elem.height() }, delay, function(){
myScrollTop(elem, delay);
});
};
var scrollUpDown = function(elem, delay) {
myScrollTop(elem, delay);
};
$(document).ready(function(){
scrollUpDown($(".scroll-up-down"), 5000);
});
As you can see, scrollUpDown()is the initial function which starts a loop switching between myScrollTop() and myScrollBottom(). You could pretty easily make the delay increase with each iteration to mimic the slowing down and eventual stop in the example animation you gave.
You could also refactor this to be a singular recursive function.
Best of luck!
It picks a random item from the array of labels. Then it goes into a loop, changing the label to the next item in the array until it gets to the chosen one, and using animation for the transitions
$('#search_btns button:nth-child(2)').hover(function() {
btnTimeID = setTimeout(function() {
// We are using the math object to randomly pick a number between 1 - 11, and then applying the formula (5n-3)5 to this number, which leaves us with a randomly selected number that is applied to the <ul> (i.e. -185) and corresponds to the position of a word (or <li> element, i.e. "I'm Feeling Curious").
var pos = -((Math.floor((Math.random() * 11) + 1)) * 5 - 3) * 5
if (pos === -135) {
console.log("position didn't change, let's force change")
pos = -35;
}
$('#search_btns button:nth-child(2) ul').animate({'bottom':pos + 'px'}, 300);
// Change the width of the button to fit the currently selected word.
if (pos === -35 || pos === -110 || pos === -185 || pos === -10 || pos === -60 || pos === -160) {
console.log(pos + ' = -35, -110, -185, -10, -60, -160');
$('#search_btns button:nth-child(2)').css('width', '149px');
} else if (pos === -85) {
console.log(pos + ' = -85');
$('#search_btns button:nth-child(2)').css('width', '160px');
} else if (pos === -210) {
console.log(pos + ' = -210');
$('#search_btns button:nth-child(2)').css('width', '165px');
} else {
console.log(pos + ' = -260, -235');
$('#search_btns button:nth-child(2)').css('width', '144px');
}
},200);
}, function() {
clearTimeout(btnTimeID);
setTimeout(function() {
console.log('setTimeout function');
$('#search_btns button:nth-child(2) ul').css('bottom', '-135px'); // this is the original position
$('#search_btns button:nth-child(2)').css('width', '144px'); // reset the original width of the button
},200);
});
body, html {
margin: 0;
box-sizing: border-box;
font-family: arial;
}
*, *:before, *:after {
box-sizing: inherit;
}
#search_btns {
width: 400px;
margin: 30px auto;
padding-left: 60px;
}
#search_btns button:nth-child(2) {
width: 144px;
}
#search_btns button:nth-child(1) {
bottom: 12px;
}
#search_btns button {
position: relative;
height: 34px;
margin: 3px;
font-weight: bold;
color: gray;
background: #f1f1f1;
border: 1px solid #f1f1f1;
border-radius: 2px;
padding: 0 15px;
overflow: hidden;
}
#search_btns button:hover {
color: black;
border: 1px solid #bdbdbd;
box-shadow: 0px 0.5px 0px 0px #d3d3d3;
}
#search_btns button:active {
border: 1px solid #7f7fff;
}
#search_btns button:focus {
outline: 0;
}
#search_btns button ul li {
list-style-type: none;
padding: 5px 0;
text-align: left;
}
#search_btns button ul {
padding-left: 0;
position: absolute;
bottom: -135px;
width: 144px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="search_btns">
<button>This might be the effect you looking for</button>
<button>
<ul>
<li>item0/li>
<li>item1</li>
<li>item2</li>
<li>item3</li>
<li>item4</li>
<li>item5</li>
<li>item6</li>
<li>item7</li>
<li>item8</li>
<li>item9</li>
</ul>
</button>
</div>
</body>
</html>
Related
I created this color guessing game from scratch using HTML, CSS and JS. You're given a random RGB value and you guess which out of three given colors is the correct one. Now I want to take it a step higher by adding a scoreboard and score (Which I'm not sure how to do at all) and a full-screen congratulation message when you guess the color right. I've tried doing that but the animation doesn't seem to work.
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="style.css">
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1 class="text-centered" id="main-h1">Guess The Color!</h1>
<h2 class="text-centered" id="colorguess"></h2>
<p id="score">
</p>
<div class="box-container">
<div class="box">
</div>
<div class="box">
</div>
<div class="box">
</div>
</div>
<div id="bravo">
<p id="bravo-text">
BRAVO
</p>
</div>
</body>
<script src="script.js"></script>
</html>
CSS
*{
box-sizing: border-box;
}
body{
font-family: arial;
background-color: #1c1874;
color: rgb(105, 105, 139);
color: #fff;
}
.text-centered{
text-align: center;
text-shadow: 0px 2px 2px rgba(150, 150, 150, 1);
}
.box-container{
padding: 200px;
align-self: center;
display: flex;
flex-direction: row;
justify-content:space-evenly;
}
.box{
width: 200px;
height: 200px;
border-radius: 20px;
cursor: pointer;
border:5px solid #ffffff;
}
#score{
font-weight: 500;
font-size: 2em;
position: fixed;
top: 5%;
left: 5%;
}
#score::before {
content: "Score: ";
}
#bravo{
position: fixed;
display: none;
opacity: 0;
top: 0;
left: 0;
width: 100%;
height: 100%;
margin: 0;
text-align: center;
font-size: 5em;
background-color: rgba(4, 8, 97, 0.69);
}
#bravo-text{
flex: 0 0 120px;
text-shadow: 0px 2px 2px rgba(150, 150, 150, 1);
}
JS
function getrandomcolor(){
var r = Math.floor(Math.random() * 256);
var g = Math.floor(Math.random() * 256);
var b = Math.floor(Math.random() * 256);
rgb = "rgb("+r+", "+g+", "+b+")";
return rgb;
}
function gamestart(){
var mainh1 = document.getElementById('main-h1');
mainh1.innerHTML = "Guess the color!";
rgbvaluetrue = getrandomcolor();
var rgb = document.getElementById('colorguess');
rgb.innerHTML = rgbvaluetrue;
var body = document.getElementsByTagName('body');
var box = document.getElementsByClassName('box');
var scoreboard= document.getElementById('score');
var score = 0;
function displaybravo(element){
var op= 0;
var timer = setInterval(function () {
if (op >= 1){
clearInterval(timer);
}
if(op>=0.1){
element.style.display = "flex";
element.style.flexDirection = "column";
element.style.justifyContent = "center";
element.style.alignItems="center";
}
element.style.opacity = op;
element.style.filter = 'alpha(opacity=' + op * 100 + ")";
op += op * 0.1;
}, 10);
}
for(var i=0;i<box.length;i++){
box[i].style.backgroundColor = getrandomcolor();
}
//here I am trying to assign the initial rgb value to one of the divs randomly
var rand = Math.floor(Math.random() * box.length);
box[rand].style.backgroundColor = rgbvaluetrue;
//here I check if the div you clicked on is correct
function markSelection() {
if(this.style.backgroundColor == rgbvaluetrue) {
mainh1.innerHTML="BRAVO";
setTimeout(function() {
var brv = document.getElementById('bravo');
displaybravo(brv);
gamestart(); }, 2000);
} else {
gamestart();
}
}
for(var i=0;i<box.length;i++){
box[i].onclick = markSelection;
}
scoreboard.innerHTML=score;
}
gamestart();
I reviewed your game and made some changes to the code based on what stood out to me. There were a few bugs that were important to correct, and many things I changed purely for readability / preference.
I tend to avoid directly using timeouts. Promises are a good way to control the order of things in javascript. This game could likely benefit from OOP to make the logic more organized, but I didn't want to return you something that was completely unrecognizable. You are welcome to take this to code review for a more complete refactoring.
The first issue that I noticed is that your setInterval never resolves with the logic implemented. Because it never resolves, every time you attempted to show the bravo message, it would start an interval at 10 ms, and they would stack on top of eachother. This quickly would become an issue, potentially even breaking your page. Instead of attempting to redesign your interval logic, I decided to use the css transition attribute to handle the Bravo message, and I threw in a keyframe animation so you could see how to add other effects without javascript. Instead of having to write logic in js and preform resource expensive operations, I can leave the animation to css. Now js just needs to add and remove the hidden class.
I also wrote a helper function wait at the top of the js, and made functions with waiting async so I could use the await keyword instead of nesting my code inside timeouts. This is more readable in my own opinion.
To add a score, I moved the score variable above the gameStart function. This way each time the game restarts, the score is not affected. Then I just had to increment the score variable whenever a correct answer is given, and change the text in the dom.
One bug I noticed was that the correct answer could have been clicked several times, and the points would have increased, because the event listener was still active after the answer was submitted. To handle this, I changed the way the event listener was applied. Instead of using element.onclick =, I opted for el.addEventListener("click", . This allowed me to use .removeEventListener once the answer was given, and only reapply the event listener once the next round started. I also added a wait for incorrect answers, and some text when the wrong answer was given.
Other more cosmetic changes include using a helper function $ to make grabbing elements easier, and changing .innerHTML to .innerText to more clearly show intent / prevent potential bugs.
I didn't correct it in this code, but it's worth mentioning variable names in javascript are usually camel case. i.e. instead of getrandomcolor it would be getRandomColor
If you have any questions about my code, please ask 👍
const wait = t => new Promise(r => setTimeout(r, t));
const $ = (str, dom = document) => [...dom.querySelectorAll(str)];
function getrandomcolor(){
const random255 = () => Math.floor(Math.random() * 256);
const [r, g, b] = Array.from({length: 3}, random255);
return "rgb(" + r + ", " + g + ", " + b + ")";
}
let scoreboard = $('#score')[0];
let score = 0;
function gamestart(){
var mainh1 = $('#main-h1')[0];
mainh1.innerText = "Guess the color!";
rgbvaluetrue = getrandomcolor();
var rgb = $('#colorguess')[0];
rgb.innerText = rgbvaluetrue;
var body = document.body;
var allBoxes = $('.box');
async function displaybravo(element){
element.classList.remove("hidden");
await wait(2000);
element.classList.add("hidden");
await wait(1000);
}
for (var i=0; i<allBoxes.length; i++) {
allBoxes[i].style.backgroundColor = getrandomcolor();
}
var randomBoxIndex = Math.floor(Math.random() * allBoxes.length);
allBoxes[randomBoxIndex].style.backgroundColor = rgbvaluetrue;
async function markSelection() {
allBoxes.forEach(box => box.removeEventListener("click", markSelection));
if (this.style.backgroundColor == rgbvaluetrue) {
score++;
scoreboard.innerText = score;
mainh1.innerText = "BRAVO";
var brv = $('#bravo')[0];
await displaybravo(brv);
gamestart();
} else {
mainh1.innerText = "NOPE!";
await wait(1000);
gamestart();
}
}
allBoxes.forEach(box => box.addEventListener("click", markSelection));
scoreboard.innerHTML = score;
}
gamestart();
* {
box-sizing: border-box;
}
body {
margin: 0;
font-family: arial;
background-color: #1c1874;
color: rgb(105, 105, 139);
color: #fff;
}
.text-centered{
text-align: center;
text-shadow: 0px 2px 2px rgba(150, 150, 150, 1);
}
.box-container{
padding: 200px;
align-self: center;
display: flex;
flex-direction: row;
justify-content:space-evenly;
}
.box{
width: 200px;
height: 200px;
border-radius: 20px;
cursor: pointer;
border:5px solid #ffffff;
}
#score{
font-weight: 500;
font-size: 2em;
position: fixed;
top: 5%;
left: 5%;
}
#score::before {
content: "Score: ";
}
#bravo {
overflow: hidden;
position: fixed;
inset: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100%; /*needed to transition to / from*/
transition: height 2s;
}
#bravo.hidden {
height: 0;
}
#bravo-text {
font-size: 5rem;
font-weight: bold;
color: black;
animation: glow 1s ease-in-out infinite alternate;
}
#keyframes glow {
from {
text-shadow:
0 0 5px #fff,
0 0 10px #fff,
0 0 15px #e60073,
0 0 20px #e60073,
0 0 25px #e60073,
0 0 30px #e60073,
0 0 35px #e60073;
}
to {
text-shadow:
0 0 10px #fff,
0 0 20px #ff4da6,
0 0 30px #ff4da6,
0 0 40px #ff4da6,
0 0 50px #ff4da6,
0 0 60px #ff4da6,
0 0 70px #ff4da6;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="main.css">
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script defer src="main.js"></script>
</head>
<body>
<h1 class="text-centered" id="main-h1">Guess The Color!</h1>
<h2 class="text-centered" id="colorguess"></h2>
<p id="score">
</p>
<div class="box-container">
<div class="box">
</div>
<div class="box">
</div>
<div class="box">
</div>
</div>
<div id="bravo" class="hidden flexCenter">
<p id="bravo-text" class="flexCenter">
BRAVO
</p>
</div>
</body>
</html>
I have encountered some websites which has footer at the bottom and scroll actually happens when I scroll to the area above footer.
To automatically scroll those pages, but the problem with my code currently is it goes at the bottom of the page, where I directly reach footer and hence the scroll trigger which is present just above the footer does not gets triggered.
Is there any way to achieve the same?
This is what I have tried currently which I am executing from the console:
(function() {
var intervalObj = null;
var retry = 0;
var clickHandler = function() {
console.log("Clicked; stopping autoscroll");
clearInterval(intervalObj);
document.body.removeEventListener("click", clickHandler);
}
function scrollDown() {
var scrollHeight = document.body.scrollHeight,
scrollTop = document.body.scrollTop,
innerHeight = window.innerHeight,
difference = (scrollHeight - scrollTop) - innerHeight
if (difference > 0) {
window.scrollBy(0, difference);
if (retry > 0) {
retry = 0;
}
console.log("scrolling down more");
} else {
if (retry >= 3) {
console.log("reached bottom of page; stopping");
clearInterval(intervalObj);
document.body.removeEventListener("click", clickHandler);
} else {
console.log("[apparenty] hit bottom of page; retrying: " + (retry + 1));
retry++;
}
}
}
document.body.addEventListener("click", clickHandler);
intervalObj = setInterval(scrollDown, 1000);
})()
There are many websites that has this feature, to test the same one of the website which you can try is
https://www.zomato.com/bangalore/indiranagar-restaurants
Note : The question similar to this does not answer how to scroll at some mid point of page instead it takes me directly to the footer, so this is not a duplicate
Logic is to retain to the middle of the Scroller unless the page is completely loaded. We can tweak the code a little to achieve the last position of scroller. Try this:
var scrollHeight = 0,
newScrollHeight;
do {
window.scrollTo(0, document.body.scrollHeight / 2);
newScrollHeight = document.body.scrollHeight / 2;
if (newScrollHeight == scrollHeight) {
break;
} else {
scrollHeight = newScrollHeight;
}
} while (true);
Although Kumar Rishabh has already answered your question, I have another solution for this situation.
Set the domain to detect if the user scrolls to the domain.
The effect just like the website you povider . https://www.zomato.com/bangalore/indiranagar-restaurants
I do some simple example for you with pure Javascript.
Fragment core code:
// Here is domain to detect if user scroll into.
if (
triggerDomain.getBoundingClientRect().top < window.innerHeight &&
triggerDomain.getBoundingClientRect().bottom > 0
) {
if (getMore === false) {
getMore = true
// Do something you want here ....
console.info('got more !!')
Full code sample, check code snippet:
const rootElement = document.getElementById("rootDiv");
const triggerDomain = document.getElementById("triggerDomain");
let getMore = false;
function detectScrollIntoDomain() {
// Here is domain to detect if user scroll into.
if (
triggerDomain.getBoundingClientRect().top < window.innerHeight &&
triggerDomain.getBoundingClientRect().bottom > 0
) {
if (getMore === false) {
getMore = true;
// Do something you want here ....
console.info("got more !!");
setTimeout(() => {
let currentScrollTop = rootElement.scrollTop;
for (let i = 0; i < 15; i++) {
let r = Math.floor(Math.random() * 255);
let g = Math.floor(Math.random() * 255);
let b = Math.floor(Math.random() * 255);
const contentElement = document.getElementById("content");
const card = document.createElement("div");
card.className = "contentCard";
card.style.backgroundColor = `rgba(${r}, ${g}, ${b})`;
contentElement.appendChild(card);
}
rootElement.scrollTo(0, currentScrollTop);
// Don't forget to set flag to `false`.
getMore = false;
}, 200);
}
}
}
rootElement.addEventListener("scroll", detectScrollIntoDomain, {
passive: true
});
html,
body {
position: relative;
font-family: sans-serif;
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
h1,
h2 {
margin: 0;
color: aliceblue;
}
#rootDiv {
position: relative;
overflow: auto;
height: 100%;
width: 100%;
}
#header {
height: 200px;
background-color: rgb(112, 112, 112);
}
#content {
display: flex;
flex-wrap: wrap;
position: relative;
height: fit-content;
background-color: rgb(136, 136, 136);
}
#content div:first-child {
height: 600px;
width: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
#triggerDomain {
position: absolute;
bottom: 0px;
outline: 1px dashed rgb(3, 25, 119);
height: 500px;
width: 100%;
background: repeating-linear-gradient(
135deg,
rgba(46, 45, 45, 0.3) 0,
rgba(46, 45, 45, 0.3) 10px,
rgba(136, 136, 136, 0.3) 10px,
rgba(136, 136, 136, 0.3) 20px
);
}
#footer {
height: 180%;
background-color: rgb(112, 112, 112);
}
.contentCard {
width: 180px;
height: 180px;
margin: 12px;
border-radius: 8px;
background-color: aquamarine;
}
<!DOCTYPE html>
<html>
<head>
<title>Parcel Sandbox</title>
<meta charset="UTF-8" />
<link rel="stylesheet" type="text/css" href="./src/styles.css"
</head>
<body>
<div id="rootDiv">
<div id="header">
<h1>Header</h1>
</div>
<div id="content">
<div>
<h2>Content</h2>
<h2>Scroll down to get more cards.</h2>
</div>
<div id="triggerDomain">
<h2>Trigger domain</h2>
</div>
</div>
<div id="footer">
<h2>Footer</h2>
</div>
</div>
<script src="src/index.js"></script>
</body>
</html>
Hope to help you !
PROBLEM: Element with id "containerLnkMenu" does not center correctly in it's parent div when passed into the js function "centerElementYParent" unless I put a break point in the function using google chrome's debugger.
The "getComputedStyle(f, null)" call returns a "0px" for height if executed normally so I end up with a '-57px' for the margin-top.
COMMENT: So I found a few people that had similar problems on the internet, but I couldn't find a way to map their solution to my needs.
Any help on this would be appreciated.
Let me know if you need me to explain anything further.
I would prefer a detailed response or links to further reading, that is related to my issue (so I can learn from this error), but any related/helpful comment is welcome.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<!--[if lt IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link rel="stylesheet" href="main.css">
<script src="main.js"></script>
</head>
<body>
<div id="btnMenu" class="borderRadius" style="top: 10px; left: 10px;" onClick="btnMenuClicked(this)">
<div id="bar1" class="bar"></div>
<div id="bar2" class="bar"></div>
<div id="bar3" class="bar"></div>
</div>
<div id="menu" class="borderRadius" style="width: 0px; height: 0px;">
<div id="containerLnkMenu">
<a id="lnkNews" class="centerTxt lnkMenu" href="">NEWS</a>
<a id="lnkFiles" class="centerTxt lnkMenu" href="">FILES</a>
<a id="lnkTree" class="centerTxt lnkMenu" href="">TREE</a>
</div>
</div>
</body>
<script>
function btnMenuClicked(e) {
animateBtnMenu(e);
var menu = document.getElementById('menu');
var menuStyle = window.getComputedStyle(menu, null);
if (menuStyle.width == '0px' && menuStyle.height == '0px') {
openMenu(menu, menuStyle, e);
centerElementYParent(document.getElementById('containerLnkMenu'), document.getElementById('menu'));
} else {
closeMenu(menu, menuStyle, e);
}
}
</script>
</html>
body {
margin: 0;
font-family: Arial;
font-size: 16px;
}
a {
display: block;
text-decoration: none;
cursor: pointer;
}
/* Class Tools */
.centerTxt { text-align: center; }
.borderRadius { border-radius: 5px; }
.bar {
height: 5px;
transition: 0.4s;
background-color: #2E0A91;
}
.lnkMenu {
padding: 5px;
color: #FFD500;
font-size: 1.5em;
}
/*--- navigation ---*/
#btnMenu {
position: fixed;
width: 25px;
padding: 5px;
transition: 0.8s;
cursor: pointer;
}
#btnMenu:hover { background-color: #2E0A91; }
#btnMenu:hover .bar { background-color: #D4B100; }
#bar2 { margin: 5px 0 5px 0; }
.change #bar1 {
transform: rotate(-45deg) translate(-10px, 4px);
width: 141%;
}
.change #bar2 { opacity: 0; }
.change #bar3 {
transform: rotate(45deg) translate(-10px, -4px);
width: 141%;
}
#menu {
position: fixed;
z-index: 100;
top: 0;
left: 0;
overflow: hidden;
transition: 0.8s;
background-color: #2E0A91;
}
//NAME: centerElementYParent
//DESCRITPTION: e = element to center, f = parent element
// Adds margin top to e in order to vertically center element within parent (f)
function centerElementYParent(e, f) {
var eStyle = window.getComputedStyle(e, null);
var fStyle = window.getComputedStyle(f, null);
console.log(fStyle.height);
var eHeight = parseInt(eStyle.height.slice(0, eStyle.height.length - 2));
var fHeight = parseInt(fStyle.height.slice(0, fStyle.height.length - 2));
var marginTop = ((fHeight - eHeight)/2) + 'px';
e.style.marginTop = marginTop;
}
//NAME: animateBtnMenu
//DESCRIPTION: Attaches the 'change' class to the btnMenu element.
function animateBtnMenu(e) {
e.classList.toggle('change');
}
//NAME: openMenu
//DESCRIPTION: Applies a width and height to the menu whilst moving the menu button respectivley
function openMenu(e, eStyle, f) {
e.style.height = '250px';
e.style.width = '300px';
var eStyle = window.getComputedStyle(e, null);
f.style.left = '310px';
f.style.top = '260px';
}
//NAME: closeMenu
//DESCRIPTION: Sets width and height of the menu to 0 and moves the menu button respectivley
function closeMenu(e, eStyle, f) {
e.style.width = '0px';
e.style.height = '0px';
f.style.top = '10px';
f.style.left = '10px';
}
It may be because the element you want to center didn't rendered on the right position yet. Try adding setTimeout to call the function.
openMenu(menu, menuStyle, e);
setTimeout(function() {
centerElementYParent(document.getElementById('containerLnkMenu'), document.getElementById('menu'));
}, 800);
Working on a tip calculator with an animation on an h1 tag and a slideDown and slideUp on click on the h2 tags. Problem is, none of the animations are playing and the click event isn't working either.
Here is the HTML file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Tip Calculator</title>
<link rel="shortcut icon" href="images/favicon.ico">
<link rel="stylesheet" href="midtermcss.css">
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<script src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.js"></script>
<script src="animationJS.js"></script>
</head>
<body>
<section id="faqs">
<h1>Tip facts</h1>
<h2>Things to know before you tip</h2>
<div>
<p>Tips Account for 44 Billion dollars of the Food Industry</p>
<p>7 States require servers to be paid minimum wage like everyone else</p>
<ul>
<li>Minnessota</li>
<li>Montana</li>
<li>Washington</li>
<li>Oregon</li>
<li>California</li>
<li>Nevada</li>
<li>Alaska</li>
</ul>
<p>Current Federal minimum tipped wage is $2.13 per hour can you live on that?</p>
<p>Charging with Credit/Debit cards tends to reduce the average tip</p>
</div>
</section>
<section id="js">
<h1 id="heading">Tip Calculator</h1>
<label for="billAmount">Total Amount Of Bill:</label>
<input type="text" id="billAmount"><br>
<label for="percentTip">Percent To Tip:</label>
<input type="text" id="percentTip"><br>
<label for="amountPeople">How Many People?:</label>
<input type="text" id="amountPeople"><br>
<label for="totalTip">Tip Total:</label>
<input type="text" id="totalTip"><br>
<label> </label>
<input type="button" id="calculate" value="Calculate"><br>
</section>
</body>
</html>
Here is the JS file.
$(document).ready(function() {
// runs when an h2 heading is clicked
$("#faqs h2").toggle(
function() {
$(this).toggleClass("minus");
$(this).next().slideDown(1000, "easeOutBounce");
},
function() {
$(this).toggleClass("minus");
$(this).next().slideUp(1000, "easeInBounce");
}
);
$("#faqs h1").animate({
fontSize: "400%",
opacity: 1,
left: "+=375"
}, 1000, "easeInExpo")
.animate({
fontSize: "175%",
left: "-=200"
}, 1000, "easeOutExpo");
$("#faqs h1").click(function() {
$(this).animate({
fontSize: "400%",
opacity: 1,
left: "+=375"
}, 2000, "easeInExpo")
.animate({
fontSize: "175%",
left: 0
}, 1000, "easeOutExpo");
});
});
var $ = function(id) {
return document.getElementById(id);
}
var calculateClick = function() {
var billAmount = parseFloat($("billAmount").value);
var percentTip = parseFloat($("percentTip").value);
var amountPeople = parseInt($("amountPeople").value);
if (isNaN(billAmount) || billAmount <= 0) {
alert("Your bill can't be 0 or less.");
} else if (isNaN(percentTip) || percentTip <= 0) {
alert("The percentage should be a whole number.");
} else if (isNaN(amountPeople) || amountPeople <= 0) {
alert("You are 1 person never count yourself as less.");
} else {
var total = billAmount * (percentTip / 100) / amountPeople;
$("totalTip").value = total.toFixed(2);
}
}
window.onload = function() {
$("calculate").onclick = calculateClick;
$("billAmount").focus();
}
Last but not least the CSS file since the open and minus classes are listed in there
* {
margin: 0;
padding: 0;
}
body {
font-family: Arial, Helvetica, sans-serif;
background-color: white;
margin: 0 auto;
width: 500px;
border: 3px solid blue;
}
section {
padding: 0 1em .5em;
}
section.js {
padding: 0 1em .5em;
}
h1 {
text-align: center;
margin: .5em 0;
}
label {
float: left;
width: 10em;
text-align: right;
}
input {
margin-left: 1em;
margin-bottom: .5em;
}
#faqs h1 {
position: relative;
left: -168px;
font-size: 125%;
color: blue;
}
h2 {
font-size: 120%;
padding: .25em 0 .25em 25px;
cursor: pointer;
background: url(images/plus.png) no-repeat left center;
}
h2.minus {
background: url(images/minus.png) no-repeat left center;
}
div.open {
display: block;
}
ul {
padding-left: 45px;
}
li {
padding-bottom: .25em;
}
p {
padding-bottom: .25em;
padding-left: 25px;
}
I can't figure out for the life of me why the animations work in a separate test file but when I use them now in my tip calculator they don't. I'm using Murach's Javascript and Jquery book but this section has been terribly hard to understand.
Your issue is that you include jQuery but later on in the global scope you redefine the $:
var $ = function(id) {
return document.getElementById(id);
}
Fiddle: http://jsfiddle.net/AtheistP3ace/u0von3g7/
All I did was change the variable name holding that function and replace it in the areas you were using it. Specifically:
var getById = function(id) {
return document.getElementById(id);
}
var calculateClick = function() {
var billAmount = parseFloat(getById("billAmount").value);
var percentTip = parseFloat(getById("percentTip").value);
var amountPeople = parseInt(getById("amountPeople").value);
if (isNaN(billAmount) || billAmount <= 0) {
alert("Your bill can't be 0 or less.");
} else if (isNaN(percentTip) || percentTip <= 0) {
alert("The percentage should be a whole number.");
} else if (isNaN(amountPeople) || amountPeople <= 0) {
alert("You are 1 person never count yourself as less.");
} else {
var total = billAmount * (percentTip / 100) / amountPeople;
getById("totalTip").value = total.toFixed(2);
}
}
window.onload = function() {
getById("calculate").onclick = calculateClick;
getById("billAmount").focus();
}
$ is just shorthand for jQuery. When you include jQuery it creates two functions for you that both do the same thing. jQuery and $. If you set $ equal to something else you have effectively overwritten jQuery library included in your page and it will no longer operate as you would expect. All jQuery functionality begins with using $ or jQuery function. Once that returns a jQuery object to you, you can begin chaining and calling functions off those objects but to get a jQuery object you need to use the jQuery or $ function.
You mentioned in a comment above your teacher had you do that to fix something. I imagine it was because jQuery was not initially included so he just created the $ selector function to get you moving but I would hope he explained why he did that and how it can affect things later.
I have a project handling a library of excel files. To make it easilier for the users to visually scan them, I would like to generate preview thumbnail images of their content. Google drive does this (screenshot below) but I have no idea how.
Any ideas/suggestions on how this could be done (without using the drive API) ?
I guess this is what you need
http://github.com/lonekorean/mini-preview
DEMO
/*
* MiniPreview v0.9
*
* #author Will Boyd
* #github http://github.com/lonekorean/mini-preview
*/
(function($) {
var PREFIX = 'mini-preview';
// implemented as a jQuery plugin
$.fn.miniPreview = function(options) {
return this.each(function() {
var $this = $(this);
var miniPreview = $this.data(PREFIX);
if (miniPreview) {
miniPreview.destroy();
}
miniPreview = new MiniPreview($this, options);
miniPreview.generate();
$this.data(PREFIX, miniPreview);
});
};
var MiniPreview = function($el, options) {
this.$el = $el;
this.$el.addClass(PREFIX + '-anchor');
this.options = $.extend({}, this.defaultOptions, options);
this.counter = MiniPreview.prototype.sharedCounter++;
};
MiniPreview.prototype = {
sharedCounter: 0,
defaultOptions: {
width: 256,
height: 144,
scale: .25,
prefetch: 'pageload'
},
generate: function() {
this.createElements();
this.setPrefetch();
},
createElements: function() {
var $wrapper = $('<div>', { class: PREFIX + '-wrapper' });
var $loading = $('<div>', { class: PREFIX + '-loading' });
var $frame = $('<iframe>', { class: PREFIX + '-frame' });
var $cover = $('<div>', { class: PREFIX + '-cover' });
$wrapper.appendTo(this.$el).append($loading, $frame, $cover);
// sizing
$wrapper.css({
width: this.options.width + 'px',
height: this.options.height + 'px'
});
// scaling
var inversePercent = 100 / this.options.scale;
$frame.css({
width: inversePercent + '%',
height: inversePercent + '%',
transform: 'scale(' + this.options.scale + ')'
});
// positioning
var fontSize = parseInt(this.$el.css('font-size').replace('px', ''), 10)
var top = (this.$el.height() + fontSize) / 2;
var left = (this.$el.width() - $wrapper.outerWidth()) / 2;
$wrapper.css({
top: top + 'px',
left: left + 'px'
});
},
setPrefetch: function() {
switch (this.options.prefetch) {
case 'pageload':
this.loadPreview();
break;
case 'parenthover':
this.$el.parent().one(this.getNamespacedEvent('mouseenter'),
this.loadPreview.bind(this));
break;
case 'none':
this.$el.one(this.getNamespacedEvent('mouseenter'),
this.loadPreview.bind(this));
break;
default:
throw 'Prefetch setting not recognized: ' + this.options.prefetch;
break;
}
},
loadPreview: function() {
this.$el.find('.' + PREFIX + '-frame')
.attr('src', this.$el.attr('href'))
.on('load', function() {
// some sites don't set their background color
$(this).css('background-color', '#fff');
});
},
getNamespacedEvent: function(event) {
return event + '.' + PREFIX + '_' + this.counter;
},
destroy: function() {
this.$el.removeClass(PREFIX + '-anchor');
this.$el.parent().off(this.getNamespacedEvent('mouseenter'));
this.$el.off(this.getNamespacedEvent('mouseenter'));
this.$el.find('.' + PREFIX + '-wrapper').remove();
}
};
})(jQuery);
.mini-preview-anchor {
display: inline-block;
position: relative;
white-space: nowrap;
}
.mini-preview-wrapper {
-moz-box-sizing: content-box;
box-sizing: content-box;
position: absolute;
overflow: hidden;
z-index: -1;
opacity: 0;
margin-top: -4px;
border: solid 1px #000;
box-shadow: 4px 4px 6px rgba(0, 0, 0, .3);
transition: z-index steps(1) .3s, opacity .3s, margin-top .3s;
}
.mini-preview-anchor:hover .mini-preview-wrapper {
z-index: 2;
opacity: 1;
margin-top: 6px;
transition: opacity .3s, margin-top .3s;
}
.mini-preview-loading, .mini-preview-cover {
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 0;
}
.mini-preview-loading {
display: table;
height: 100%;
width: 100%;
font-size: 1.25rem;
text-align: center;
color: #f5ead4;
background-color: #59513f;
}
.mini-preview-loading::before {
content: 'Loading...';
display: table-cell;
text-align: center;
vertical-align: middle;
}
.mini-preview-cover {
background-color: rgba(0, 0, 0, 0); /* IE fix */
}
.mini-preview-frame {
border: none;
-webkit-transform-origin: 0 0;
transform-origin: 0 0;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>MiniPreview Demo</title>
<link href="http://fonts.googleapis.com/css?family=Roboto+Slab" rel="stylesheet">
<style>
body {
height: 100%;
margin: 0;
padding: 0 10% 40px;
font-size: 2rem;
line-height: 1.5;
font-family: 'Roboto Slab', sans-serif;
text-align: justify;
color: #59513f;
background-color: #f5ead4;
}
a {
color: #537f7c;
}
.break {
text-align: center;
}
</style>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<!-- MiniPreview stuff here -->
<link href="./jquery.minipreview.css" rel="stylesheet">
<script src="./jquery.minipreview.js"></script>
<script>
$(function() {
$('#p1 a').miniPreview({ prefetch: 'pageload' });
$('#p2 a').miniPreview({ prefetch: 'parenthover' });
$('#p3 a').miniPreview({ prefetch: 'none' });
});
</script>
</head>
<body>
<p id="p1">
This demo shows how to add live mini-previews to links on hover. Check out these links to SitePoint and A List Apart. Hover over them to see a small preview of what they point to.
</p>
<p class="break">• • •</p>
<p id="p2">
Those previews were fetched as soon as this page loaded. This is great for having the previews ready ahead of time, but can eat up extra bandwidth. As an alternative, check out these links to Abduzeedo and Smashing Magazine. These previews aren't fetched until you hover over this paragraph.
</p>
<p class="break">• • •</p>
<p id="p3">
Finally, check out these links to Daniel's blog, Joni's blog, and my blog. These previews are only fetched when needed. This saves the most bandwidth, but there will be a delay before the previews can be shown.
</p>
</body>
</html>
ORIGINAL SOURCE:
http://codepen.io/kanakiyajay/pen/NqgZjo
I just use a library to generate a PNG preview of the excel file and show it.
I use Free Spire.XLS for .NET because I'm in the .net world, but you can look at Wijmo Workbook Viewer for your Node.js needs.