i was trying to made my own TODO app with HTML,CSS and JS .. everything working as expected , exept this weird problem :
when i add an todo item the forloop will put addEventListener on it , so when i click on it , it will launch any code inside
The Problem : if i create more than one todo item .. some items stop working (addEventListener not working when i click on the item).
its like if i create 1 item:
item1 : working.
if i create 2 items:
item1 : not working.
item2 : working.
if i create 3 items:
item1 : working.
item2 : not working.
item2 : working.
...etc.
any explanation how to fix !
HTML CODE
<div id="form">
<p id="error">Fill The Empty !</p>
<input id="input" type="text" placeholder="Text Here!" >
<button id="add" type="submit" onclick="addIt()">Add</button>
</div>
<div id="listContainer">
<ul id="list">
</ul>
<p id="noItems">You Have No Items!</p>
</div>
CSS CODE
margin: 0px;
padding: 0px;
font-family: monospace, sans-serif;
list-style: none;
font-size: 10pt;
box-sizing: border-box;
}
#form{
display: flex;
flex-direction: column;
justify-content: center;
align-items:center;
}
#error{
color: red;
display: none;
margin: 5px 0px;
}
#input{
width: 95%;
height: 40px;
text-align: center;
margin: 5px 0px;
border: 1px purple dashed;
}
#add{
height: 40px;
width: 95%;
border: 0px;
color: white;
background-color: purple;
font-weight: 900;
}
#add:active{
color: purple;
background-color: white;
}
#listContainer{
margin-top: 40px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 100vw;
}
#list{
display: flex;
flex-direction: column-reverse;
justify-content: center;
align-items: center;
width: 100vw;
}
.item{
position: relative;
text-align: center;
padding: 10px;
margin: 5px;
width: 95%;
color: purple;
background-color: white;
border: 1px purple solid;
font-size: 11pt;
}
.delete{
position: absolute;
right: 0px;
top: 0px;
padding: 10px;
width: 50px;
color: white;
background-color: red;
font-size: 11pt;
font-weight: 900;
}
#noItems{
color: lightgray;
margin-top: 50px;
/*display: none;*/
}
JS CODE
let storeInput = "";
function addIt(){
/*---addIT() start---*/
let input = document.getElementById("input");
storeInput = input.value;
if(storeInput == ""){
let errorMsg = document.getElementById("error");
errorMsg.style.display = "block";
setTimeout(function(){errorMsg.style.display = "none";}, 2000)
}else{
input.value = "";
let item = document.createElement("LI");
item.className = "item";
item.innerHTML = storeInput;
let list = document.getElementById("list");
list.appendChild(item);
let deleteIt = document.createElement("I");
deleteIt.className = "delete";
deleteIt.innerHTML = "X";
item.appendChild(deleteIt);
}
let allItems = document.querySelectorAll(".item");
for(var i = 0; i < allItems.length; i++){
allItems[i].addEventListener("click", function(){
if(this.style.textDecoration == "line-through"){
this.style.textDecoration = "none";
}else{
this.style.textDecoration = "line-through";
}
})
}
let deleteItem = document.querySelectorAll(".delete");
for(var j = 0; j < deleteItem.length; j++){
deleteItem[j].addEventListener("click", function(){
var deleteIt = this.parentElement;
deleteIt.remove();
})
}
document.querySelectorAll(".item").length;
if(allItems.length == 0){
document.getElementById("noItems").style.display = "block";
}else{
document.getElementById("noItems").style.display = "none";
}
/*---addIT() end---*/}
if you want to try the app live :
https://codepen.io/Salsa_Project/pen/NVWPaY?editors=0110
AND TY IN ADVANCE.
The function addit() adds eventlisteners to all the items and delete buttons everytime you add an element. You should only add eventlisteners to the current item. codepen
let storeInput = "";
function addIt(){
/*---addIT() start---*/
let input = document.getElementById("input");
storeInput = input.value;
if(storeInput == ""){
let errorMsg = document.getElementById("error");
errorMsg.style.display = "block";
setTimeout(function(){errorMsg.style.display = "none";}, 2000)
}else{
input.value = "";
let item = document.createElement("LI");
item.className = "item";
item.innerHTML = storeInput;
let list = document.getElementById("list");
list.appendChild(item);
let deleteIt = document.createElement("I");
deleteIt.className = "delete";
deleteIt.innerHTML = "X";
item.appendChild(deleteIt);
item.addEventListener("click", function(){
if(this.style.textDecoration == "line-through"){
this.style.textDecoration = "none";
}else{
this.style.textDecoration = "line-through";
}
});
deleteIt.addEventListener("click", function(){
var deleteIt = this.parentElement;
deleteIt.remove();
})
}
let allItems = document.querySelectorAll(".item");
document.querySelectorAll(".item").length;
if(allItems.length == 0){
document.getElementById("noItems").style.display = "block";
}else{
document.getElementById("noItems").style.display = "none";
}
/*---addIT() end---*/}
Let us use this snippit for example
for(var j = 0; j < deleteItem.length; j++){
deleteItem[j].addEventListener("click", function(){
var deleteIt = this.parentElement;
deleteIt.remove();
})
}
Here, you are running a loop, and foreach iteration, you are creating a new click event. The issue here is your not unbinding events. So, in your current code, if you click the button, it will trigger all call events, that were previously triggered.
The quickest solution for your code, is to add something like
let deleteItem = document.querySelectorAll(".delete");
for(var j = 0; j < deleteItem.length; j++){
deleteItem[j].parentNode.replaceChild(deleteItem[j].cloneNode(true), deleteItem[j]);
})
}
deleteItem = document.querySelectorAll(".delete");
for(var j = 0; j < deleteItem.length; j++){
deleteItem[j].addEventListener("click", function(){
var deleteIt = this.parentElement;
deleteIt.remove();
})
}
Note that
for(var j = 0; j < deleteItem.length; j++){
deleteItem[j].parentNode.replaceChild(deleteItem[j].cloneNode(true), deleteItem[j]);
})
}
Will replace your current element, with itself. The only differenceis, cloneNode, does not copy the event listeners. This fixes your problem.
Related
It's difficult to identify the exact issue, My StopWatch is not working when I click on Stop Button and wait for some second then I click on start button then I see that my second is working fine but minutes is not working properly. please check that is there any issue
let start = document.getElementById("start");
let stop = document.getElementById("stop");
let reset = document.getElementById("reset");
let h3 = document.getElementById("h3");
let time = document.getElementById("time");
let h3CreateMin = document.createElement("h3");
let h3CreateHour = document.createElement("h3");
let milisecond = document.getElementById("milisecond");
let second = document.getElementById("second");
let minSpan = document.createElement("span");
let minSpanSigin = document.createElement("span");
let hourSpan = document.createElement("span");
let hourSpanSigin = document.createElement("span");
let secStart = 0;
let miliSecStart = 0;
let minStart = 0;
let hourStart = 0;
let s = true;
start.addEventListener("click", function () {
reset.style.display = "block";
stop.style.display = "block";
start.style.display = "none";
miliSecondStop = setInterval(() => {
let miliSec = miliSecStart + 1;
milisecond.innerText = miliSec;
miliSecStart = miliSec;
if (miliSecStart === 99) {
miliSecStart = 0;
}
}, 10);
// Sec Start
secondStop = setInterval(() => {
let sec = secStart + 1;
secStart = sec;
second.innerText = secStart;
if (sec === 60) {
secStart = 0;
}
}, 1000);
// Min Start
minStop = setInterval(() => {
let min = minStart + 1;
if (s === true) {
time.prepend(h3CreateMin);
}
h3CreateMin.style.display = "block";
h3CreateMin.append(minSpan);
minSpan.classList = "value";
h3CreateMin.classList = "time_s_m_h";
h3CreateMin.append(minSpanSigin);
minSpanSigin.classList = "sigin";
minSpanSigin.innerText = "M";
minStart = min;
minSpan.innerText = min;
if (min === 60) {
minStart = 0;
}
s = false;
}, 60000);
// 60000
// Hour Start
hourStop = setInterval(() => {
let hour = hourStart + 1;
time.prepend(h3CreateHour);
h3CreateHour.style.display = "block";
h3CreateHour.classList = "time_s_m_h";
h3CreateHour.append(hourSpan);
hourSpan.classList = "value";
h3CreateHour.append(hourSpanSigin);
hourSpanSigin.classList = "sigin";
hourSpanSigin.innerText = "H";
hourSpan.innerText = hour;
hourStart = hour;
if (hour === 24) {
hourStart = 0;
}
}, 60000);
// 3600000
});
stop.addEventListener("click", function () {
start.style.display = "block";
stop.style.display = "none";
clearInterval(miliSecondStop);
clearInterval(secondStop);
clearInterval(minStop);
clearInterval(hourStop);
});
reset.addEventListener("click", function () {
start.style.display = "block";
stop.style.display = "none";
clearInterval(miliSecondStop);
miliSecStart = 0;
milisecond.innerText = "00";
clearInterval(secondStop);
secStart = 0;
second.innerText = 0;
clearInterval(minStop);
minStart = 0;
h3CreateMin.style.display = "none";
clearInterval(hourStop);
hourStart = 0;
h3CreateHour.style.display = "none";
});
*{
margin: 0px;
padding: 0px;
box-sizing: border-box;
font-family: Arial, Helvetica, sans-serif;
color: white;
}
main{
width: 100%;
height: 500px;
background-color: #FEA600;
display: flex;
flex-direction: column;
align-items: center;
}
main div:first-child{
margin-top: 20px;
}
main div:first-child h1, main div:first-child h2,main div:first-child h3{
font-size: 4rem;
font-weight: 100;
text-align: center;
margin-top: 20px;
}
main div:first-child #time{
display: flex;
align-items: center;
justify-content: center;
width: 100%;
}
main div:first-child #time .time_s_m_h{
display: flex;
/* border: 1px solid rgb(0, 8, 255); */
align-items: flex-end;
justify-content: center;
width: 100px;
margin: 5px;
}
main div:first-child h3 .sigin{
font-size: 2rem;
/* border: 1px solid green; */
}
main div:first-child h3 #milisecond{
display: inline-block;
width: 50px;
/* border: 1px solid green; */
}
main div:last-child{
display: flex;
}
main div:last-child button{
padding: 20px;
width: 150px;
background-color: #FEA600;
font-size: 25px;
margin: 10px;
border:1px solid #ffffff;
cursor: pointer;
}
#stop,#reset{
display: none;
}
HTML
<body>
<main>
<div>
<h1>STOP WATCH</h1>
<!-- <h2>Vanilla JavaScript stopwatch</h2> -->
<div id="time">
<h3 class="time_s_m_h">
<span id="second" class="value">0</span>
<span class="sigin">S</span>
</h3>
<h3 id="h3">
<span id="milisecond" class="sigin">00</span>
</h3>
</div>
</div>
<div id="btnDiv">
<button id="start">Start</button>
<button id="stop">Stop</button>
<button id="reset">Reset</button>
</div>
</main>
<script src="app.js"></script>
</body>
You should use one timer to count.
Your code does not work exactly for second too.
If you click start and stop quickly, scond label will not increase.
It's because when you click start and stop, all timer will be reset.
So you should use one timer.
let start = document.getElementById("start");
let stop = document.getElementById("stop");
let reset = document.getElementById("reset");
let h3 = document.getElementById("h3");
let time = document.getElementById("time");
let h3CreateMin = document.createElement("h3");
let h3CreateHour = document.createElement("h3");
let milisecond = document.getElementById("milisecond");
let second = document.getElementById("second");
let minSpan = document.createElement("span");
let minSpanSigin = document.createElement("span");
let hourSpan = document.createElement("span");
let hourSpanSigin = document.createElement("span");
let miliSec = 0;
let s = true;
start.addEventListener("click", function () {
reset.style.display = "block";
stop.style.display = "block";
start.style.display = "none";
miliSecondStop = setInterval(() => {
miliSec++;
let milsecText = miliSec % 100;
let secText = (parseInt(miliSec / 100)) % 60;
let minText = (parseInt(miliSec / 6000)) % 60;
let hourText = parseInt(miliSec / 360000);
milisecond.innerText = milsecText;
second.innerText = secText;
if(minText>0){
time.prepend(h3CreateMin);
h3CreateMin.style.display = "block";
h3CreateMin.append(minSpan);
minSpan.classList = "value";
h3CreateMin.classList = "time_s_m_h";
h3CreateMin.append(minSpanSigin);
minSpanSigin.classList = "sigin";
minSpanSigin.innerText = "M";
minSpan.innerText = minText;
}
if(hourText > 0){
time.prepend(h3CreateHour);
h3CreateHour.style.display = "block";
h3CreateHour.classList = "time_s_m_h";
h3CreateHour.append(hourSpan);
hourSpan.classList = "value";
h3CreateHour.append(hourSpanSigin);
hourSpanSigin.classList = "sigin";
hourSpanSigin.innerText = "H";
hourSpan.innerText = hourText;
}
}, 10);
});
stop.addEventListener("click", function () {
start.style.display = "block";
stop.style.display = "none";
clearInterval(miliSecondStop);
});
reset.addEventListener("click", function () {
start.style.display = "block";
stop.style.display = "none";
clearInterval(miliSecondStop);
miliSec = 0;
milisecond.innerText = "00";
h3CreateMin.style.display = "none";
h3CreateHour.style.display = "none";
});
*{
margin: 0px;
padding: 0px;
box-sizing: border-box;
font-family: Arial, Helvetica, sans-serif;
color: white;
}
main{
width: 100%;
height: 500px;
background-color: #FEA600;
display: flex;
flex-direction: column;
align-items: center;
}
main div:first-child{
margin-top: 20px;
}
main div:first-child h1, main div:first-child h2,main div:first-child h3{
font-size: 4rem;
font-weight: 100;
text-align: center;
margin-top: 20px;
}
main div:first-child #time{
display: flex;
align-items: center;
justify-content: center;
width: 100%;
}
main div:first-child #time .time_s_m_h{
display: flex;
/* border: 1px solid rgb(0, 8, 255); */
align-items: flex-end;
justify-content: center;
width: 100px;
margin: 5px;
}
main div:first-child h3 .sigin{
font-size: 2rem;
/* border: 1px solid green; */
}
main div:first-child h3 #milisecond{
display: inline-block;
width: 50px;
/* border: 1px solid green; */
}
main div:last-child{
display: flex;
}
main div:last-child button{
padding: 20px;
width: 150px;
background-color: #FEA600;
font-size: 25px;
margin: 10px;
border:1px solid #ffffff;
cursor: pointer;
}
#stop,#reset{
display: none;
}
HTML
<body>
<main>
<div>
<h1>STOP WATCH</h1>
<!-- <h2>Vanilla JavaScript stopwatch</h2> -->
<div id="time">
<h3 class="time_s_m_h">
<span id="second" class="value">0</span>
<span class="sigin">S</span>
</h3>
<h3 id="h3">
<span id="milisecond" class="sigin">00</span>
</h3>
</div>
</div>
<div id="btnDiv">
<button id="start">Start</button>
<button id="stop">Stop</button>
<button id="reset">Reset</button>
</div>
</main>
<script src="app.js"></script>
</body>
I have an input field that add task. when i add the task a delete button appear next to each task
these task are stored in the local storage as an array
when i click delete button i want to delete the specific item not all the local storage
in general we use localStorage.removeItem(key);
let inputTask = document.querySelector('.input');
let tasks = document.querySelector('.tasks');
let add = document.querySelector('.add');
let alls = [];
//show tasks
function show() {
if (window.localStorage.task) {
let storedTaskes = JSON.parse(localStorage.getItem("task"));
storedTaskes.forEach((item) => {
let paragraph = document.createElement('p');
let deleteBtn = document.createElement('button');
deleteBtn.className = "delete";
deleteBtn.innerHTML = "Delete";
deleteBtn.id = item;
deleteBtn.setAttribute("onclick","deleteBtn(this)");
console.log(deleteBtn.value);
paragraph.innerHTML = item;
paragraph.appendChild(deleteBtn);
tasks.appendChild(paragraph);
});
}
}
// add tasks
add.onclick = function () {
if (inputTask.value.trim() !== "") {
alls.push(inputTask.value);
for (let i = 0; i < alls.length; i++) {
window.localStorage.setItem(`task`, JSON.stringify(alls));
}
}
inputTask.value = '';
show();
}
show();
//Delete Task
function deleteBtn(ob) {
let id = ob.id;
let taskArray = JSON.parse(localStorage.getItem("task"));
for(let i = 0; i < taskArray.length; i++){
if(taskArray[i] === id){
localStorage.removeItem(taskArray[i]);
}
}
}
body{
height: 90vh;
display: flex;
align-items: center;
justify-content: center;
}
.container {
display: flex;
align-items: center;
flex-direction: column;
gap: 20px;
}
.form {
background-color: #f0f0f0;
padding: 20px;
width: 500px;
text-align: center;
display: flex;
align-item: center;
justify-content: center;
gap: 15px;
}
.input{
border: 0;
outline: none;
padding: 10px 20px;
width: 300px;
border-radius: 5px;
}
.add,
.delete{
border: 0;
outline: none;
background-color: red;
color: white;
padding: 10px;
border-radius: 5px;
cursor: pointer;
}
.tasks {
background-color: #f0f0f0;
padding: 20px;
width: 500px;
}
p {
display: block;
background-color: white;
padding: 15px;
border-radius: 5px;
display: flex;
align-items: center;
justify-content: space-between;
}
<div class="container">
<div class="form">
<input type="text" class="input">
<input type="submit" class="add" value="Add Task">
</div>
<div class="tasks"></div>
</div>
How can i delete the specific item from the array in the local storage and show the new result for the user
You need to remove from the array and store the array again since that is how your other part works
function deleteBtn(ob) {
let id = ob.id;
let taskArray = JSON.parse(localStorage.getItem("task"));
taskArray = taskArray.filter(item => item != id)
localStorage.setItem("task", JSON.stringify(taskArray));
show()
}
ALso change
for (let i = 0; i < alls.length; i++) {
window.localStorage.setItem(`task`, JSON.stringify(alls));
}
to
localStorage.setItem(`task`, JSON.stringify(alls));
Here is a better version
I use delegation for the delete and save to localstorage without reading it again
I use a generated ID as id
Note I have to comment out the localstorage part since SO does not allow it
let inputTask = document.querySelector('.input');
let tasks = document.querySelector('.tasks');
let add = document.querySelector('.add');
let storedTasks // = localStorage.getItem("task"); // uncomment on your server
let allTasks = storedTasks ? JSON.parse(storedTasks) : [];
function show() {
tasks.innerHTML = allTasks
.map(task => `<p>${task.input} <button class="delete" data-id="${task.id}">X</button></p>`)
.join('<br/>');
}
// add tasks
add.onclick = function() {
const input = inputTask.value.trim();
if (input !== "") {
const id = allTasks.length; // use the length at this time
allTasks.push({ id:new Date().getTime(), input });
// localStorage.setItem("task",JSON.stringify(allTasks)); // uncomment on your server
inputTask.value = '';
show();
}
};
show();
document.querySelector(".tasks").addEventListener("click", function(e) {
const tgt = e.target;
if (tgt.classList.contains("delete")) {
let id = tgt.dataset.id;
allTasks = allTasks.filter(item => item.id != id)
tgt.closest("p").remove();
// localStorage.setItem("task",JSON.stringify(allTasks)); // uncomment on your server
}
});
body {
height: 90vh;
display: flex;
align-items: center;
justify-content: center;
}
.container {
display: flex;
align-items: center;
flex-direction: column;
gap: 20px;
}
.form {
background-color: #f0f0f0;
padding: 20px;
width: 500px;
text-align: center;
display: flex;
align-item: center;
justify-content: center;
gap: 15px;
}
.input {
border: 0;
outline: none;
padding: 10px 20px;
width: 300px;
border-radius: 5px;
}
.add,
.delete {
border: 0;
outline: none;
background-color: red;
color: white;
padding: 10px;
border-radius: 5px;
cursor: pointer;
}
.tasks {
background-color: #f0f0f0;
padding: 20px;
width: 500px;
}
p {
display: block;
background-color: white;
padding: 15px;
border-radius: 5px;
display: flex;
align-items: center;
justify-content: space-between;
}
<div class="container">
<div class="form">
<input type="text" class="input">
<input type="submit" class="add" value="Add Task">
</div>
<div class="tasks"></div>
</div>
function deleteBtn({id}) {
let taskArray = JSON.parse(localStorage.getItem("task")); // get the array
taskArray = taskArray.filter(ob=> ob.id != id ) // remove the id
localStorage.setItem("task", JSON.stringify(taskArray));
show()
}
but since you are using tasks.appendChild(paragraph)
you will have to change show function to
//show tasks
function show() {
if (window.localStorage.task) {
let storedTaskes = JSON.parse(localStorage.getItem("task"));
tasks.innerHTML = "" // here
storedTaskes.forEach((item) => {
let paragraph = document.createElement('p');
let deleteBtn = document.createElement('button');
deleteBtn.className = "delete";
deleteBtn.innerHTML = "Delete";
deleteBtn.id = item;
deleteBtn.setAttribute("onclick","deleteBtn(this)");
console.log(deleteBtn.value);
paragraph.innerHTML = item;
paragraph.appendChild(deleteBtn);
tasks.appendChild(paragraph)
});
}
}
I cant get the "if" part to work, thus not outputting the text Test0 or Test1 to my "Test" div after I press either of the links. I have checked for any error messages, which there are none of. I also added the changing color to check if it was the event listeners that were the problem, but that worked fine. So my only problem is that I can't get the text to output.
var testEl = document.querySelector("#test");
var menyEl = document.querySelectorAll("a");
for (var i = 0; i < menyEl.length; i++) {
menyEl[i].addEventListener("click", byttInfo);
}
function byttInfo(e) {
if (e.target.className === "ikke_aktiv") {
for (var i = 0; i < menyEl.length; i++) {
menyEl[i].className = "ikke_aktiv";
}
e.target.className = "aktiv"
}
if (e.target.value === 0) {
testEl.innerHTML = "Test0"
} else if (e.target.value === 1) {
testEl.innerHTML = "Test1"
}
}
.innpakning {
width: 80%;
background-color: #708790;
padding: 10px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.loddrett_meny {
display: flex, block;
flex: 1;
padding-top: 6px;
}
.loddrett_meny a {
display: block;
text-align: center;
padding: 12px;
margin: 4px;
color: white;
font-size: 20px;
text-decoration: none;
}
.loddrett_meny a:hover {
background-color: black;
border-radius: 8px;
transition: 0.75s;
}
.aktiv {
background-color: #3cb500;
}
.ikke_aktiv {
background-color: #555;
}
.innhold,
#test {
flex: 6;
height: auto;
background-color: #a6d4a3;
padding-left: 2px;
border-radius: 2px;
margin: 10px;
margin-right: 0px;
font-size: 20px;
}
<div class="innpakning">
<div class="loddrett_meny">
<a class="aktiv" value="0">Kapittel 20</a>
<a class="ikke_aktiv" value="1">Kapittel 20.1</a>
</div>
<div id="test"></div>
</div>
You need to use quotes around values or convert them to Number
if(e.target.value === "0"){
testEl.innerHTML = "Test0"
}else if(Number(e.target.value) === 1){
testEl.innerHTML = "Test1"
}
Adding on what Abdulah Proho said: You can't add the value attribute to a tags, so it's discarded and e.target.value. You may use data attributes for this:
var testEl = document.querySelector("#test");
var menyEl = document.querySelectorAll("a");
for (var i = 0; i < menyEl.length; i++) {
menyEl[i].addEventListener("click", byttInfo);
}
function byttInfo(e) {
if (e.target.className === "ikke_aktiv") {
for (var i = 0; i < menyEl.length; i++) {
menyEl[i].className = "ikke_aktiv";
}
e.target.className = "aktiv"
}
if (e.target.dataset.value === "0") {
testEl.innerHTML = "Test0"
} else if (e.target.dataset.value === "1") {
testEl.innerHTML = "Test1"
}
}
.innpakning {
width: 80%;
background-color: #708790;
padding: 10px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.loddrett_meny {
display: flex, block;
flex: 1;
padding-top: 6px;
}
.loddrett_meny a {
display: block;
text-align: center;
padding: 12px;
margin: 4px;
color: white;
font-size: 20px;
text-decoration: none;
}
.loddrett_meny a:hover {
background-color: black;
border-radius: 8px;
transition: 0.75s;
}
.aktiv {
background-color: #3cb500;
}
.ikke_aktiv {
background-color: #555;
}
.innhold,
#test {
flex: 6;
height: auto;
background-color: #a6d4a3;
padding-left: 2px;
border-radius: 2px;
margin: 10px;
margin-right: 0px;
font-size: 20px;
}
<div class="innpakning">
<div class="loddrett_meny">
<a class="aktiv" data-value="0">Kapittel 20</a>
<a class="ikke_aktiv" data-value="1">Kapittel 20.1</a>
</div>
<div id="test"></div>
</div>
e.target.value is undefined. Due to anchor tags usually not having value attribute. The 'a' elements don't have the data prototype for value.
You should try getting the value using:
e.target.getAttribute('value')
Also while comparing try using:
e.target.getAttribute('value') === '0'
Given the value you get from getAttribute function is a string the value getting compared with should also be a string.
The following works I have tested it as a snippet. Trying copying this entirely and replace it with your js. you need to use the getAttribute method to get the value.
var testEl = document.getElementById("test");;
var menyEl = document.querySelectorAll("a");
for (var i = 0; i < menyEl.length; i++) {
menyEl[i].addEventListener("click", byttInfo);
}
function byttInfo(e) {
if (e.target.className === "ikke_aktiv") {
for (var i = 0; i < menyEl.length; i++) {
menyEl[i].className = "ikke_aktiv";
}
e.target.className = "aktiv"
}
if (e.target.getAttribute("value") === "0"){
testEl.innerText = "Test0"
} else if (e.target.getAttribute("value") === "1") {
testEl.innerText = "Test1"
}
}
So I am working on creating a custom alert box. I've got most of the code the way I want it.
What I Want:
What I would like is to click the minus to fade the alert box so you can view the html behind it.
What is Wrong:
My issue is the min.onclick code does not click (clicking the minus sign does nothing).
See Below:
var b = document.getElementById('button-container');
var bg = document.createElement('div');
bg.setAttribute('id', 'alert-box');
bg.setAttribute('class','alert');
b.appendChild(bg);
var box = document.createElement('div');
box.setAttribute('id', 'alert-text');
box.setAttribute('class','alert-content');
box.setAttribute('display', 'block');
box.innerHTML = 'Fancy stuff happens here!<br>Look chess pieces';
bg.appendChild(box);
var min = document.createElement('span');
min.setAttribute('id','alert-min');
min.setAttribute('class','alert-min');
min.innerHTML = '−';
var s = true;
min.onclick = function() {
console.log('pressed!');
if(s) {
box.style.opacity = '.25';
s = false;
}
else{
box.style.opacity = '1';
s = true;
}
};
box.appendChild(min);
box.innerHTML += '<br><br>';
var images = ['q', 'n', 'r', 'b'];
var t = ['1/15', '7/70', '7/72', 'b/b1'];
for(var i = 0; i < images.length; i++) (function(i){
var btn = document.createElement('button');
btn.setAttribute('class','alert-button');
btn.setAttribute('id',images[i]+'btn');
btn.onclick = function () {
console.log('You clicked: ', images[i]);
};
box.appendChild(btn);
var img = document.createElement('img');
img.setAttribute('id',images[i]+'img');
img.setAttribute('src','https://upload.wikimedia.org/wikipedia/commons/thumb/'+t[i]+'/Chess_'+images[i]+'lt45.svg/45px-Chess_'+images[i]+'lt45.svg.png');
img.setAttribute('class','alert-image');
btn.appendChild(img);
})(i);
.alert {
display: block;
position: fixed;
z-index: 1;
padding-top: 10px;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgb(0,0,0);
background-color: rgba(0,0,0,0.4);
}
.alert-content {
background-color: #daac27;
margin: auto;
padding: 20px;
border: 1px solid #888;
width: 80%;
}
.alert-min {
color: #fff;
float: right;
font-size: 28px;
font-weight: bold;
}
.alert-min:hover,
.alert-min:focus {
color: #000;
text-decoration: none;
cursor: pointer;
}
<br><br><br>
O no! You can't see me!
<div id="button-container">
</div>
To be honest I have no idea why your script does not work. I did nothing but appending the close "button" after that loop. Now the click handler is working.
edit:
i also edited the other console.log due to it printed undefined
var b = document.getElementById('button-container');
var bg = document.createElement('div');
bg.setAttribute('id', 'alert-box');
bg.setAttribute('class','alert');
b.appendChild(bg);
var box = document.createElement('div');
box.setAttribute('id', 'alert-text');
box.setAttribute('class','alert-content');
box.setAttribute('display', 'block');
box.innerHTML = 'Fancy stuff happens here!<br>Look chess pieces';
bg.appendChild(box);
box.innerHTML += '<br><br>';
var images = ['q', 'n', 'r', 'b'];
var t = ['1/15', '7/70', '7/72', 'b/b1'];
for(var i = 0; i < images.length; i++) {
var btn = document.createElement('button');
btn.setAttribute('class','alert-button');
btn.setAttribute('id',images[i]+'btn');
let tmp = images[i]
btn.onclick = function () {
console.log('You clicked: ', tmp);
};
box.appendChild(btn);
var img = document.createElement('img');
img.setAttribute('id',images[i]+'img');
img.setAttribute('src','https://upload.wikimedia.org/wikipedia/commons/thumb/'+t[i]+'/Chess_'+images[i]+'lt45.svg/45px-Chess_'+images[i]+'lt45.svg.png');
img.setAttribute('class','alert-image');
btn.appendChild(img);
}
var min = document.createElement('span');
min.setAttribute('id','alert-min');
min.setAttribute('class','alert-min');
min.innerHTML = '−';
var s = true;
min.onclick = function() {
console.log('pressed!');
if(s) {
box.style.opacity = '.25';
s = false;
}
else{
box.style.opacity = '1';
s = true;
}
};
box.appendChild(min);
.alert {
display: block;
position: fixed;
z-index: 1;
padding-top: 10px;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgb(0,0,0);
background-color: rgba(0,0,0,0.4);
}
.alert-content {
background-color: #daac27;
margin: auto;
padding: 20px;
border: 1px solid #888;
width: 80%;
}
.alert-min {
color: #fff;
float: right;
font-size: 28px;
font-weight: bold;
}
.alert-min:hover,
.alert-min:focus {
color: #000;
text-decoration: none;
cursor: pointer;
}
<br><br><br>
O no! You can't see me!
<div id="button-container">
</div>
let n = 5;
let m = 5;
for(let j=0; j<m; j++){
for(let i=0; i<n; i++){
let boite = document.createElement("p");
boite.innerHTML = i+1;
document.querySelector("body").appendChild(boite);
}
document.write("<br>");
}
body{
margin: 20px;
background-color: white;
}
p{
background-color: black;
color: white;
padding: 20px;
width: 30px;
border: 2px solid white;
display: inline-block;
}
I'm trying to change the background-color of a paragraph in yellow when the number is even (so, in javascript).
I believe i have to write a condition with as a result something like
document.body.style.backgroundColor = "yellow";
but i don't know how to select the paragraph as i don't want the backgroundColor of the body to change
You can do this using a condition as follows
if((i+1)% 2 == 0){}
let n = 5;
let m = 5;
for(let j=0; j<m; j++){
for(let i=0; i<n; i++){
let boite = document.createElement("p");
boite.innerHTML = i+1;
if((i+1)% 2 == 0){
//voir si i+1 est pair ajouter le couleur
boite.style.backgroundColor = "yellow";
boite.style.color = "#000";
}
document.querySelector("body").appendChild(boite);
}
document.write("<br>");
}
body{
margin: 20px;
background-color: white;
}
p{
background-color: black;
color: white;
padding: 20px;
width: 30px;
border: 2px solid white;
display: inline-block;
}
Just give each paragraph a separate id then get the element's id then change it's style like this:
document.getElementById("ID").style.backgroundColor = "yellow";
To change the bacgkround color of a paragraph just use following:
<body>
<p id="paragraphToChange">Hello World!</p>
<script>
document.getElementById("paragraphToChange").style.background = "blue";
</script>
</body>
Here's how I'd do it:
let docBody = document.querySelector("body");
let n = 6;
let m = 6;
for (let j = 1; j < m; j++) {
for (let i = 1; i < n; i++) {
ifEven = (!(i % 2)) ? "style='background-color:yellow;color:#000;'" : "";
docBody.insertAdjacentHTML("beforeend", "<p " + ifEven + ">" + i + "</p>");
}
docBody.children[docBody.children.length - 1].insertAdjacentHTML("afterend", "<br>");
}
body {
margin: 20px;
background-color: white;
}
p {
background-color: black;
color: white;
padding: 20px;
width: 30px;
border: 2px solid white;
display: inline-block;
}