So I thought it would be pretty simple to implement an if statement to have an element appear or disappear at the click of a button.
After a couple of hours now, I have not gotten further than getting the element to disappear. It registers the second click(tested with a console.log), but the display property does not change back to 'flex'.
I've also already tried different variations of 'getElementById' and 'querySelector' during my sentence.
const edit = document.getElementById('edit-btn');
const fill = document.querySelector('#filler');
edit.addEventListener('click', popInOut(fill))
function popInOut(e){
if(e.style.display=='flex'){
e.style.display='none'
}else if(e.style.display=='none'){
e.style.display='flex'
}
}
The 'filler' element is a bootstrap column with this styling.
#filler{
display:flex;
flex-direction: column;
background-color: #1c1f22;
position:absolute;
top:40%;
height:50%;
}
hey it is your query selector which is causing the problem
and also you can use your filler directly in function because its declared
in global scope
const edit = document.getElementById("edit-btn");
const filler = document.getElementById("filler");
edit.addEventListener("click", fix);
function fix() {
if (filler.style.display === "none") {
filler.style.display = "flex";
} else {
filler.style.display = "none";
}
}
body {
font-family: sans-serif;
}
#filler {
display: flex;
/* flex-direction: column; */
background-color: whitesmoke;
position: absolute;
top: 30%;
left: 20%;
height: 50%;
gap: 1rem;
}
#filler div:nth-child(even) {
background: turquoise;
}
#filler div:nth-child(odd) {
background: yellowgreen;
}
<!DOCTYPE html>
<html>
<head>
<title>Parcel Sandbox</title>
<meta charset="UTF-8" />
<link href="style.css"/>
</head>
<body>
<div id="app">
<div id="filler">
<div>Hare krishna</div>
<div>Radhe Shyam</div>
<div>Sita Ram</div>
</div>
<button id="edit-btn">Edit</button>
</div>
<script src="index.js"></script>
</body>
</html>
Related
The below code ALMOST works and I think I'm close yet quite far away from getting it to work properly. The problem is, the way the handlePinch function is set up. What actually happens when the user pinches to zoom a bit, is the square starts to accelerate. The more the user pinches, the faster the square zooms.
How can this be implemented that each time the user pinches to zoom, it incrementally scales, i.e. picking up where it left off without exceeding the max scale?
I'm stuck on this for two days and there doesn't seem to be any formula to show how something like this works. Note, I know there are libraries for this, I want to know how this works with vanilla js
const box = document.querySelector('.box')
function updateCss(scale) {
box.style.transform = `scale(${scale})`
}
let lastScale
let currentScale
let isAlreadyScaled = false
const minScale = 1
const maxScale = 1.8
function handlePinch(e) {
e.preventDefault()
const isZooming = e.scale > 1
if (isZooming) {
if (!isAlreadyScaled) {
lastScale = Math.min(minScale * e.scale, maxScale)
isAlreadyScaled = true
} else {
lastScale = Math.min(minScale * (lastScale * e.scale), maxScale)
}
}
updateCss(lastScale)
}
box.addEventListener('touchstart', e => {
if (e.touches.length === 2) {
handlePinch(e)
}
})
box.addEventListener('touchmove', e => {
if (e.touches.length === 2) {
handlePinch(e)
}
})
* {
box-sizing: border-box;
}
body {
padding: 0;
margin: 0;
}
.wrapper {
height: 400px;
width: 100%;
top: 0;
left: 0;
position: relative;
margin: 24px;
}
.scale-container {
height: 100%;
width: 100%;
position: absolute;
background: #eee;
display: flex;
align-items: center;
justify-content: center;
}
.box {
height: 200px;
width: 200px;
background: pink;
position: absolute;
}
<!DOCTYPE html>
<html lang="en">
<head>
<title>Home</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
</head>
<body>
<div class="wrapper">
<div class="scale-container">
<div class="box"></div>
</div>
</div>
</body>
</html>
I made grid 16x16 with borders for each cell, then i added a button to toggle on/off borders of those cells, but it also changes overall size of my grid. how do i prevent this?
in the future i want to implement "change size" button that will increase numbers of cells but not change grid size. I'm sure i need to define grid size somehow but i don know how. Whatever i try either messes up grid size or cell size or both
here is my code
const grid = document.getElementById('grid');
const size = document.getElementById('size');
const eraser = document.getElementById('eraser');
const color = document.getElementById('color');
const gridBorder = document.getElementById('grid-borders');
// grid
function makeGrid(number) {
grid.style.gridTemplateColumns = `repeat(${number}, 1fr)`;
grid.style.gridTemplateRows = `repeat(${number}, 1fr)`;
for (let i = 0; i < number * number; i++) {
let cell = document.createElement('div');
grid.appendChild(cell).setAttribute('id', 'box');
}
}
makeGrid(16);
// drawing on hover
color.addEventListener('click', function () {
grid.addEventListener('mouseover', function (e) {
e.target.style.backgroundColor = 'black';
});
});
// erase functionality
eraser.addEventListener('click', function () {
grid.addEventListener('mouseover', function (e) {
e.target.style.backgroundColor = 'white';
});
});
// gird borders
const allBoxes = document.querySelectorAll('#box');
gridBorder.addEventListener('click', function () {
for (let i = 0; i < allBoxes.length; i++) {
if (allBoxes[i].style.border === '1px solid black') {
allBoxes[i].style.border = 'none';
} else {
allBoxes[i].style.border = '1px solid black';
}
}
});
body {
height: 100vh;
}
#grid {
display: grid;
justify-content: center;
border: 1px solid #ccc;
}
#box {
padding: 1em;
border: 1px solid black;
}
#title {
display: flex;
align-items: flex-end;
justify-content: center;
height: 230px;
}
#container {
display: flex;
height: 60%;
width: 1204px;
align-items: flex-start;
justify-content: flex-end;
gap: 20px;
}
#menu {
display: flex;
flex-direction: column;
gap: 10px;
}
<!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>Etch-a-Sketch</title>
<link rel="stylesheet" href="style.css" />
<script src="script.js" defer></script>
</head>
<body>
<div id="title">
<h1>Etch-a-Sketch</h1>
</div>
<main id="container">
<div id="menu">
<button id="size">Canvas Size</button>
<button id="color">Color</button>
<button id="eraser">Eraser</button>
<button id="grid-borders">Grid Borders</button>
</div>
<div id="grid"></div>
</main>
</body>
</html>
You can use outline instead of border. Change your CSS box definition and remove the border there as it will be used to query your box class.
NOTE: I added a box and border class initially when creating your boxes as querying multiple elements should be targeted using a class and not a unique ID.
Now that you have the class targeted, you can simple toggle classes with the click event and use css to add/remove -> toggle the outlines state using its corresponding toggled class style.
I also added a conditional to check which event is being fired in your hover state listener, this will prevent the grid from being toggled so only its children, then boxes are toggled.
Let me know if you have any issues with the code or if this isn't working for your needs and I can either remove this answer or edit to tailor any other issues you may be having.
const grid = document.getElementById('grid');
const size = document.getElementById('size');
const eraser = document.getElementById('eraser');
const color = document.getElementById('color');
const gridBorder = document.getElementById('grid-borders');
// grid
function makeGrid(number) {
grid.style.gridTemplateColumns = `repeat(${number}, 1fr)`;
grid.style.gridTemplateRows = `repeat(${number}, 1fr)`;
for (let i = 0; i < number * number; i++) {
let cell = document.createElement('div');
grid.appendChild(cell).id = 'box';
// added class border and box
cell.classList.add('border'); //--> border will be used to toggle outline in css
cell.classList.add('box') //--> box used to query all the dynamically created box elements
}
}
makeGrid(16);
// drawing on hover
color.addEventListener('click', function() {
grid.addEventListener('mouseover', function(e) {
// make sure event.target is not the grid itself
e.target !== grid ? e.target.style.backgroundColor = 'black' : null;
});
});
// erase functionality
eraser.addEventListener('click', function() {
grid.addEventListener('mouseover', function(e) {
// make sure event.target is not the grid itself
e.target !== grid ? e.target.style.backgroundColor = 'white' : null;
});
});
// grid borders
const allBoxes = document.querySelectorAll('.box');
gridBorder.addEventListener('click', function() {
// added a forEach method to toggle classes in order to track click state and style using css styling
allBoxes.forEach(box => {
box.classList.toggle('no-border');
box.classList.toggle('border');
})
});
body {
height: 100vh;
}
#grid {
display: grid;
justify-content: center;
border: 1px solid #ccc;
}
.box {
/* removed the initial outline &/or border property here so it can be added and removed (toggled) using JS el.classList.toggle */
padding: 1em;
}
#title {
display: flex;
align-items: flex-end;
justify-content: center;
height: 230px;
}
#container {
display: flex;
height: 60%;
width: 1204px;
align-items: flex-start;
justify-content: flex-end;
gap: 20px;
}
#menu {
display: flex;
flex-direction: column;
gap: 10px;
}
/* added the following classes to be toggled using JS depending on state of gridBorders button */
.border {
outline: 1px solid black;
}
.no-border {
outline: none;
}
.black-bg {
background: black;
}
.white-bg {
background: white;
}
<!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>Etch-a-Sketch</title>
<link rel="stylesheet" href="style.css" />
<script src="script.js" defer></script>
</head>
<body>
<div id="title">
<h1>Etch-a-Sketch</h1>
</div>
<main id="container">
<div id="menu">
<button id="size">Canvas Size</button>
<button id="color">Color</button>
<button id="eraser">Eraser</button>
<button id="grid-borders">Grid Borders</button>
</div>
<div id="grid"></div>
</main>
</body>
</html>
Instead of using an actual border around grid items, use grid-gap prop along with background-color of the grid itself:
#grid {
...
grid-gap: 1px;
background-color: black;
}
Refer to the documentation for more info.
I am trying to create a code that works when you put it on the google search bar, that is a must and i created a div you can edit, also i created a reset button that replaces the content on the div with the default text, but when I try to press ctrl + z it does not go back, and i don't know how to make it work
-I cannot get rid of the: data:text/html, part because it wouldn't work in the search bar for google
-i do have to have all the code types in just one document, because i have to copy paste it all on the google search bar
function reset() {
div_1.innerHTML = '<p> Default text<p>';
}
.div_1 {
display: block;
background-color: rgba(255, 0, 0, 0.5);
height: 80%;
position: relative;
width: 60%;
position-left: 100px;
}
<div contenteditable="true" class="div_1" id="div_1">
<p> Default text<p>
</div>
<button onclick="reset()">reset</button>
function reset() {
div_1.innerHTML = ''; //set the inner HTML to empty string
}
.div_1 {
display: block;
background-color: rgba(255, 0, 0, 0.5);
height: 80%;
position: relative;
width: 60%;
position-left: 100px;
}
<div contenteditable="true" class="div_1" id="div_1">
<p> Default text<p>
</div>
<button onclick="reset()">reset</button>
I think you are trying to make the form empty when you press reset button.
So you have to change the inner HTML to an empty string in order to do that.
I hope it helped
i was able to find an option with the memento pattern and creating an event for the ctrl + z input on the keyboard
function copy(){
inp1.select();
navigator.clipboard.writeText(inp1.value);
ctn.innerHTML = inp1.value;
}
var mementos = [];
function reset() {
mementos.push(document.getElementById('div_1').innerHTML);
div_1.innerHTML= '<p>caller name: </p><p>reason for the call:</p><p>CTN: <div class="ctn" id="ctn"></p><p><br></p><p></p>';
}
document.addEventListener('keydown', function(event) {
if (event.ctrlKey && event.key === 'z') {
var lastMemento = mementos.pop();
div_1.innerHTML = lastMemento;
}
});
function undo() {
var lastMemento = mementos.pop();
div_1.innerHTML = lastMemento;
}
input{
width:200px;
height: 100%;
}
.div_1{
display: block;
background-color:rgba(255, 0, 0, 0.5);
height:400px;
position: relative;
width: 400px;
padding-left: 2px;
}
button{
position: relative;
}
.ctn {
display: inline;
background-color: red;
}
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Notes</title>
</head>
<body>
<link rel="stylesheet" href="syles.css">
<input placeholder="(000)-000-0000" maxlength="10" id="inp1">
<button onclick="reset()">reset</button>
<button onclick="copy()">copy</button>
<button onclick="undo()">Undo</button>
<div contenteditable="true"class="div_1" id="div_1">
<p>caller name: </p><p>reason for the call:</p><p>CTN: <div class="ctn" id="ctn"></p><p><br></p><p></p>
</div>
</body>
</html>
I'm learning JS by following Wes Bos's class. I'm trying to select buttons and display information every time the user clicks on them. So I add an event listener, however, the fallback function seems to be executed automatically when it is located inside the event listener. I don't understand why 'hello' is displayed automatically while the function youClickTheButton is executed only when the user clicks on a button (see the below code).
Why does this happen?
const myButtons = document.querySelectorAll('.cards button');
const modalOuter = document.querySelector('.modal-outer');
function youClickTheButton(event) {
console.log(event);
modalOuter.classList.add('open');
}
myButtons.forEach(item => item.addEventListener('click', youClickTheButton));
myButtons.forEach(item => item.addEventListener('click', console.log('hello')));
// whenever you click on the button it will open a pop up with a picture with the description
// whenever you click outside of this pop up it should close itself use .closest()
// populate the modal with name and description of the card so you don't have to modify the .html file
// you could also close it by simply pressing escape
const myButtons = document.querySelectorAll('.cards button');
const modalOuter = document.querySelector('.modal-outer');
function youClickTheButton(event) {
console.log(event);
modalOuter.classList.add('open');
}
myButtons.forEach(item => item.addEventListener('click', youClickTheButton));
myButtons.forEach(item => item.addEventListener('click', console.log('hello')));
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title></title>
<link rel="stylesheet" href="../../base.css">
</head>
<body>
<div class="cards">
<div class="card number1" data-description="Wes is cool">
<img src="https://picsum.photos/200?random=1" alt="Wes Bos">
<h2>Wes Bos</h2>
<button>Learn more →</button>
</div>
<div class="card number2" data-description="Scott is neat!">
<img src="https://picsum.photos/200?random=2" alt="Wes Bos">
<h2>Scott Tolinski</h2>
<button>Learn more →</button>
</div>
<div class="card number3" data-description="Kait is beautiful!">
<img src="https://picsum.photos/200?random=3" alt="Wes Bos">
<h2>Kait Bos</h2>
<button>Learn more →</button>
</div>
<div class="card number4" data-description="Snickers is a dog!">
<img src="https://picsum.photos/200?random=4" alt="Wes Bos">
<h2>Snickers the dog</h2>
<button>Learn more →</button>
</div>
</div>
<div class="modal-outer ">
<div class="modal-inner ">
<p>You clicked on the 1st one</p>
</div>
</div>
<style>
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
grid-gap: 20px;
padding: 2rem;
}
.card {
background: white;
padding: 1rem;
border-radius: 2px;
}
.card img {
width: 100%;
}
.card h2 {
color: black;
}
.modal-outer {
display: grid;
background: hsla(50, 100%, 50%, 0.7);
position: fixed;
height: 100vh;
width: 100vw;
top: 0;
left: 0;
justify-content: center;
align-items: center;
/* Hide this modal until we need it */
opacity: 0;
pointer-events: none;
transition: opacity 0.2s;
}
.modal-outer img {
width: 100%;
}
.modal-outer.open {
opacity: 1;
pointer-events: all;
}
.modal-inner {
max-width: 600px;
min-width: 400px;
padding: 2rem;
border-radius: 5px;
min-height: 200px;
background: white;
transform: translateY(-200%);
transition: transform 2s;
}
.modal-outer.open .modal-inner {
transform: translateY(0);
}
</style>
<script src="./click-outside_5.js"></script>
</body>
</html>
Check the difference between your two item.addEventListener()s. In the first one, you pass down a function, while in the second one, you call one (no parentheses vs. parentheses).
If you pass down a callback function (i.e. first case), you don't invoke it immediately, you just say that "Here is this function I created, run it every time someone clicks on any of these buttons."
If you want to log from your second function, you need to pass a function, not the result of the function:
myButtons.forEach(item => item.addEventListener('click', () => console.log('hello')))
// OR
function logHello() {
return console.log('hello')
}
myButtons.forEach(item => item.addEventListener('click', logHello));
You can read more about it on MDN.
Anyway, you should not loop over the buttons twice, but I think you're just testing things out at the moment. console.log('hello') could be in your youClickTheButton() function.
I am working on a project, and cant figure out how to hide my welcome2 and welcome2-0 html code, then once the button is pressed show that information. im new with jquery, and am really confused tried looking this stuff up and still have little idea on how to fix this issue. i appreciate any help or input guys, sorry if anything poorly formatted.
var name ;
var nameFormat=true;
function submission() {
var name = document.getElementById("textbox").value;
if (name.length > 0) {
alert("Welcome "+name);
$("#name").fadeOut(1000);
$("#welcome").fadeOut(1000);
}
else{
nameFormat==false;
alert("Please enter the name again");
}
}
#welcome{
top:30px;
left: 30px;
color: antiquewhite;
border: 2px solid blue;
background: blue;
padding: 25px;
}
#name{
top:30px;
left: 500px;
color: antiquewhite;
background: blue;
border: 25px solid blue;
}
body {
background-color: lightblue;
}
#welcome2{
position: relative;
top:30px;
left: 30px;
color: antiquewhite;
border: 2px solid blue;
background: blue;
padding: 25px;
}
HTML
<html lang="en">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Welcome!</title>
<link rel="stylesheet" href="includes/styles1.css" type="text/css" media="screen" />
</head>
<p>
<body>
<div id="welcome"><b>Welcome to the Myanmar Trivia Quiz</b><br> please enter your name and click on "Begin Quiz" to start</div>
<div id ="name"><b>Name:</b>
<input type="text" id="textbox">
<button id=”myButton” type="button" onclick="submission()" >submit</button>
</p>
<div id="welcome2">Myanmar Trivia Quiz </div>
<div id="welcome2-0">Test your Demographic Knowledge<br>--------------------------------------------------------------------------------------</div>
</div>
</body>
<script src="includes/project.js"></script>
</html>
3 things:
Your HTML was malformed
You need to set display: none on the css
for what you want to be hidden at the start
You need to call fadeIn
(or show) on the element AFTER fadeOut (or hide) has finished, you
can do that using promises and the fadeIn callback function
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
http://api.jquery.com/fadein/
var name ;
var nameFormat=true;
function submission() {
var name = document.getElementById("textbox").value;
if (name.length > 0) {
alert("Welcome "+name);
fadeOutWelcome().then(() => fadeInWelcome());
}
else{
nameFormat==false;
alert("Please enter the name again");
}
}
const fadeOutWelcome = () => {
return new Promise((resolve, reject) => {
$("#name").fadeOut(1000, () => resolve());
$("#welcome").fadeOut(1000);
});
}
const fadeInWelcome = () => {
$("#welcome2").fadeIn(1000);
$("#welcome2-0").fadeIn(1000);
}
#welcome{
top:30px;
left: 30px;
color: antiquewhite;
border: 2px solid blue;
background: blue;
padding: 25px;
}
#name{
top:30px;
left: 500px;
color: antiquewhite;
background: blue;
border: 25px solid blue;
}
body {
background-color: lightblue;
}
#welcome2{
display: none;
position: relative;
top:30px;
left: 30px;
color: antiquewhite;
border: 2px solid blue;
background: blue;
padding: 25px;
}
HTML
<html lang="en">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Welcome!</title>
<link rel="stylesheet" href="includes/styles1.css" type="text/css" media="screen" />
</head>
<p>
<body>
<div id="welcome"><b>Welcome to the Myanmar Trivia Quiz</b><br> please enter your name and click on "Begin Quiz" to start</div>
<div id ="name"><b>Name:</b>
<input type="text" id="textbox">
<button id=”myButton” type="button" onclick="submission()" >submit</button>
</p>
</div>
<div id="welcome2">Myanmar Trivia Quiz
<div id="welcome2-0">Test your Demographic Knowledge<br>--------------------------------------------------------------------------------------</div>
</div>
</body>
<script src="includes/project.js"></script>
</html>
A few things:
Javascript is case-sensitive, so true is a reserved word, True is not. So instead of var nameFormat=True , you should do: var nameFormat= true .
Then, you're saying you want to hide welcome2 and welcome2-0 divs, but in your javascript code you're not doing this. If you want do this, do the following:
$("#welcome2").hide();
$("#welcome2-0").hide();
// or
$("#welcome2").fadeOut(100);
$("#welcome2-0").fadeOut(100);
There is another issue in your else block: you're doing nameFormat==false , which is just comparing if nameFormat is false. If you want to assign false to nameFormat variable, do this:
nameFormat = false;
Include the .hide() at the beginning of your javascript code (so that it executes at the very beginning) which would hide those 2 divs.
Then when the button is pressed, use .show() to show those 2 divs again.
Also, where you had nameFormat == false;, you need to change that to nameFormat = false;. == is the comparison operator, so it would look at that and say "Oh nameFormat is not false", and move on. If you wanted to make nameFormat be false (which I assume you did), you must use the assignment operator (which is =)
var name;
var nameFormat = true;
$("#welcome2").hide();
$("#welcome2-0").hide();
function submission() {
var name = document.getElementById("textbox").value;
if (name.length > 0) {
alert("Welcome " + name);
$("#name").fadeOut(1000);
$("#welcome").fadeOut(1000);
$("#welcome2").show();
$("#welcome2-0").show();
} else {
nameFormat == false;
alert("Please enter the name again");
}
}
#welcome {
top: 30px;
left: 30px;
color: antiquewhite;
border: 2px solid blue;
background: blue;
padding: 25px;
}
#name {
top: 30px;
left: 500px;
color: antiquewhite;
background: blue;
border: 25px solid blue;
}
body {
background-color: lightblue;
}
#welcome2 {
position: relative;
top: 30px;
left: 30px;
color: antiquewhite;
border: 2px solid blue;
background: blue;
padding: 25px;
}
HTML
<html lang="en">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Welcome!</title>
<link rel="stylesheet" href="includes/styles1.css" type="text/css" media="screen" />
</head>
<p>
<body>
<div id="welcome"><b>Welcome to the Myanmar Trivia Quiz</b><br> please enter your name and click on "Begin Quiz" to start</div>
<div id="name"><b>Name:</b>
<input type="text" id="textbox">
<button id=”myButton” type="button" onclick="submission()">submit</button>
</div>
<div id="welcome2">Myanmar Trivia Quiz </div>
<div id="welcome2-0">Test your Demographic Knowledge<br>--------------------------------------------------------------------------------------</div>
</div>
</body>
<script src="includes/project.js"></script>
</html>
To achieve what you are trying to do, it's simply as:
var name;
var nameFormat=true;
function submission() {
name = document.getElementById("textbox").value;
if (name.length > 0) {
alert("Welcome "+name);
$("#name").fadeOut(1000);
$("#welcome").fadeOut(1000);
$("#welcome2").fadeIn(1000);
$("#welcome2-0").fadeIn(1000);
}
else{
nameFormat=false;
alert("Please enter the name again");
}
}
Since you showed up in your code fadeOut, I made my answer with that. Otherwise you can replace fadeIn with show.
About your CSS code, try to set display: none; for those elements that should be hidden when the page loads.
For more info look at:
http://api.jquery.com/show/