Я могу скрыть дочерний элемент, добавив каждый дочерний элемент в этот код:
window.addEventListener('mouseup', function(event){
let children = parent[0].children[0]
if (event.target != children && event.target.parentNode != children){
children.style.display = 'none';
}
});
Но как можно скрыть щелчок дочернего элемента ul за пределами дочернего элемента ul (с циклом for или чем-то еще), не добавляя этот код для каждого дочернего элемента?
В этом коде я показываю дочерний элемент ul при нажатии на родительский элемент li
var parent = document.querySelectorAll('body > ul > li');
parent[0].addEventListener('click', function () {
parent[0].children[0].style.display = 'block';
});
parent[1].addEventListener('click', function () {
parent[1].children[0].style.display = 'block';
});
parent[2].addEventListener('click', function () {
parent[2].children[0].style.display = 'block';
});
window.addEventListener('mouseup', function(event){
let children = parent[0].children[0]
if (event.target != children && event.target.parentNode != children){
children.style.display = 'none';
}
});ul > li > ul {
display: none;
}
ul, li {
width: max-content;
}<ul>
<li>parent1
<ul>
<li>child1</li>
</ul>
</li>
<li>parent2
<ul>
<li>child2</li>
</ul>
</li>
<li>parent3
<ul>
<li>child3</li>
</ul>
</li>
</ul>Спасибо



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Если я понимаю вашу проблему: пользователь нажимает на любой из дочерних элементов, в дочернем состоянии не должно быть никаких изменений (скрыть). Вы можете использовать приведенный ниже код (я предполагаю, что вы используете только ES5). Если вы хотите скрыть дочерние элементы по родительскому щелчку, удалите метод isParentClick().
var parent = document.querySelectorAll('body > ul > li');
var len = parent.length;
for(var i=0;i<len;i++){
parent[i].addEventListener('click', function (event) {
if (event.target !== event.currentTarget.children[0].children[0]){
if (event.currentTarget.children[0].style.display === 'block'){
event.currentTarget.children[0].style.display = 'none';
} else {
event.currentTarget.children[0].style.display = 'block';
}
}
});
}
window.addEventListener('mouseup', function(event){
if (isParentClick()){
return false;
}
if (isChildClick(event)){
return false;
}
for(var i=0;i<len;i++){
parent[i].children[0].style.display = 'none';
}
});
function isParentClick(){
for(var i=0;i<len;i++){
if (parent[i] === event.target){
return true;
}
}
return false;
}
function isChildClick(event){
for(var i=0;i<len;i++){
if (parent[i].children[0].children[0] === event.target){
return true;
}
}
return false;
}ul > li > ul {
display: none;
}
ul, li {
width: max-content;
}<ul>
<li>parent1
<ul>
<li>child1</li>
</ul>
</li>
<li>parent2
<ul>
<li>child2</li>
</ul>
</li>
<li>parent3
<ul>
<li>child3</li>
</ul>
</li>
</ul>@GalibHasanov Вы можете проверить состояние отображения chid, щелкнув родительский элемент. Пожалуйста, проверьте обновленный код.
Но теперь я нажимаю на ребенка, а затем его прячу. Как этого избежать?
Хм. Если мы нажимаем на дочерний элемент, мы также запускаем событие родительского щелчка. Я поставил условие в обновленной кодовой базе. Теперь он должен работать.
Вы можете использовать document.querySelectorAll вместо нацеливания на отдельные элементы
Поскольку для отображения дочернего элемента щелчок будет на li, поэтому снова выполните querySelector, выберите ul и добавьте стиль.
Обратите внимание на использование stopPropagation. К body прикреплено еще одно событие, так что любой щелчок по body скроет дочерний элемент. Использование stopPropagation заключается в том, чтобы предотвратить событие из фазы bubling, щелчок по li и щелчок по телу будут происходить одновременно.
Тело окаймлено красным
var parent = document.querySelectorAll('body > ul > li');
parent.forEach(function(item) {
item.addEventListener('click', function(e) {
e.stopPropagation()
item.querySelector('ul').style.display = 'block';
})
document.body.addEventListener('click', function(e) {
document.querySelectorAll('.parent').forEach(function(item) {
item.querySelector('ul').style.display = 'none'
})
})
})ul>li>ul {
display: none;
}
ul,
li {
width: max-content;
}
body {
border: 1px solid red;
}<ul>
<li class='parent'>parent1
<ul>
<li>child1</li>
</ul>
</li>
<li class='parent'>parent2
<ul>
<li>child2</li>
</ul>
</li>
<li class='parent'>parent3
<ul>
<li>child3</li>
</ul>
</li>
</ul>Но как сделать, чтобы при повторном нажатии родительского <li> скрыть дочерний <ul>. Например, щелкните parent1, покажите child1, а когда снова щелкните parent1, скройте child1.
@GalibHasanov взгляните на toggle
Я меняю код. Похоже, он работает, но теперь, когда я нажимаю на дочерний элемент, он скрывается. jsfiddle.net/tr2uk9fs/3
Но как сделать, чтобы при повторном нажатии родительского <li> скрыть дочерний <ul>. Например, щелкните parent1, покажите child1, а когда снова щелкните parent1, скройте child1. Спасибо