Traversing through them DOM - javascript

Im having trouble trying to do the following:
When I hit the button(the first time), I want it to select the first box and then change the background to grey, and as the button is being pressed, I want it to jump to the next box and change that box into grey. Help Please!
const boxes = document.querySelector('#boxes');
const button = document.querySelector('button');
button.addEventListener('click', () => {
let firstChild = boxes.firstElementChild;
for (let i = 0; i < boxes.length; i++) {
firstChild.nextElementSibling.style.backgroundColor = 'grey';
}
})
body {
background: rgb(78, 78, 78);
}
.boxes {
height: 600px;
width: 380px;
background: rgb(236, 236, 236);
border-radius: 20px;
}
.box {
height: 100px;
background: rgb(26, 149, 187);
}
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<!-- My CSS -->
<link rel="stylesheet" href="main.css">
<title>Hello, world!</title>
</head>
<body>
<div class="container boxes mt-5">
<h1 class="text-center mb-4">App.js</h1>
<div id='boxes' class="row justify-content-around">
<div class="col-3 box "></div>
<div class="col-3 box "></div>
<div class="col-3 box "></div>
</div>
<div class="row mt-4 justify-content-around">
<div class="col-3 box "></div>
<div class="col-3 box "></div>
<div class="col-3 box "></div>
</div>
<div class="container text-center mt-4">
<button id="button" type="button" class="btn btn-warning">Submit</button>
</div>
</div>
</body>
</html>

This is one way to do it using closures:
const boxes = document.querySelector('#boxes');
const button = document.querySelector('button');
const createListener = () => {
let counter = 0
return () => {
boxes.children[counter %
boxes.children.length].style.backgroundColor = 'gray'
counter++
}
}
button.addEventListener('click', createListener())
I did not test it but it should work. If you don't understand what's going on please research on closures. It'll be very useful.

Related

How to get the color of an element which i have clicked or its background color via javascript?

I tried to use EyeDropper API but I think there are some issues on Linux because it requires me to share my screen and Although I shared, I could not get a result. I'm getting this after clicking the button. image
<!DOCTYPE html>
<html lang="en">
<head>
<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>COLOR PICKER</title>
<!-- GOOGLE FONTS -->
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Sharp:opsz,wght,FILL,GRAD#20..48,100..700,0..1,-50..200"
/>
<!-- CSS & SCRIPT -->
<link rel="stylesheet" href="style.css" />
<script defer src="./script.js"></script>
</head>
<body class="grid pi-cent">
<div class="container flex-col">
<header class="flex jc-cnt ai-cnt">
<button class="pick-btn">Pick Color</button>
</header>
<article class="flex jc-sb">
<p>Picked Color<s class="plural">s</s></p>
Clear All
</article>
<ul class="grid">
<li class="flex">
<div
class="color"
style="--bg: #000000; width: 15px; height: 15px"
></div>
<p class="clr-code">#0000</p>
</li>
</ul>
</div>
<script>
const pickBtn = document.querySelector(".pick-btn");
const pickColor = async (e) => {
try {
const eDrop = new window.EyeDropper();
const resp = await eDrop.open();
console.log(resp);
} catch (err) {
console.log(err);
}
};
pickBtn.addEventListener("click", pickColor);
</script>
</body>
</html>
You forgot to add click event to the button.
const button = document.querySelector('button');
button.addEventListener('click', () => {
if (!window.EyeDropper) {
resultElement.textContent = 'Your browser does not support the EyeDropper API';
return;
}
const eyeDropper = new EyeDropper();
eyeDropper.open().then((result) => {
console.log(result.sRGBHex);
}).catch((e) => {
console.log(e)
});
})
.green,
.blue,
.red {
cursor: pointer;
margin-bottom: 1rem;
}
.green {
color: green;
}
.blue {
color: blue;
}
.red {
color: red;
}
<div class="green">Green color</div>
<div class="blue">Blue color</div>
<div class="red">Red color</div>
<button>Pick color</button>
As #ourmaninamsterdam mentioned the EyeDropper is experimental and only supported in chromium browsers like edge, chrome, opera
Browser compatibility

How can I turn the array of numbers into a list that only appears when the plus icon is clicked?

I have returned an array of results and turned it into an average, but below the average, I wish to reveal each individual test result of the student when the grey plus icon is clicked.
like the link below shows.
https://storage.googleapis.com/hatchways-app.appspot.com/assessments/data/frontend/f-1/735fae21-9b8d-4431-8978-5098a2217fd2/part4.webm
any help is appreciated
const apiInfo = $('.info');
const avg = (arr) => arr.reduce((acc, x) => acc + x, 0) / arr.length;
const nameSeachInput = $('#nameSearch');
nameSeachInput.on('input',
function() {
apiInfo.empty();
allStudents.filter(student => student.firstName.toLowerCase().includes(this.value.toLowerCase()) || student.lastName.toLowerCase().includes(this.value.toLowerCase())).forEach(student => {
if (student.id.includes('')) {
renderStudentInfo(student, apiInfo);
}
});
});
let allStudents;
const renderStudentInfo = (student, $target) => {
const fullName = student.firstName + ' ' + student.lastName,
average = avg(student.grades.map(grade => parseInt(grade, 10)));
$target.append($(`
<div class="infoB">
<img class="pPic float-left m-3"
src="${student.pic}" alt="profile pic" />
<h4 class="title">${fullName}<h4>
<p class="mb-1 stats">Email: ${student.email}</p>
<p class="mb-1 stats">Comapny: ${student.company}</p>
<p class="mb-1 stats">Skill: ${student.skill}</p>
<p class="mb-1 stats">Average: ${average.toFixed(2)}%</p>
<p class="mb-1 d-none" id="stats"> ${student.grades}%<p>
<i class="mb-5 fa fa-plus float-right"></i>
</div>
`));
};
$( "#plus" ).click(function() {
$( '#stats' ).toggleClass( "d-none" );
});
const init = () => {
$.ajax({
url: 'https://api.hatchways.io/assessment/students',
method: 'GET',
}).then(({
students
}) => {
allStudents = students;
students.forEach((student) => {
if (student.id.includes('')) {
renderStudentInfo(student, apiInfo);
}
});
});
}
init();
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<link
rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"
integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z"
crossorigin="anonymous"
/>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="input mt-5 mx-5">
<input
id="nameSearch"
type="text"
class="form-control"
placeholder="Search by name"
aria-label="Search by name"
aria-describedby="basic-addon1"
/>
</div>
<div class="input mb-0 mt-2 mx-5">
<input
id="tagSearch"
type="text"
class="form-control"
placeholder="Search tags"
aria-label="Search tags"
aria-describedby="basic-addon1"
/>
</div>
<div class="container mt-0">
<div class="info card scroll shadow p-3 mb-5 bg-white rounded"></div>
<span class="glyphicon glyphicon-plus"></span>
</div>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
<script src="index.js"></script>
</body>
</html>
body{
background-color: rgb(243, 240, 240);
}
img{
border-radius: 50%;
border: solid rgb(156, 148, 148) 1px;
min-width: 130px;
}
.infoB{
border-bottom: solid grey 1px;
}
.stats{
color: grey;
margin-left: 175px;
}
.title{
font-size: 50px;
}
.card {
margin-top: 100px;
}
.scroll {
max-height: 575px;
overflow-y: auto;
}
.fa-plus{
color: grey;
font-size: 50px;
}
There are several ways to do it, but the simplest way would be to have the individual numbers in a container that you show/hide every time the plus icon is clicked. You may also want to swap the plus icon image for a minus icon on each toggle.
I've implemented a basic version here: https://jsfiddle.net/r63ctej0/
Essentially, in the above implementation, I've put the numbers in a <ul> tag and I give this list an id {fullName}_numbers so that each card has a unique id.
Then I create a toggleNumbers(id) function that takes that id and switches its display state.
Lastly, I added onclick=toggleName('{fullName}_numbers') to the plus icon

How can I filter the results by first and last name?

I need the search bars to filter out the results by first and last name
as shown in this link,
https://storage.googleapis.com/hatchways-app.appspot.com/assessments/data/frontend/f-1/735fae21-9b8d-4431-8978-5098a2217fd2/part3.webm
as well as the plus button to expand the percentages back to a list instead of an average.
https://storage.googleapis.com/hatchways-app.appspot.com/assessments/data/frontend/f-1/735fae21-9b8d-4431-8978-5098a2217fd2/part4.webm
as shown here.
As well as an input field to add tags to each student for the second search bar to find.
https://storage.googleapis.com/hatchways-app.appspot.com/assessments/data/frontend/f-1/735fae21-9b8d-4431-8978-5098a2217fd2/part5.webm
as shown here.
I am very stumped on this problem. any assistance would be welcome.
thank you!
const apiInfo = $('.info');
const avg = (arr) => arr.reduce((acc, x) => acc + x, 0) / arr.length;
const renderStudentInfo = (student, $target) => {
const fullName = student.firstName + ' ' + student.lastName,
average = avg(student.grades.map(grade => parseInt(grade, 10)));
$target.append($(`
<div class="infoB">
<img class="pPic float-left m-3"
src="${student.pic}" alt="profile pic" />
<h4 class="title">${fullName}<h4>
<p class="mb-1 stats">Email: ${student.email}</p>
<p class="mb-1 stats">Comapny: ${student.company}</p>
<p class="mb-1 stats">Skill: ${student.skill}</p>
<p class="mb-1 stats">Average: ${average.toFixed(2)}%</p>
<i class="mb-5 fa fa-plus float-right"></i>
</div>
`));
};
const init = () => {
$.ajax({
url: 'https://api.hatchways.io/assessment/students',
method: 'GET',
}).then(({ students }) => {
students.forEach((student) => {
if (student.id.includes('')) {
renderStudentInfo(student, apiInfo);
}
});
});
}
init();
body{
background-color: rgb(243, 240, 240);
}
img{
border-radius: 50%;
border: solid rgb(156, 148, 148) 1px;
min-width: 130px;
}
.infoB{
border-bottom: solid grey 1px;
}
.stats{
color: grey;
margin-left: 175px;
}
.title{
font-size: 50px;
}
.card {
margin-top: 100px;
}
.scroll {
max-height: 575px;
overflow-y: auto;
}
.fa-plus{
color: grey;
font-size: 50px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<link
rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"
integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z"
crossorigin="anonymous"
/>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="input mt-5 mx-5">
<input
id="nameSearch"
type="text"
class="form-control"
placeholder="Search by name"
aria-label="Search by name"
aria-describedby="basic-addon1"
/>
</div>
<div class="input mb-0 mt-2 mx-5">
<input
id="tagSearch"
type="text"
class="form-control"
placeholder="Search tags"
aria-label="Search tags"
aria-describedby="basic-addon1"
/>
</div>
<div class="container mt-0">
<div class="info card scroll shadow p-3 mb-5 bg-white rounded"></div>
<span class="glyphicon glyphicon-plus"></span>
</div>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
<script src="index.js"></script>
</body>
</html>

OnMouseEvents Issue

I am new to coding and am having trouble with the onmouseover and onmouseout events. I am trying to make it so that when my mouse rolls over an element in my navbar it will turn pink. The issue is that everything that I have found uses Jquery and not Javascript. According to a debugger navBarTextReaction is not defined but then how do I go about defining it?
Do I have to set something equal to the function? I'm so confused. Help Please!
For some reason it is working here and it still isn't working when I load it in the browser.
navBarVar = document.getElementById("navBar").classList;
function navBarTextReaction() {
if(navBarVar.contains("makeWhite")) {
navBarVar.remove("makeWhite");
}
else {
navBarVar.add("makeWhite");
}
if(navBarVar.contains("makePink")){
navBarVar.remove("makePink");
}
else {
navBarVar.add("makePink");
}
}
.background {
background: #4F4F52;
}
.navbar1 {
background: #282727;
shadow: 1em 1em #87B4CB;
font-family: Patrick Hand SC;
text-shadow: .01em .01em #171717;
font-size: 1.5em;
text-align: center;
}
.makeWhite {
color: #FFFFFF;
font-weight: bold;
}
.makePink {
color: #FBEBEB;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link rel="stylesheet" type="text/css" href="styles.css">
<link href="https://fonts.googleapis.com/css?family=Cardo|Great+Vibes|Patrick+Hand+SC|Quattrocento" rel="stylesheet">
<script src="script.js"></script>
</head>
<body>
<div class = "background">
<div class = "container-fluid">
<div class = "row">
<div onmouseover = "navBarTextReaction()" onmouseout = "navBarTextReaction()" id = "navBar" class = "navbar1 col-sm-3 makeWhite"> Home Page </div>
<div id = "navBar" class = "navbar1 col-sm-3 makeWhite"> Chord Leading Chart </div>
<div id = "navBar" class = "navbar1 col-sm-3 makeWhite"> Note Game </div>
<div id = "navBar" class = "navbar1 col-sm-3 makeWhite"> Circle of Fifths </div>
</div>
</div>
</div>
</body>
</html>
Lose all the duplicate id attributes and just use CSS classes and the :hover pseudo-class
.navbar1 {
color: #fff;
font-weight: bold;
}
.navbar1:hover {
color: #FBEBEB;
font-weight: normal;
}
<div class="navbar1 col-sm-3">Home Page</div>
<div class="navbar1 col-sm-3">Chord Leading Chart</div>
<div class="navbar1 col-sm-3">Note Game</div>
<div class="navbar1 col-sm-3">Circle of Fifths</div>
<div onmouseover = "navBarTextReaction()" onmouseout = "navBarTextReaction()" id = "navBar" class = "navbar1 col-sm-3 makeWhite"> Home Page </div>
Add () after function names in your HTML and I also corrected the code to use the correct function name.
navBarVar = document.getElementById("navBar").classList;
function navBarTextReaction() {
if(navBarVar.contains("makeWhite")) {
navBarVar.remove("makeWhite");
}
else {
navBarVar.add("makeWhite");
}
if(navBarVar.contains("makePink")){
navBarVar.remove("makePink");
}
else {
navBarVar.add("makePink");
}
}
.background {
background: #4F4F52;
}
.navbar1 {
background: #282727;
shadow: 1em 1em #87B4CB;
font-family: Patrick Hand SC;
text-shadow: .01em .01em #171717;
font-size: 1.5em;
text-align: center;
}
.makeWhite {
color: #FFFFFF;
font-weight: bold;
}
.makePink {
color: #FBEBEB;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link rel="stylesheet" type="text/css" href="styles.css">
<link href="https://fonts.googleapis.com/css?family=Cardo|Great+Vibes|Patrick+Hand+SC|Quattrocento" rel="stylesheet">
<script src="script.js"></script>
</head>
<body>
<div class = "background">
<div class = "container-fluid">
<div class = "row">
<div onmouseover = "navBarTextReaction()" onmouseout = "navBarTextReaction()" id = "navBar" class = "navbar1 col-sm-3 makeWhite"> Home Page </div>
<div id = "navBar" class = "navbar1 col-sm-3 makeWhite"> Chord Leading Chart </div>
<div id = "navBar" class = "navbar1 col-sm-3 makeWhite"> Note Game </div>
<div id = "navBar" class = "navbar1 col-sm-3 makeWhite"> Circle of Fifths </div>
</div>
</div>
</div>
</body>
</html>
navBarTextReation =>navBarTextReaction()

Quick button pressing for iOS web app

I couldn't find anything on how fast a button was pressed, so I hope this is OK. This is for a web-application.
For those of you who have an iPhone (or most modern smartphones now), if you have the pin styled unlock screen when you unlock your phone, the smartphone recognizes every touch you do, as quick as you do it.
The same is with a website, if you click on buttons quickly, it registers every click you do as soon as you do it.
However, I am having a problem crossing the two over.
I have a 'pin' styled login where the pin is just 1234 for test purposes. I want it so that someone can use it as a web-app and they have their unique pin to sign in quickly. However, if I try to put in 1234 quickly, it only registers 1 and 4 or sometimes 1 and 3 depending on how slow I do it. If I take my time and do it, then I can get all 4, but doing it quick is where my problem lies.
Overall question:
Is there any way for a web-app to register quick finger presses on smartphones (but primarily iOS?)
Code
HTML
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta content="yes" name="apple-mobile-web-app-capable">
<meta name="format-detection" content="telephone=no">
<meta name="apple-mobile-web-app-capable" content="yes" />
<title>Pin</title>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="style.css">
<script src='http://code.jquery.com/jquery.min.js'></script>
<!-- Latest compiled and minified JavaScript -->
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
</head>
<body>
<div class='container'>
<div class='row text-center'>
<div class='col-xs-12'>
<div class='small-circle a1'></div>
<div class='small-circle a2'></div>
<div class='small-circle a3'></div>
<div class='small-circle a4'></div>
</div>
<div class='col-xs-4'>
<div class='main num hover' data-number="1"></div>
</div>
<div class='col-xs-4'>
<div class='main num hover' data-number="2"></div>
</div>
<div class='col-xs-4'>
<div class='main num hover' data-number="3"></div>
</div>
<div class='col-xs-4'>
<div class='main num hover' data-number="4"></div>
</div>
<div class='col-xs-4'>
<div class='main num hover' data-number="5"></div>
</div>
<div class='col-xs-4'>
<div class='main num hover' data-number="6"></div>
</div>
<div class='col-xs-4'>
<div class='main num hover' data-number="7"></div>
</div>
<div class='col-xs-4'>
<div class='main num hover' data-number="8"></div>
</div>
<div class='col-xs-4'>
<div class='main num hover' data-number="9"></div>
</div>
<div class='clearfix'></div>
<div class='col-xs-12'>
<div class='bottom_main num hover' data-number="0"></div>
</div>
</div>
</div>
</div>
<script src='script.js'></script>
</body>
</html>
CSS
body{
counter-reset: amount;
}
.num{
width:75px;
height:75px;
border:1px solid #000;
border-radius:100%;
line-height:75px;
margin:auto;
margin-top:30px;
counter-increment:amount;
}
.main:before{
content:counter(amount);
}
.bottom_main:before{
content:'0';
}
.active{
background:blue !important;
}
.small-circle{
display:inline-block;
width:20px;
height:20px;
border:1px solid #000;
border-radius:100%;
margin-top:20px;
}
jQuery
$(document).ready(function() {
var array = [];
var pin = "1234";
var a = 0;
$('.num').click(function(){
a++;
if (array.length <= 3)
{
array.push($(this).attr('data-number'));
}
});
setInterval(function() {
$('.a'+a).addClass('active');
if (array.length >= 4)
{
if (array.join("") === pin)
{
$('.small-circle').css('background','green');
$('.small-circle').removeClass('active');
}
else
{
array = [];
a = 0;
$('.small-circle').css('background','red');
$('.small-circle').removeClass('active');
}
}
}, 100);
});
And a jsFiddle for quick checking, although I'm not sure that it will work on an iPhone.
A click performed by the user takes 300ms to dispatch an event. This is just to detect possible doubleclicks.
You can prevent this by listening to touchstart-touchend and trigger them as a click without delay.
But instead of building your own start-end detections, this is already done well by Financial Times in their web app. See: https://github.com/ftlabs/fastclick for details.

Categories

Resources