I have started making a blur image so when you click the button "Blur Image", it will blur image but there are some errors showing on Console.Log and I have been trying to solve it but didn't had success.
let btn = document.querySelector('.btnbl')[0];
let img = document.querySelector('img')[0];
c = 0;
function coverImage () {
if( c === 0) {
btn.innerHTML = 'Blur Image';
img.style.filter = 'blur(0)';
c = 1;
} else {
btn.innerHTML = 'Unblur Image';
img.style.filter = 'blur(24px)';
c = 0;
}
}
.blur{
margin-top: 20px;
display: flex;
justify-content: center;
}
.blur img{
width: 730px;
height: 520px;
filter: blur(0px);
}
.btnbl{
position: absolute;
top: 45px;
right: 452px;
padding: 7px;
background-color: darkslategray;
border-radius: 5px solid yellow;
font-size: 20px;
color: white;
cursor: pointer;
font-family: sans-serif;
}
<div class="blur">
<img src="https://4.bp.blogspot.com/_EZ16vWYvHHg/TFBW_zN6oaI/AAAAAAAAQd4/8UxrcXLQ5js/s1600/www.idool.net-Perrito.jpg">
<button onclick="coverImage()" class="btnbl">Blur Image</button>
</div>
document.querySelector returns a single element so no need to access the elements like it returns an array by using []. and make c=1 before calling the function because originally it is un-blurred
let btn = document.querySelector('.btnbl');
let img = document.querySelector('img');
c = 1;
function coverImage () {
if( c === 0) {
btn.innerHTML = 'Blur Image';
img.style.filter = 'blur(0)';
c = 1;
} else {
btn.innerHTML = 'Unblur Image';
img.style.filter = 'blur(24px)';
c = 0;
}
}
.blur{
margin-top: 20px;
display: flex;
justify-content: center;
}
.blur img{
width: 730px;
height: 520px;
filter: blur(0px);
}
.btnbl{
position: absolute;
top: 45px;
right: 452px;
padding: 7px;
background-color: darkslategray;
border-radius: 5px solid yellow;
font-size: 20px;
color: white;
cursor: pointer;
font-family: sans-serif;
}
<div class="blur">
<img src="https://4.bp.blogspot.com/_EZ16vWYvHHg/TFBW_zN6oaI/AAAAAAAAQd4/8UxrcXLQ5js/s1600/www.idool.net-Perrito.jpg">
<button onclick="coverImage()" class="btnbl">Blur Image</button>
</div>
querySelector() returns only one element, so no need to reference it as an array.
Just take out the indexes for the variables like so:
let btn = document.querySelector('.btnbl');
let img = document.querySelector('img');
let btn = document.querySelector('.btnbl');
let img = document.querySelector('img');
c = 0;
function coverImage () {
if( c === 0) {
btn.innerHTML = 'Blur Image';
img.style.filter = 'blur(0)';
c = 1;
} else {
btn.innerHTML = 'Unblur Image';
img.style.filter = 'blur(24px)';
c = 0;
}
}
.blur{
margin-top: 20px;
display: flex;
justify-content: center;
}
.blur img{
width: 730px;
height: 520px;
filter: blur(0px);
}
.btnbl{
position: absolute;
top: 45px;
right: 452px;
padding: 7px;
background-color: darkslategray;
border-radius: 5px solid yellow;
font-size: 20px;
color: white;
cursor: pointer;
font-family: sans-serif;
}
<div class="blur">
<img src="https://4.bp.blogspot.com/_EZ16vWYvHHg/TFBW_zN6oaI/AAAAAAAAQd4/8UxrcXLQ5js/s1600/www.idool.net-Perrito.jpg">
<button onclick="coverImage()" class="btnbl">Blur Image</button>
</div>
Related
const sentence = document.getElementById('sentence')
const word = document.getElementById('word')
const number = document.getElementById('number')
const btnContainer = document.getElementById('btnContainer')
function Start() {
btnContainer.style.display = 'flex';
}
Start()
sentence.addEventListener('click', () => {
type = 1;
Start();
})
word.addEventListener('click', () => {
type = 2;
Start();
})
number.addEventListener('click', () => {
type = 3;
Start();
})
.btnContainer {
position: absolute;
top: 60px;
right: .5vw;
gap: .2em;
width: 25vw;
height: 10vh;
align-items: center;
justify-content: center;
}
.btn {
background-color: transparent;
border: transparent;
font-size: 1.1rem;
color: var(--lightprimary);
transition: ease-in-out .2s;
}
.btn:hover {
color: var(--darkprimary);
}
<div class="btnContainer" id="btnContainer">
<button class="sentenceButton btn" id="sentence">Sentence</button>
<button class="wordButton btn" id="word">Words</button>
<button class="numberButton btn" id="number">Numbers</button>
</div>
There is more code that hasn't something to do with the buttons.
The 'btnContainer.style.display' is necessary to work with the other code.
Please confirm that your CSS :root selector is structured like so. In order for it to grab the primary color, you have to define that color first. Also, as mentioned in the comments it appears your buttons are responding via the console log.
const sentence = document.getElementById('sentence')
const word = document.getElementById('word')
const number = document.getElementById('number')
const btnContainer = document.getElementById('btnContainer')
function Start() {
btnContainer.style.display = 'flex';
}
Start()
sentence.addEventListener('click', () => { type = 1; Start(); })
word.addEventListener('click', () => { type = 2; Start(); })
number.addEventListener('click', () => { type = 3; Start(); })
.btnContainer {
position: absolute;
top: 60px;
right: .5vw;
gap: .2em;
width: 25vw;
height: 10vh;
align-items: center;
justify-content: center;
}
.btn {
background-color: white;
border: hidden;
font-size: 1.1rem;
color: var(--lightprimary);
transition: ease-in-out .2s;
}
.btn:hover {
background-color: var(--darkprimary-color);
}
:root {
--darkprimary-color: yellow;
}
<div class="btnContainer" id="btnContainer">
<button class="sentenceButton btn" id="sentence" type="button">Sentence</button>
<button class="wordButton btn" id="word" type="button">Words</button>
<button class="numberButton btn" id="number" type="button">Numbers</button>
</div>
Without the Javascript code and with defined --lightprimary and --darkprimary, everything works.
:root{
--lightprimary: green;
--darkprimary: red;
}
.btnContainer {
position: absolute;
top: 60px;
right: .5vw;
gap: .2em;
width: 25vw;
height: 10vh;
align-items: center;
justify-content: center;
}
.btn {
background-color: transparent;
border: transparent;
font-size: 1.1rem;
color: var(--lightprimary);
transition: ease-in-out .2s;
}
.btn:hover {
color: var(--darkprimary);
}
<div class="btnContainer" id="btnContainer">
<button class="sentenceButton btn" id="sentence">Sentence</button>
<button class="wordButton btn" id="word">Words</button>
<button class="numberButton btn" id="number">Numbers</button>
</div>
const shortApi = 'https://api.quotable.io/random?minLength=60&maxLength=80'
const mediumApi = 'https://api.quotable.io/random?minLength=100&maxLength=180'
const longApi = 'https://api.quotable.io/random?minLength=200&maxLength=220'
const display = document.getElementById('display')
const input = document.getElementById('input')
const restart = document.getElementById('restart-btn')
const sentence = document.getElementById('sentence')
const word = document.getElementById('word')
const number = document.getElementById('number')
const actionBtn1 = document.getElementById('btn1')
const actionBtn2 = document.getElementById('btn2')
const actionBtn3 = document.getElementById('btn3')
const actionBtn4 = document.getElementById('btn4')
const container = document.getElementById('container')
const btnContainer = document.getElementById('btnContainer')
const smallBtnContainer = document.getElementById('smallBtnContainer')
const stats = document.getElementById('stats')
const exit = document.getElementById('exit')
var type = 1
async function newQuote() {
display.innerText = '';
var quote = 'hello world'
let arr = quote.split("").map(value => {
return "<span class='span'>" + value + "</span>"
})
display.innerHTML += arr.join("");
}
function Start() {
newQuote()
input.value = null
stats.style.display = 'none';
container.style.display = 'flex';
btnContainer.style.display = 'flex';
smallBtnContainer.style.display = 'block';
input.disabled = false;
let startTime = null
let endTime = null
input.addEventListener('input', () => {
if (startTime == null)
startTime = new Date()
let quoteChars = document.querySelectorAll(".span")
var mistakes = 0
quoteChars = Array.from(quoteChars)
let inputChars = input.value.split("")
quoteChars.forEach((char, index) => {
if (char.innerText === inputChars[index]) {
char.classList.add('correct')
char.classList.remove('incorrect')
} else if (inputChars[index] == null) {
char.classList.remove('correct')
char.classList.remove('incorrect')
} else {
char.classList.remove('correct')
char.classList.add('incorrect')
mistakes += 1
}
})
if (inputChars.length >= quoteChars.length) {
clicked = false
stats.style.display = 'block';
container.style.display = 'none';
btnContainer.style.display = 'none';
smallBtnContainer.style.display = 'none';
input.disabled = true;
endTime = new Date()
const delta = endTime - startTime
const seconds = delta / 1000
const minutes = seconds / 60
const accuracy = Math.round(((input.value.length - mistakes) / input.value.length) * 100)
const wpm = (input.value.length / 5 / minutes).toFixed(2) + " wpm"
document.getElementById('score').innerHTML = wpm
document.getElementById('mistakes').innerText = mistakes
document.getElementById('accuracy').innerText = accuracy + "%"
}
})
}
function changeActionButtons(type) {
actionBtn1.style.display = 'block'
actionBtn2.style.display = 'block'
actionBtn3.style.display = 'block'
actionBtn4.style.display = 'block'
if (type == 1) {
actionBtn1.style.display = 'none'
actionBtn2.textContent = 'short'
actionBtn3.textContent = 'medium'
actionBtn4.textContent = 'long'
} else if (type == 2) {
actionBtn1.textContent = '1'
actionBtn2.textContent = '10'
actionBtn3.textContent = '20'
actionBtn4.textContent = '30'
} else if (type == 3) {
actionBtn1.textContent = '1'
actionBtn2.textContent = '5'
actionBtn3.textContent = '10'
actionBtn4.textContent = '15'
}
}
changeActionButtons(type)
Start()
exit.addEventListener('click', () => {
stats.style.display = 'none';
container.style.display = 'flex';
btnContainer.style.display = 'block';
smallBtnContainer.style.display = 'block';
Start()
})
restart.addEventListener('click', () => {
Start();
})
sentence.addEventListener('click', () => {
console.log('gello');
type = 1;
changeActionButtons(1);
Start();
console.log('clicked');
})
word.addEventListener('click', () => {
type = 2;
changeActionButtons(2);
Start();
})
number.addEventListener('click', () => {
type = 3;
changeActionButtons(3);
Start();
})
* {
box-sizing: border-box;
}
:root {
--primary: #222;
--lightprimary: #555;
--darkprimary: #0f0f0f;
--secondary: #ffcf00;
--incorrect: #ff2d2d;
}
body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
background-color: var(--primary);
font-size: 2rem;
font-family: 'Oxygen', Arial, sans-serif;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
user-select: none;
-khtml-user-select: none;
}
button {
font-family: 'Oxygen', Arial, sans-serif;
}
.container {
position: relative;
display: flex;
width: 90%;
height: 50vh;
text-align: center;
justify-content: center;
align-items: center;
padding: 1rem;
color: var(--lightprimary);
max-width: 1000px;
transition: ease-in-out .2s;
}
.quote {
font-family: 'Oxygen Mono', monospace;
display: block;
position: absolute;
top: 100px;
}
.input {
font-family: 'Oxygen Mono', monospace;
position: absolute;
top: 280px;
resize: none;
width: 100%;
border: 2px solid var(--lightprimary);
border-radius: 20px;
text-align: left;
font-size: 1.1rem;
margin: auto;
outline: none;
text-align: center;
color: var(--lightprimary);
background-color: transparent;
}
.input:focus {
border-color: var(--darkprimary);
}
.restart-btn {
position: absolute;
top: 340px;
background-color: transparent;
border: transparent;
font-size: 4rem;
color: var(--lightprimary);
transition: ease-in-out .2s;
}
.restart-btn:hover {
color: var(--darkprimary);
}
.btnContainer {
position: absolute;
top: 60px;
right: .5vw;
gap: .2em;
width: 25vw;
height: 10vh;
align-items: center;
justify-content: center;
}
.btn {
font-size: 1.1rem;
color: var(--lightprimary);
transition: ease-in-out .2s;
}
.btn:hover {
color: var(--darkprimary);
}
.smallBtnContainer {
position: absolute;
top: 70px;
right: 6.5vw;
gap: .2em;
width: 25vw;
height: 10vh;
align-items: center;
justify-content: center;
}
.smallBtn {
background-color: transparent;
border: transparent;
font-size: 1rem;
color: var(--lightprimary);
transition: ease-in-out .2s;
}
.smallBtn:hover {
color: var(--darkprimary);
}
.stats {
display: none;
justify-content: center;
align-items: center;
width: 40vw;
height: 40vh;
position: absolute;
color: var(--secondary);
text-align: center;
font-size: 1.6rem;
transition: ease-in-out .2s;
}
.exit {
font-size: 2rem;
background-color: transparent;
border: transparent;
color: var(--lightprimary);
transition: ease-in-out .2s;
}
.exit:hover {
color: var(--darkprimary);
}
.logo {
position: absolute;
width: 200px;
aspect-ratio: 1;
top: 0;
left: 0;
}
.title {
position: absolute;
color: var(--secondary);
top: 75px;
left: 150px;
}
.correct {
color: var(--secondary);
text-decoration: none;
}
.incorrect {
color: var(--incorrect);
text-decoration: underline;
}
<!DOCTYPE html>
<html>
<head>
<link href="https://fonts.googleapis.com/css2?family=Oxygen&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Oxygen+Mono&display=swap" rel="stylesheet">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles.css">
<title>Type Lite</title>
<script src="script.js" defer></script>
</head>
<body>
<img class="logo" alt='logo'>
<p class='title'>logo</p>
<div class="stats" id="stats">
<p>Score: <span id="score"></span></p>
<p>Mistakes: <span id="mistakes"></span></p>
<p>Accuracy: <span id="accuracy"></span></p>
<button class="exit" id="exit">X</button>
</div>
<div class="container" id="container">
<div class="quote" id="display"></div>
<textarea class="input" id="input" cols="90" rows="2" placeholder="Type here to start." autofocus></textarea>
<button class="restart-btn" id="restart-btn">Restart</button>
</div>
<div class="btnContainer" id="btnContainer">
<button class="sentenceButton btn" id="sentence">Sentence</button>
<button class="wordButton btn" id="word">Words</button>
<button class="numberButton btn" id="number">Numbers</button>
</div>
<div class="smallBtnContainer" id="smallBtnContainer">
<button class="smallBtn" id="btn1">1</button>
<button class="smallBtn" id="btn2">2</button>
<button class="smallBtn" id="btn3">3</button>
<button class="smallBtn" id="btn4">4</button>
</div>
</body>
</html>
I am fairly new to javascript, and am working on a note-taking app to practice some things I have learned so far. It all works fine, however, when I click on the Read More button to view overflow text of the note, it displays the text from the most recent note, as opposed to the note I click Read More on. I want the entire text of a particular note to be displayed when its corresponding Read More button is pressed. Am I overthinking this? I think some kind of implementation of for...of, or for loops may help me achieve this outcome. This is a link to my codepen: https://codepen.io/oliverc96/pen/xxdZYrr
const addNote = document.querySelector('.add-note');
const newNote = document.querySelector('#new-note');
const noteFeed = document.querySelector('#note-feed');
let modalBg = document.createElement('div');
let modalWindow = document.createElement('div');
let exitSymbol = document.createElement('i');
let modalText = document.createElement('p');
function expandNote() {
modalWindow.classList.add('enterAnimation');
modalBg.style.visibility = 'visible';
exitSymbol.addEventListener('click', () => {
modalBg.style.visibility = 'hidden';
modalWindow.classList.remove('enterAnimation');
})
}
function createNote() {
const noteContainer = document.createElement('div');
noteContainer.classList.add('containerStyle');
let noteHeader = document.createElement('h1');
const noteNum = noteFeed.childElementCount;
noteHeader.innerText = `Note #${noteNum + 1}`;
noteHeader.classList.add('headerStyle');
noteContainer.append(noteHeader);
let noteText = document.createElement('p');
noteText.innerText = `${newNote.value}`;
noteText.classList.add('paraStyle');
noteContainer.append(noteText);
let readMore = document.createElement('button');
readMore.innerText = 'Read More';
readMore.classList.add('btnStyle');
noteContainer.append(readMore);
noteFeed.append(noteContainer);
readMore.addEventListener('click', expandNote);
modalBg.classList.add('modal-bg');
modalWindow.classList.add('modal-window');
exitSymbol.className = 'far fa-times-circle';
exitSymbol.classList.add('exitSymbol');
modalWindow.append(exitSymbol);
modalText.classList.add('fullTextStyle');
modalText.innerText = `${noteText.innerText}`;
modalWindow.append(modalText);
modalBg.append(modalWindow);
noteContainer.append(modalBg);
newNote.value = '';
}
addNote.addEventListener('click', createNote);
newNote.addEventListener('keyup', function(e) {
if (e.keyCode === 13) {
e.preventDefault();
createNote();
}
})
Actually your modalText will always store the latest value according to your code. You can follow the following steps to solve this.
Attach an data-attribute to that noteText.
When click on read more pass the id of that specific note.
Now just show the innerText of that selected item. You can use querySelector to get the element using data-attribute.
You can check my implementation.
console.clear();
const addNote = document.querySelector('.add-note');
const newNote = document.querySelector('#new-note');
const noteFeed = document.querySelector('#note-feed');
let modalBg = document.createElement('div');
let modalWindow = document.createElement('div');
let exitSymbol = document.createElement('i');
let modalText = document.createElement('p');
function expandNote(noteContainer, noteNum) {
return function () {
modalWindow.classList.add('enterAnimation');
modalBg.style.visibility = 'visible';
exitSymbol.addEventListener('click', () => {
modalBg.style.visibility = 'hidden';
modalWindow.classList.remove('enterAnimation');
})
const data = document.querySelector(`[data-id='${noteNum}']`).innerText;
showMoreModal(noteContainer, data);
}
}
function showMoreModal(noteContainer, data) {
modalBg.classList.add('modal-bg');
modalWindow.classList.add('modal-window');
exitSymbol.className = 'far fa-times-circle';
exitSymbol.classList.add('exitSymbol');
modalWindow.append(exitSymbol);
modalText.classList.add('fullTextStyle');
modalText.innerText = `${data}`;
modalWindow.append(modalText);
modalBg.append(modalWindow);
noteContainer.append(modalBg);
}
function createNote() {
const noteContainer = document.createElement('div');
noteContainer.classList.add('containerStyle');
let noteHeader = document.createElement('h1');
const noteNum = noteFeed.childElementCount;
noteHeader.innerText = `Note #${noteNum + 1}`;
noteHeader.classList.add('headerStyle');
noteContainer.append(noteHeader);
let noteText = document.createElement('p');
noteText.innerText = `${newNote.value}`;
noteText.classList.add('paraStyle');
noteText.setAttribute('data-id', noteNum);
noteContainer.append(noteText);
let readMore = document.createElement('button');
readMore.innerText = 'Read More';
readMore.classList.add('btnStyle');
noteContainer.append(readMore);
noteFeed.append(noteContainer);
readMore.addEventListener('click', expandNote(noteContainer, noteNum));
newNote.value = '';
}
addNote.addEventListener('click', createNote);
newNote.addEventListener('keyup', function(e) {
if (e.keyCode === 13) {
e.preventDefault();
createNote();
}
})
* {
padding: 0;
margin: 0;
box-sizing: border-box;
font-family: 'Montserrat', sans-serif;
}
#wrapper {
width: 1600px;
height: 100vh;
margin: auto;
text-align: center;
}
h1 {
font-size: 100px;
margin-top: 20px;
font-weight: 500;
}
h2 {
font-size: 50px;
font-weight: 400;
margin-top: 10px;
}
#add-new-note {
color: rgb(0, 153, 153);
}
textarea {
width: 1500px;
margin-top: 30px;
height: 60px;
border-radius: 6px;
padding: 20px;
font-size: 18px;
}
textarea:focus {
outline-color: black;
}
.add-note {
font-size: 20px;
width: 180px;
height: 50px;
border-radius: 6px;
margin-top: 30px;
background-color: rgb(0, 153, 153);
color: white;
border-style: solid;
border-color: rgb(0, 102, 102);
}
.add-note:hover {
background-color: rgb(0, 128, 128);
cursor: pointer;
}
#note-feed {
background-color: rgb(0, 153, 153);
height: 500px;
margin-top: 25px;
width: 1500px;
border-radius: 6px;
display: flex;
overflow: scroll;
flex-wrap: wrap;
padding: 20px 10px;
margin-left: 50px;
}
.containerStyle {
display: flex;
flex-direction: column;
justify-content: space-around;
background-color: rgb(169, 169, 214);
height: 48%;
width: 31%;
margin-right: 11px;
margin-left: 20px;
border-radius: 6px;
margin-bottom: 20px;
overflow: hidden;
padding: 0 28px;
padding-bottom: 15px;
text-align: left;
}
.headerStyle {
font-size: 30px;
}
.paraStyle {
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
font-size: 18px;
text-overflow: ellipsis;
overflow: hidden;
}
.btnStyle {
font-size: 20px;
width: 150px;
height: 40px;
border-radius: 6px;
background-color: rgb(255, 128, 128);
color: white;
border-style: solid;
border-color: rgb(255, 77, 77);
align-self: left;
}
.btnStyle:hover {
background-color: rgb(255, 102, 102);
cursor: pointer;
}
.modal-bg {
z-index: 1;
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
background: rgba(0,0,0,0.5);
color: white;
display: flex;
justify-content: center;
align-items: center;
visibility: hidden;
overflow: scroll;
}
.modal-window {
border-radius: 6px;
background: white;
width: 70%;
min-height: 30%;
max-height: 70%;
overflow: scroll;
display: flex;
justify-content: flex-start;
align-items: flex-start;
}
.enterAnimation {
animation-name: fadeInDown;
animation-duration: 1s;
}
#keyframes fadeInDown {
0% {
opacity: 0;
transform: translateY(-200px);
}
100% {
opacity: 1;
}
}
.exitSymbol {
color: rgb(0, 128, 128);
font-size: 30px;
margin: 20px 20px;
}
.exitSymbol:hover {
cursor: pointer;
opacity: 0.8;
}
.fullTextStyle {
color: black;
width: 90%;
height: 80%;
text-align: left;
margin-top: 60px;
margin-bottom: 30px;
font-size: 18px;
}
<html>
<head>
<title> Note Taker </title>
<link type="text/css" href="notes.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght#100;200;300;400;500;600;700&display=swap" rel="stylesheet">
</head>
<body>
<div id="wrapper">
<h1> Note Taker </h1>
<h2 id="add-new-note"> Add A New Note: </h2>
<textarea id="new-note" name="note-box" placeholder="Write your note here"></textarea>
<button class="add-note"> Add Note </button>
<div id="note-feed">
</div>
</div>
<script src="notes.js"></script>
<script src="https://kit.fontawesome.com/6fc6f370ca.js" crossorigin="anonymous"></script>
</body>
</html>
I have a code that gets characters names and gender after clicking on film name. This information appears in modal window and my goal is to delete HTML element with characters every time I close modal, so if I select another film the new set of characters will appear, and the old one is already deleted.
The problem is that removeChild method doesn't work as expected. I've tried different variations including parentNode but nothing helped.
Here is the code:
window.addEventListener('DOMContentLoaded', function() {
let btn = document.querySelector('.sw-btn');
let content = document.querySelector('.content');
let modal = document.querySelector('.modal');
let modalBody = document.querySelector('.modal-body');
let closeBtn = document.querySelector('.close-btn');
let filmsList = document.createElement('ul');
let charsList = document.createElement('ol');
function getFilms() {
axios.get('https://swapi.co/api/films/').then(res => {
content.appendChild(filmsList);
for (var i = 0; i < res.data.results.length; i++) {
res.data.results.sort(function(a, b) {
let dateA = new Date(a.release_date),
dateB = new Date(b.release_date);
return dateA - dateB;
});
(function updateFilms() {
let addFilm = document.createElement('li');
filmsList.appendChild(addFilm);
let addFilmAnchor = document.createElement('a');
let addFilmId = document.createElement('p');
let addFilmCrawl = document.createElement('p');
let addFilmDirector = document.createElement('p');
let addFilmDate = document.createElement('p');
addFilmAnchor.textContent = res.data.results[i].title;
addFilmId.textContent = `Episode ID: ${res.data.results[i].episode_id}`;
addFilmCrawl.textContent = `Episode description: ${res.data.results[i].opening_crawl}`;
addFilmDirector.textContent = `Episode director: ${res.data.results[i].director}`;
addFilmDate.textContent = `Episode release date: ${res.data.results[i].release_date}`;
addFilm.append(addFilmAnchor, addFilmId, addFilmCrawl, addFilmDirector, addFilmDate);
})();
}
let links = document.getElementsByTagName('a');
for (let j = 0; j < links.length; j++) {
links[j].onclick = function() {
modal.style.display = 'block';
modalBody.appendChild(charsList);
let chars = res.data.results[j].characters;
for (let k = 0; k < chars.length; k++) {
const element = chars[k];
axios.get(element).then(res => {
let addChar = document.createElement('li');
charsList.appendChild(addChar);
let addCharName = document.createElement('p');
let addCharGender = document.createElement('p');
addCharName.textContent = `Character name: ${res.data.name}`;
addCharGender.textContent = `Character gender: ${res.data.gender}`;
addChar.append(addCharName, addCharGender);
})
}
closeBtn.addEventListener('click', () => {
modal.style.display = 'none';
console.log(modalBody.childNodes[0]);
// Problem is here
modalBody.removeChild(modalBody.childNodes[0]);
});
window.addEventListener('click', (e) => {
if (e.target == modal) {
modal.style.display = 'none';
console.log(modalBody.childNodes[0]);
modalBody.removeChild(modalBody.childNodes[0]);
}
})
}
}
}).catch(err => {
console.log("An error occured");
})
};
btn.addEventListener('click', getFilms);
closeBtn.addEventListener('click', () => {
modal.style.display = 'none';
});
window.addEventListener('click', (e) => {
if (e.target == modal) {
modal.style.display = 'none';
}
})
});
body {
max-height: 100vh;
padding: 0;
margin: 0;
font-family: Muli;
}
body::before {
background: url('https://upload.wikimedia.org/wikipedia/commons/thumb/6/6c/Star_Wars_Logo.svg/1200px-Star_Wars_Logo.svg.png') no-repeat center / cover;
background-size: cover;
content: "";
display: block;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -2;
opacity: 0.1;
}
h1 {
text-align: center;
color: #660d41;
font-size: 3em;
margin-top: 10px;
letter-spacing: 1px;
}
main {
display: flex;
align-items: center;
flex-direction: column;
}
.content {
max-width: 55%;
overflow-y: scroll;
max-height: 75vh;
}
.modal {
display: none;
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(0, 0, 0, 0.5);
}
.modal-content {
background-color: #f4f4f4;
margin: 20% auto;
width: 40%;
box-shadow: 0 5px 8px 0 rgba(0, 0, 0, 0.2), 0 7px 20px 0 rgba(0, 0, 0, 0.2);
animation: modalOpen 1s;
}
.modal-header {
background: coral;
padding: 15px;
color: white;
letter-spacing: 1px;
position: relative;
}
.modal-header h2 {
margin: 0;
}
.modal-body {
padding: 10px 20px;
}
.close-btn {
color: white;
float: right;
font-size: 30px;
position: absolute;
top: 0px;
right: 10px;
}
.close-btn:hover,
.close-btn:focus {
color: black;
text-decoration: none;
cursor: pointer;
transition: all 0.4s ease-in;
}
ul {
list-style-type: none;
padding: 10px 20px;
}
li {
border-bottom: 1px solid orangered;
margin-bottom: 30px;
}
li:last-child {
border-bottom: none;
margin-bottom: 0;
}
a {
font-size: 1.7em;
color: #b907d9;
cursor: pointer;
margin-bottom: 10px;
}
p {
font-size: 1.2rem;
color: #0f063f;
margin: 10px 0;
}
button {
padding: .5em 1.5em;
border: none;
color: white;
transition: all 0.2s ease-in;
background: #da2417;
border-radius: 20px;
font-size: 1em;
cursor: pointer;
margin-top: 15px;
}
button:focus {
outline: none;
}
button:hover {
background: #e7736b;
}
button:active {
box-shadow: 0px 0px 15px rgba(0, 0, 0, 0.7) inset;
}
#keyframes modalOpen {
from {
opacity: 0
}
to {
opacity: 1
}
}
<link href="https://fonts.googleapis.com/css?family=Muli&display=swap" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.0/axios.min.js"></script>
<h1>Star wars films</h1>
<main>
<div class="content"></div>
<div class="modal">
<div class="modal-content">
<div class="modal-header">
<span class="close-btn">×</span>
<h2>Episode Characters</h2>
</div>
<div class="modal-body"></div>
</div>
</div>
<button class="sw-btn">Find Films</button>
</main>
Any help would be appreciated.
The problem is that you are using the same ol element when appending the characters to the list, since you instantiate it at the beginning and re-use it later: let charsList = document.createElement('ol');
When you close the modal, you will remove that ol element from the modal, but you will not remove its content. When opening the modal again, the ol will be added again - with your old content.
If you move the declaration of charsList inside your onclick handler, it will work.
Also, you should register the close handlers of your modal only once. Otherwise, it will be called as often as you open your modal.
Demo:
window.addEventListener('DOMContentLoaded', function () {
let btn = document.querySelector('.sw-btn');
let content = document.querySelector('.content');
let modal = document.querySelector('.modal');
let modalBody = document.querySelector('.modal-body');
let closeBtn = document.querySelector('.close-btn');
let filmsList = document.createElement('ul');
closeBtn.addEventListener('click', () => {
modal.style.display = 'none';
console.log(modalBody.childNodes[0]);
modalBody.removeChild(modalBody.childNodes[0]);
});
window.addEventListener('click', (e) => {
if (e.target == modal) {
modal.style.display = 'none';
console.log(modalBody.childNodes[0]);
modalBody.removeChild(modalBody.childNodes[0]);
}
})
function getFilms() {
axios.get('https://swapi.co/api/films/').then(res => {
content.appendChild(filmsList);
for (var i = 0; i < res.data.results.length; i++) {
res.data.results.sort(function (a, b) {
let dateA = new Date(a.release_date),
dateB = new Date(b.release_date);
return dateA - dateB;
});
(function updateFilms() {
let addFilm = document.createElement('li');
filmsList.appendChild(addFilm);
let addFilmAnchor = document.createElement('a');
let addFilmId = document.createElement('p');
let addFilmCrawl = document.createElement('p');
let addFilmDirector = document.createElement('p');
let addFilmDate = document.createElement('p');
addFilmAnchor.textContent = res.data.results[i].title;
addFilmId.textContent = `Episode ID: ${res.data.results[i].episode_id}`;
addFilmCrawl.textContent = `Episode description: ${res.data.results[i].opening_crawl}`;
addFilmDirector.textContent = `Episode director: ${res.data.results[i].director}`;
addFilmDate.textContent = `Episode release date: ${res.data.results[i].release_date}`;
addFilm.append(addFilmAnchor, addFilmId, addFilmCrawl, addFilmDirector, addFilmDate);
})();
}
let links = document.getElementsByTagName('a');
for (let j = 0; j < links.length; j++) {
links[j].onclick = function () {
modal.style.display = 'block';
let charsList = document.createElement('ol');
modalBody.appendChild(charsList);
let chars = res.data.results[j].characters;
for (let k = 0; k < chars.length; k++) {
const element = chars[k];
axios.get(element).then(res => {
let addChar = document.createElement('li');
charsList.appendChild(addChar);
let addCharName = document.createElement('p');
let addCharGender = document.createElement('p');
addCharName.textContent = `Character name: ${res.data.name}`;
addCharGender.textContent = `Character gender: ${res.data.gender}`;
addChar.append(addCharName, addCharGender);
})
}
}
}
}).catch(err => {
console.log("An error occured");
})
};
btn.addEventListener('click', getFilms);
closeBtn.addEventListener('click', () => {
modal.style.display = 'none';
});
window.addEventListener('click', (e) => {
if (e.target == modal) {
modal.style.display = 'none';
}
})
});
body {
max-height: 100vh;
padding: 0;
margin: 0;
font-family: Muli;
}
body::before {
background: url('https://upload.wikimedia.org/wikipedia/commons/thumb/6/6c/Star_Wars_Logo.svg/1200px-Star_Wars_Logo.svg.png') no-repeat center / cover;
background-size: cover;
content: "";
display: block;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -2;
opacity: 0.1;
}
h1 {
text-align: center;
color: #660d41;
font-size: 3em;
margin-top: 10px;
letter-spacing: 1px;
}
main {
display: flex;
align-items: center;
flex-direction: column;
}
.content {
max-width: 55%;
overflow-y: scroll;
max-height: 75vh;
}
.modal {
display: none;
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(0, 0, 0, 0.5);
}
.modal-content {
background-color: #f4f4f4;
margin: 20% auto;
width: 40%;
box-shadow: 0 5px 8px 0 rgba(0, 0, 0, 0.2), 0 7px 20px 0 rgba(0, 0, 0, 0.2);
animation: modalOpen 1s;
}
.modal-header {
background: coral;
padding: 15px;
color: white;
letter-spacing: 1px;
position: relative;
}
.modal-header h2 {
margin: 0;
}
.modal-body {
padding: 10px 20px;
}
.close-btn {
color: white;
float: right;
font-size: 30px;
position: absolute;
top: 0px;
right: 10px;
}
.close-btn:hover,
.close-btn:focus {
color: black;
text-decoration: none;
cursor: pointer;
transition: all 0.4s ease-in;
}
ul {
list-style-type: none;
padding: 10px 20px;
}
li {
border-bottom: 1px solid orangered;
margin-bottom: 30px;
}
li:last-child {
border-bottom: none;
margin-bottom: 0;
}
a {
font-size: 1.7em;
color: #b907d9;
cursor: pointer;
margin-bottom: 10px;
}
p {
font-size: 1.2rem;
color: #0f063f;
margin: 10px 0;
}
button {
padding: .5em 1.5em;
border: none;
color: white;
transition: all 0.2s ease-in;
background: #da2417;
border-radius: 20px;
font-size: 1em;
cursor: pointer;
margin-top: 15px;
}
button:focus {
outline: none;
}
button:hover {
background: #e7736b;
}
button:active {
box-shadow: 0px 0px 15px rgba(0, 0, 0, 0.7) inset;
}
#keyframes modalOpen {
from {
opacity: 0
}
to {
opacity: 1
}
}
<link href="https://fonts.googleapis.com/css?family=Muli&display=swap" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.0/axios.min.js"></script>
<h1>Star wars films</h1>
<main>
<div class="content"></div>
<div class="modal">
<div class="modal-content">
<div class="modal-header">
<span class="close-btn">×</span>
<h2>Episode Characters</h2>
</div>
<div class="modal-body"></div>
</div>
</div>
<button class="sw-btn">Find Films</button>
</main>
Do this charsList.innerText = ''; when click close button.
When you call removeChild you take off the <ol> from modalbody in UI. You can see the modalBody is empty after clicking close button.
But you already store the <ol> element in js variable by let charsList = document.createElement('ol'); so the ol element itself doesn't change actually.
The <li> element still inside the <ol>. Then you add more new <li> and put it back to modalBody.
My solution is remove all element in <ol> when clicking close button.
https://gyazo.com/aa49eb6d6849b3adabb8924aa9e40594
I have the elements in the diagram and I want to let the user choose in which element they are going to add the semi column to add text, but I dont know how to let them select a element and then add according to that selection.
var addDetail = document.getElementById('addDetail');
var clauseInput = document.getElementsByClassName('clause');
document.addEventListener('click', function(e) {
e = e || window.event;
var target = e.target || e.srcElement;
if(target == clauseInput[0] || target == clauseInput[1] ||
target == clauseInput[2] || target == clauseInput[3] ||
target == clauseInput[4] || target == addDetail) {
document.getElementById('addDetail').style.display='inline-block';
// createDetail();
console.log(target);
} else {
document.getElementById('addDetail').style.display='none';
}
}, false);
Update
Instead of searching through all clause elements every time when addDetail been clicked, there is e.relatedTarget that really suitable to your problem, detailed documentation, and the update snippet :
/*CREATE TOP AND BOTTOM CLAUSES*/
/*Top Clauses*/
const addClauseTop = document.querySelector('#addClauseTop');
var targetClauseElement;
var addDetail = document.getElementById('addDetail');
addDetail.addEventListener('focusin', function(e) {
createDetail(e.relatedTarget);
});
window.addEventListener('mouseup',function(e) {
if ( e.currentTarget != addDetail ) {
addDetail.style.display='none';
}
});
var firstTopClause = document.getElementsByClassName('clause')[0];
firstTopClause.addEventListener('click', function(e) {
addDetail.style.display='inline-block';
});
var firstBottomClause = document.getElementsByClassName('clauseDivReverse')[0];
firstBottomClause.addEventListener('click', function(e) {
addDetail.style.display='inline-block';
});
addClauseTop.addEventListener('click',function(e){
e.preventDefault();
//Get Divs-Overlay
const topDivs = document.querySelector('#topClauses');
const bottomDivs = document.querySelector('#bottomClauses');
// Create Elements
const clauseDiv = document.createElement('div');
const clauseText = document.createElement('input');
const clauseStroke = document.createElement('div');
// // //Give Style
clauseDiv.classList.add('clauseDiv');
clauseDiv.addEventListener('click', function(e) {
addDetail.style.display='inline-block';
});
clauseText.classList.add('clause');
clauseText.setAttribute("id", "clause");
clauseStroke.classList.add('strokeClause');
//
// // Append to document
clauseDiv.appendChild(clauseText);
clauseDiv.appendChild(clauseStroke);
topDivs.appendChild(clauseDiv);
document.body.appendChild(topDivs);
document.body.appendChild(bottomDivs);
})
/*BOTTOM Clauses*/
const addClauseBottom = document.querySelector('#addClauseBottom');
addClauseBottom.addEventListener('click',function(e){
e.preventDefault();
//Get Divs-Overlay
const topDivs = document.querySelector('#topClauses');
const bottomDivs = document.querySelector('#bottomClauses');
// Create Elements
const clauseDiv = document.createElement('div');
clauseDiv.addEventListener('click', function(e) {
targetClauseElement = e.currentTarget;
addDetail.style.display='inline-block';
});
const clauseText = document.createElement('input');
const clauseStroke = document.createElement('div');
// // //Give Style
clauseDiv.classList.add('clauseDivReverse');
clauseText.classList.add('clauseReverse');
clauseText.setAttribute("id", "clauseReverse");
clauseStroke.classList.add('strokeClauseReverse');
//
// // Append to document
clauseDiv.appendChild(clauseText);
clauseDiv.appendChild(clauseStroke);
bottomDivs.appendChild(clauseDiv);
document.body.appendChild(bottomDivs);
})
/***********/
//Create a addDetail
function createDetail(target){
var mainColumn = target.parentElement;
var strokeColumn = mainColumn.children[1];
// Create Elements
var levelOneDiv = document.createElement('div');
var levelOneText = document.createElement('input');
if ( mainColumn.classList.contains('clauseDiv') ) {
levelOneDiv.classList.add('levelOneClauseReverse');
levelOneText.classList.add('levelOneTextReverse');
//I thought you have not completed your style yet, like something levelOneClause class
} else {
levelOneDiv.classList.add('levelOneClauseReverse');
levelOneText.classList.add('levelOneTextReverse');
}
levelOneDiv.appendChild(levelOneText);
strokeColumn.appendChild(levelOneDiv);
}
#import url('https://fonts.googleapis.com/css?family=Vollkorn+SC');
body{
margin: 10%;
margin-right: 15%;
margin-left: 10%;
margin-top: 5%;
}
h1{
color: #3B3C3D;
font-family: 'Vollkorn SC', serif;
font-size: 2em;
text-align:center;
}
h2{
color: #3B3C3D;
font-family: 'Vollkorn SC', serif;
font-size: 1.5em;
text-align:center;
}
#bottomClauses{
clear: both;
float: right;
}
/*CONTROL-PANEL*/
#controlPanel{
float: inline-block;
margin-top: 5%;
margin-left: 20%;
margin-right: 20%;
margin-bottom: 15%;
padding-bottom: 2%;
border-radius: 10%;
border-bottom: 0.1vw solid #3B3C3D;
}
.addClause{
background-color: #2c3e50;
margin-top: 5%;
font-size: 0.75em;
padding: 0.5em;
border: 0;
color: #FFF;
}
.addClause:hover{
cursor: pointer;
background-color: #000;
}
.addDetail{
display: none;
background-color: #2c3e50;
margin-top: 5%;
font-size: 0.75em;
padding: 0.5em;
border: 0;
color: #FFF;
}
.addDetail:hover{
cursor: pointer;
background-color: #000;
}
/*FISHBONE*/
#fishBone{
position: relative;
float:right;
top: 19.75vw;
width: 100%;
height: 0.2vw;
background-color: #34495e;
}
#finalResult{
position: absolute;
/*float:right;*/
left: 83.5vw;
top: 44.25vw;
width: 7.5vw;
height: 7.5vw;
padding: 1vw;
text-align: center;
color: #FFF;
background-color: #7f8c8d;
border-radius: 50%;
border: 0.15vw solid #34495e;
}
/*NEW CLAUSE*/
.clauseDiv{
display: inline-block;
float:right;
width: 5vw;
margin-right: 12.5vw;
}
.clause{
float: inline-block;
position: relative;
top: -3.5vw;
right: 2vw;
text-align: center;
width: 5.8vw;
height: 1.5vw;
padding: 0.2vw;
color: #FFF;
background-color: #3498db;
border-radius: 0.15vw;
border: 0;
}
.strokeClause{
position: relative;
top: -5.75vw;
transform: rotate(-25deg);
background-color: #34495e;
width: 0.1vw;
height: 25vw;
margin-left: 7.5vw;
border: 0.05vw solid #34495e;
border-radius: 0.1vw;
float: inline-block;
z-index: -1;
}
/*NEW CLAUSE REVERSE*/
.clauseDivReverse{
float: inline-block;
float:right;
width: 5vw;
margin-right: 12.5vw;
}
.clauseReverse{
position: relative;
top: 15.5vw;
right: 2.5vw;
float: inline-block;
text-align: center;
width: 5.8vw;
height: 1.5vw;
padding: 0.2vw;
color: #FFF;
background-color: #3498db;
border-radius: 0.15vw;
border: 0;
}
.strokeClauseReverse{
position: relative;
top: -9.75vw;
transform: rotate(25deg);
background-color: #34495e;
width: 0.1vw;
height: 25vw;
margin-left: 7.5vw;
border: 0.05vw solid #34495e;
border-radius: 0.1vw;
float: inline-block;
z-index: -1;
}
/*NEW LEVEL ONE*/
.levelOneClauseReverse{
margin-bottom: 5vw;
}
.levelOneTextReverse{
border: 0;
position: relative;
font-size: 0.75vw;
width: 13vw;
top: 4.5vw;
right: 12.75vw;
border-bottom: 0.1vw solid #34495e;
transform: rotate(-25deg);
}
<body>
<h1>Diagram Editor</h1>
<div id='controlPanel'>
<h2>Control Panel</h2>
<input type='submit' name='addClause' value='Clause on TOP' class='addClause' id='addClauseTop'>
<input type='submit' name='addClause' value='Clause on BOTTOM' class='addClause' id='addClauseBottom'>
<input type='submit' name='addClause' value='Add Detail' class='addDetail' id='addDetail'>
</div>
<div id='fishBone'></div>
<input type='text' name='clause' id='finalResult'>
<div id='topClauses'>
<div class='clauseDiv'>
<input class='clause' id='clause'>
<div class='strokeClause'>
</div>
</div>
</div>
<div id='bottomClauses'>
<div class='clauseDivReverse' >
<input class='clauseReverse clause'>
<div class='strokeClauseReverse'>
<div class='levelOneClauseReverse'>
<input class='levelOneTextReverse'>
</div>
<div class='levelOneClauseReverse'>
<input class='levelOneTextReverse'>
</div>
<div class='levelOneClauseReverse'>
<input class='levelOneTextReverse'>
</div>
<div class='levelOneClauseReverse'>
<input class='levelOneTextReverse'>
</div>
</div>
</div>
</div>
<script src="app.js"></script>
</body>
I am making a styled HTML version of the typical JS 'alert()' box.
It is simply a nice that uses 'display: none;' and 'display: block;' to toggle the box.
However, this doesn't have the functionality of a JS 'alert()' box, as doing
for(var c = 0; c < 10; c++){ //like the joke? (c++)
cool.alert('You have seen '+c+' alerts');
}
will not create 10 successive alert boxes, but make the box's display 'block' 10 times.
Is there any way to pause the document until the alert box is closed so that the loop would be paused?
Here's all the relevant code:
<button onclick="cool.alert('Hi')">Alert box</button><div id='block'></div>
<div id='box'>
<p id='text'></p><hr id='hr'>
<div id='Ok' onclick='cool.alertclear()'>Ok</div>
</div>
<script>
var cover = document.getElementById('block');
var box = document.getElementById('box');
var text = document.getElementById('text');
var ok = document.getElementById('Ok');
var hr = document.getElementById('hr');
var cool = {
alert: function(input){
cover.style.display = 'block';
box.style.display = 'block';
ok.style.display = 'block';
text.innerHTML = input;
},
alertclear: function(){
cover.style.display = 'none';
box.style.display = 'none';
ok.style.display = 'none';
}
}
</script>
<style>
#block{
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
background: rgba(0,0,0,0.6);
display: none;
z-index: 100;
}
#box{
position: absolute;
top: 25%;
left: 35%;
height: 30%;
width: 30%;
border-radius: 10px;
background: rgba(255,255,255,0.8);
box-shadow: 0 0 50px rgba(0,0,0,0.2);
display: none;
z-index: 101;
color: #000;
padding: 10px;
cursor: default;
}
#text{
height: 60%;
word-break: break-all;
overflow-x: hidden;
overflow-y: auto;
}
#Yes{
position: absolute;
bottom: 5%;
right: 25%;
height: 15%;
width: 18%;
border-radius: 5px;
background: linear-gradient(left top, #00FF00, #00DD00);
background: -webkit-linear-gradient(left top, #00FF00, #00DD00);
cursor: hand;
text-align: center;
font-size: 1.5em;
color: white;
display: none;
}
#No{
position: absolute;
bottom: 5%;
right: 5%;
height: 15%;
width: 18%;
border-radius: 5px;
background: linear-gradient(left top, #ff6c6c, #ff4e4e);
background: -webkit-linear-gradient(left top, #ff6c6c, #ff4e4e);
cursor: hand;
text-align: center;
font-size: 1.5em;
color: white;
display: none;
}
#Ok, #Go{
position: absolute;
bottom: 5%;
right: 5%;
height: 15%;
width: 18%;
border-radius: 5px;
background: grey;
cursor: hand;
text-align: center;
font-size: 1.5em;
color: white;
display: none;
}
#Prompt{
position: absolute;
top: 30%;
left: 5%;
height: 40%;
width: 90%;
resize: none;
overflow-x: hidden;
overflow-y: auto;
word-break: break-all;
display: none;
}
#hr{
position: relative;
bottom: 0%;
}
</style>
You could keep track of the alerts like this:
var inputArr = [];
var showing = false;
var cool = {
alert: function(input){
if(!showing) {
cool.show(input);
showing = true;
} else {
inputArr.push(input);
}
},
alertclear: function(){
cover.style.display = 'none';
box.style.display = 'none';
ok.style.display = 'none';
if(inputArr.length>0) {
input = inputArr.shift();
cool.show(input);
} else {
showing = false;
}
},
show: function(input) {
cover.style.display = 'block';
box.style.display = 'block';
ok.style.display = 'block';
text.innerHTML = input;
}
}