我想知道当forEach的回调未直接引用所需元素时如何选择子代。
const $searchField = document.querySelectorAll('.js-search');
if ($searchField.length > 0) {
$searchField.forEach(function($el) {
// $el = .js-search
$el.addEventListener('click', function(event) {
$el.classList.add('is-active');
});
// Here, i need to target the input, not .js-search
$el.addEventListener('keyup', function(event) {
if ($el.value.length > 0) {
$el.classList.add('is-active');
} else {
$el.classList.remove('is-active')
}
//});
});
}
在这里,$el
指的是父.js-search
,因此很明显,键盘无法工作。我想确保选择输入,但是我不确定如何正确选择输入。
演示在Codepen上可用!
目标是在搜索完成后(至少有1个字符)保持状态为活动状态。
谢谢
答案 0 :(得分:3)
只需选择子input
的{{1}},而不是.value
的{{1}}:
$el
请注意,如果您不希望进行.value
,则不需要-在空集合上调用const $searchField = document.querySelectorAll('.js-search');
$searchField.forEach(function($el) {
// $el = .js-search
$el.addEventListener('click', function() {
$el.classList.add('is-active');
});
const input = $el.querySelector('input');
input.addEventListener('keyup', function() {
if (input.value.length > 0) {
$el.classList.add('is-active');
} else {
$el.classList.remove('is-active')
}
});
});
不会引发错误,它不会迭代任何内容。 / p>
您还可以考虑为if
添加一个polyfill(如果还没有的话),因为较旧的浏览器不支持它。 (或者,将集合转换为数组,或使用forEach
)
基于意见的观点,但不需要在变量名前加上NodeList.prototype.forEach
-这不是PHP。通常,当指示某事物是jQuery(Array.prototype.forEach.call
)集合时,会使用$
前缀。如果您要进行DOM操作,可能最好不要使用以$
开头的变量名,以免引起以后代码阅读者的困惑。
答案 1 :(得分:1)
您可以使用this.querySelector('input');
,其中this
将成为父元素,而querySelector
将获得第一个input
子元素
const $searchField = document.querySelectorAll('.js-search');
if ($searchField.length > 0) {
$searchField.forEach(function($el) {
$el.addEventListener('click', function(event) {
$el.classList.add('is-active');
let $input = this.querySelector('input');
$input.addEventListener('keyup', function(et) {
console.log(et.target.value)
});
});
});
document.addEventListener('click', function(event) {
if (!$(event.target).closest('.js-search').length) {
closeSearchs();
}
$('.js-search.is-active').not($(event.target).closest('.js-search')).removeClass('is-active');
});
}
function closeSearchs() {
$searchField.forEach(function($el) {
$el.classList.toggle('is-active');
});
}
.field-search {
position: relative;
&.is-active {
.search-input {
background-color: rgba(0, 0, 0, .35);
color: white;
}
}
.search-input {
background: none;
box-shadow: none;
border-radius: 4px;
color: black;
font-size: 1.2rem;
font-weight: 400;
height: 100%;
outline: none;
padding-left: 4.5rem;
transition: background-color .2s;
width: 365px;
&::placeholder {
color: black;
font-size: 1.2rem;
font-weight: 400;
}
&.is-active {
background-color: rgba(255, 255, 255, .1);
}
}
}
<div class="field-search js-search">
<input type="search" class="search-input" placeholder="Search...">
</div>