I currently practicing HTML/CSS/DOM(JS) and more focusing on DOM right now. For now, I try to clone the instagram for studying HTML/CSS/DOM. In the DOM part(js), when I try to use event(EventListener), I am curious that "If the other project or Website need so many EventListener,Do I have to declare name.addEventListener("event name", function()) every-time? Can I declare the EventListener at the body or wrapper(div-class) and using event.target, so I don't need to be declared EventListener several times?" I am sorry if I explain so weird and messy. I tried to explain my brain storming thought. I will share my code just in case
This is HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>
Westagram!
</title>
<link rel="stylesheet" href="style/login.css" type="text/css">
<link rel="stylesheet" href="style/common.css" type="text/css">
<!-- <link rel="stylesheet" href="js/login.js"> -->
</head>
<body>
<!-- 아래 모든 div들을 포함하는 제일 상위 Container -->
<div >
<div >
<p >Westagram</p>
</div>
<!-- 로그인 섹션 -->
<div >
<div >
<input type="text" id="text" placeholder="Phone number, username, or email" />
</div>
<div >
<input type="password" id="password" placeholder="Password">
</div>
<div >
<button >Log in
</button>
</div>
</div>
<!-- 비밀번호 찾는 섹션 -->
<div >
<a >Forgot Password</a>
</div>
</div>
<script src="js/login.js"></script>
</html>
This is CSS file
*{
padding: 0;
margin: 0;
text-decoration: none;
list-style: none;
box-sizing: border-box;
}
@font-face {
font-family: instagramFont;
src: url("../src/westagram.ttf") format("opentype");
}
.wrapper {
margin: 250px 250px 0px 250px;
padding: 30px;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
border: solid 1px #D3D3D3;
width: 500px;
height: 500px;
}
.wrapper .login-container {
width: 400px;
height: 500px;
}
.wrapper .login-container .id{
margin-top: 70px;
}
#text {
width: 100%;
height: 45px;
border: solid 1px #D3D3D3;
border-radius: 5px;
padding-left: 15px;
}
#password {
width: 100%;
height: 45px;
border: solid 1px #D3D3D3;
border-radius: 5px;
padding-left: 15px;
}
.wrapper .login-container .bt .login-btn{
width: 100%;
height: 45px;
border: solid 1px #D3D3D3;
border-radius: 5px;
/*background-color: #ff000;*/
background-color: #B2DFFC;
cursor: pointer;
/*padding-left: 15px;*/
}
.wrapper .login-container .pw {
margin-top: 10px;
margin-bottom: 10px;
}
.wrapper .login-container.bt {
}
.westagram {
font-size : 60%;
font-family: instagramFont;
font-size: 5rem;
}
This is JS code
let id = document.querySelector("#text");
let password = document.querySelector("#password");
let loginButton = document.querySelector(".login-btn")
function active() {
if(id.value.length > 0 && password.value.length > 0){
loginButton.style.backgroundColor='#0095F6';
} else {
loginButton.style.backgroundColor='#B2DFFC'
}
}
id.addEventListener("keyup", active)
password.addEventListener("keyup", active)
I really appreciate your help in advance!
CodePudding user response:
Can you add one event listener? Yes. It is event delegation. You use the target and you do checks to see if it is the element. Multiple ways to check if the element is the same. You can use is(), you can check a class/id/attribute or you can see if the elements match a reference
document.body.addEventListener("input", function (evt) {
const target = evt.target;
if (target.closest('#inp1, #inp2')) {
console.log(target.value);
}
});
<input type="text" id="inp1" class="loginInput" />
<input type="text" id="inp2" class="loginInput" />
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
document.body.addEventListener("input", function (evt) {
const target = evt.target;
if (target.classList.contains("loginInput")) {
console.log(target.value);
}
});
<input type="text" id="inp1" class="loginInput" />
<input type="text" id="inp2" class="loginInput" />
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
var inp1 = document.querySelector("#inp1");
var inp2 = document.querySelector("#inp2");
document.body.addEventListener("input", function(evt) {
const target = evt.target;
if (target === inp1 || target === inp2) {
console.log(target.value);
}
});
<input type="text" id="inp1" class="loginInput" />
<input type="text" id="inp2" class="loginInput" />
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
In the inputs are in the same container, you might not even care what input it is. Just bind the event listener to the parent. Any action inside of it will be picked up.
document.querySelector('#login').addEventListener("input", function(evt) {
const target = evt.target;
console.log(target.value);
});
<form id="login">
<input type="text" id="inp1" class="loginInput" />
<input type="text" id="inp2" class="loginInput" />
</form>
<iframe name="sif4" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
You can write a function to prevent repeating exactly the same event listeners:
function eventHandler(event, func, target ){
return target.addEventListener(event, func);
}
eventHandler("keyup", active, id);