如何在元素外添加点击事件?
How to add a click event outside an element?
我当前的代码通过添加 class 通过单击打开输入。当用户单击关闭输入时,我无法添加第二次单击以删除添加的 class。我添加了第二次点击事件,但它只是阻止了我的第一次点击事件。
有没有其他方法可以使用纯 JavaScript 来解决这个问题?
(注释掉失败的尝试。)
let searchElement = document.querySelector('#searchElement');
let offCanvas = document.querySelector('#main');
searchElement.addEventListener('click', () => {
searchElement.classList.add('extendInputSearch');
});
// offCanvas.addEventListener('click', () => {
// searchElement.classList.remove('extendInputSearch');
// });
* {
padding: 0;
margin: 0;
}
html,
body {
height: 100%;
width: 100%;
}
main {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
background-color: #e1e2f1;
}
form {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
}
input {
width: 100%;
height: 32px;
border: none;
outline: none;
font-size: 1rem;
}
.inputSearch {
display: flex;
align-items: center;
width: 100%;
max-width: 15px;
padding: 8px 20px;
background-color: #ffffff;
border: 1px solid transparent;
border-radius: 6px;
transition: all 0.6s cubic-bezier(0.16, 1, 0.3, 1);
}
.inputSearch:hover {
border: 1px solid #7e51fa;
}
.inputSearch i {
color: #7e51fa;
margin-right: 20px;
}
.extendInputSearch {
max-width: 400px;
}
<link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.10.0/css/all.css" integrity="sha384-AYmEC3Yw5cVb3ZcuHtOA93w35dYTsvhLPVnYs9eStHfGJvOvKxVfELGroGkvsg+p" crossorigin="anonymous"/>
<main id="main">
<form>
<div id="searchElement" class="inputSearch">
<i class="fas fa-search"></i>
<input type="text" placeholder="Search">
</div>
</form>
</main>
试一试:
let searchElement = document.querySelector('#searchElement');
let offCanvas = document.querySelector('#main');
searchElement.addEventListener('click', () => {
searchElement.classList.add('extendInputSearch');
});
document.addEventListener('click', (e) => {
const searchElement = document.querySelector('#searchElement');
if (e.target != searchElement && e.target != searchElement.querySelector('i') && e.target != searchElement.querySelector('input')) {
searchElement.classList.remove('extendInputSearch');
}
});
* {
padding: 0;
margin: 0;
}
html,
body {
height: 100%;
width: 100%;
}
main {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
background-color: #e1e2f1;
}
form {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
}
input {
width: 100%;
height: 32px;
border: none;
outline: none;
font-size: 1rem;
}
.inputSearch {
display: flex;
align-items: center;
width: 100%;
max-width: 15px;
padding: 8px 20px;
background-color: #ffffff;
border: 1px solid transparent;
border-radius: 6px;
transition: all 0.6s cubic-bezier(0.16, 1, 0.3, 1);
}
.inputSearch:hover {
border: 1px solid #7e51fa;
}
.inputSearch i {
color: #7e51fa;
margin-right: 20px;
}
.extendInputSearch {
max-width: 400px;
}
<link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.10.0/css/all.css" integrity="sha384-AYmEC3Yw5cVb3ZcuHtOA93w35dYTsvhLPVnYs9eStHfGJvOvKxVfELGroGkvsg+p" crossorigin="anonymous"/>
<main id="main">
<form>
<div id="searchElement" class="inputSearch">
<i class="fas fa-search"></i>
<input type="text" placeholder="Search">
</div>
</form>
</main>
您尝试的问题是删除 class 的事件侦听器应用于整个 #main
元素, 包括 searchElement。这意味着两个事件侦听器都应用于 searchElement,当您单击 searchElement 时,首先添加 class(使用第一个侦听器)然后删除(使用第二个侦听器)。
要使其正常工作,您需要更改第二个侦听器以专门排除 searchElement。例如,在这段代码中,我们为整个文档添加了一个点击监听器。在侦听器中,我们使用事件参数上的 Node.contains()
函数检查点击是否在 searchElement 之外。如果点击的元素不是 searchElement 的子元素(即点击在 searchElement 之外),我们从 searchElement 中删除 extendInputSearch
class。
let searchElement = document.querySelector('#searchElement');
searchElement.addEventListener('click', () => {
searchElement.classList.add('extendInputSearch');
});
document.addEventListener('click', (e) => {
if(!searchElement.contains(e.target)){
searchElement.classList.remove('extendInputSearch');
}
});
* {
padding: 0;
margin: 0;
}
html,
body {
height: 100%;
width: 100%;
}
main {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
background-color: #e1e2f1;
}
form {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
}
input {
width: 100%;
height: 32px;
border: none;
outline: none;
font-size: 1rem;
}
.inputSearch {
display: flex;
align-items: center;
width: 100%;
max-width: 15px;
padding: 8px 20px;
background-color: #ffffff;
border: 1px solid transparent;
border-radius: 6px;
transition: all 0.6s cubic-bezier(0.16, 1, 0.3, 1);
}
.inputSearch:hover {
border: 1px solid #7e51fa;
}
.inputSearch i {
color: #7e51fa;
margin-right: 20px;
}
.extendInputSearch {
max-width: 400px;
}
<link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.10.0/css/all.css" integrity="sha384-AYmEC3Yw5cVb3ZcuHtOA93w35dYTsvhLPVnYs9eStHfGJvOvKxVfELGroGkvsg+p" crossorigin="anonymous"/>
<main id="main">
<form>
<div id="searchElement" class="inputSearch">
<i class="fas fa-search"></i>
<input type="text" placeholder="Search">
</div>
</form>
</main>
我当前的代码通过添加 class 通过单击打开输入。当用户单击关闭输入时,我无法添加第二次单击以删除添加的 class。我添加了第二次点击事件,但它只是阻止了我的第一次点击事件。
有没有其他方法可以使用纯 JavaScript 来解决这个问题?
(注释掉失败的尝试。)
let searchElement = document.querySelector('#searchElement');
let offCanvas = document.querySelector('#main');
searchElement.addEventListener('click', () => {
searchElement.classList.add('extendInputSearch');
});
// offCanvas.addEventListener('click', () => {
// searchElement.classList.remove('extendInputSearch');
// });
* {
padding: 0;
margin: 0;
}
html,
body {
height: 100%;
width: 100%;
}
main {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
background-color: #e1e2f1;
}
form {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
}
input {
width: 100%;
height: 32px;
border: none;
outline: none;
font-size: 1rem;
}
.inputSearch {
display: flex;
align-items: center;
width: 100%;
max-width: 15px;
padding: 8px 20px;
background-color: #ffffff;
border: 1px solid transparent;
border-radius: 6px;
transition: all 0.6s cubic-bezier(0.16, 1, 0.3, 1);
}
.inputSearch:hover {
border: 1px solid #7e51fa;
}
.inputSearch i {
color: #7e51fa;
margin-right: 20px;
}
.extendInputSearch {
max-width: 400px;
}
<link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.10.0/css/all.css" integrity="sha384-AYmEC3Yw5cVb3ZcuHtOA93w35dYTsvhLPVnYs9eStHfGJvOvKxVfELGroGkvsg+p" crossorigin="anonymous"/>
<main id="main">
<form>
<div id="searchElement" class="inputSearch">
<i class="fas fa-search"></i>
<input type="text" placeholder="Search">
</div>
</form>
</main>
试一试:
let searchElement = document.querySelector('#searchElement');
let offCanvas = document.querySelector('#main');
searchElement.addEventListener('click', () => {
searchElement.classList.add('extendInputSearch');
});
document.addEventListener('click', (e) => {
const searchElement = document.querySelector('#searchElement');
if (e.target != searchElement && e.target != searchElement.querySelector('i') && e.target != searchElement.querySelector('input')) {
searchElement.classList.remove('extendInputSearch');
}
});
* {
padding: 0;
margin: 0;
}
html,
body {
height: 100%;
width: 100%;
}
main {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
background-color: #e1e2f1;
}
form {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
}
input {
width: 100%;
height: 32px;
border: none;
outline: none;
font-size: 1rem;
}
.inputSearch {
display: flex;
align-items: center;
width: 100%;
max-width: 15px;
padding: 8px 20px;
background-color: #ffffff;
border: 1px solid transparent;
border-radius: 6px;
transition: all 0.6s cubic-bezier(0.16, 1, 0.3, 1);
}
.inputSearch:hover {
border: 1px solid #7e51fa;
}
.inputSearch i {
color: #7e51fa;
margin-right: 20px;
}
.extendInputSearch {
max-width: 400px;
}
<link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.10.0/css/all.css" integrity="sha384-AYmEC3Yw5cVb3ZcuHtOA93w35dYTsvhLPVnYs9eStHfGJvOvKxVfELGroGkvsg+p" crossorigin="anonymous"/>
<main id="main">
<form>
<div id="searchElement" class="inputSearch">
<i class="fas fa-search"></i>
<input type="text" placeholder="Search">
</div>
</form>
</main>
您尝试的问题是删除 class 的事件侦听器应用于整个 #main
元素, 包括 searchElement。这意味着两个事件侦听器都应用于 searchElement,当您单击 searchElement 时,首先添加 class(使用第一个侦听器)然后删除(使用第二个侦听器)。
要使其正常工作,您需要更改第二个侦听器以专门排除 searchElement。例如,在这段代码中,我们为整个文档添加了一个点击监听器。在侦听器中,我们使用事件参数上的 Node.contains()
函数检查点击是否在 searchElement 之外。如果点击的元素不是 searchElement 的子元素(即点击在 searchElement 之外),我们从 searchElement 中删除 extendInputSearch
class。
let searchElement = document.querySelector('#searchElement');
searchElement.addEventListener('click', () => {
searchElement.classList.add('extendInputSearch');
});
document.addEventListener('click', (e) => {
if(!searchElement.contains(e.target)){
searchElement.classList.remove('extendInputSearch');
}
});
* {
padding: 0;
margin: 0;
}
html,
body {
height: 100%;
width: 100%;
}
main {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
background-color: #e1e2f1;
}
form {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
}
input {
width: 100%;
height: 32px;
border: none;
outline: none;
font-size: 1rem;
}
.inputSearch {
display: flex;
align-items: center;
width: 100%;
max-width: 15px;
padding: 8px 20px;
background-color: #ffffff;
border: 1px solid transparent;
border-radius: 6px;
transition: all 0.6s cubic-bezier(0.16, 1, 0.3, 1);
}
.inputSearch:hover {
border: 1px solid #7e51fa;
}
.inputSearch i {
color: #7e51fa;
margin-right: 20px;
}
.extendInputSearch {
max-width: 400px;
}
<link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.10.0/css/all.css" integrity="sha384-AYmEC3Yw5cVb3ZcuHtOA93w35dYTsvhLPVnYs9eStHfGJvOvKxVfELGroGkvsg+p" crossorigin="anonymous"/>
<main id="main">
<form>
<div id="searchElement" class="inputSearch">
<i class="fas fa-search"></i>
<input type="text" placeholder="Search">
</div>
</form>
</main>