|
Выборка элементов querySelectorAll
Ребят, всем привет!
Пожалуйста укажите на ошибку в коде. Почему при клике на выбранных элементах они не пропадают? <h1 class="oli">вариант 1</h1> <p class="sd">вариант 2</p> <p class="oli">вариант 3</p>
var x = document.querySelectorAll('.oli');
document.x.addEventListener("click", myFunction);
function myFunction() {
var i;
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
}
|
Nlk,
что такое Цитата:
и на всякий случай у querySelectorAll нет метода addEventListener, нужен цикл по всем элементам для addEventListener |
"x" - коллекция элементов, по сути массив.
У массива нет метода "addEventListener", а у "document" не появилось свойство "x" от того, что вы создали переменную. Чтобы повесить обработчик на каждый элемент коллекции, нужно пробежаться по коллекции в цикле. В обработчике события "this" - ссылка на элемент, на котором произошло событие.
var x = document.querySelectorAll('.oli');
for(var i=0;i<x.length;i++)
x[i].addEventListener("click", myFunction);
function myFunction() {
this.style.display = "none";
}
|
Всем огромное спасибо, особенно за столь подробные разъяснения.
|
А скобочки для цикла for можно и не ставить?
|
Nlk, лучше ставить.
Если в блоке только 1 операция, то скобки можно опустить. |
Nexus,
Спасибо. Простите за мою навязчивость, в цикле for переменную i вы внесли в цикл, а в каких случаях могло быть полезно объявлять переменную вне цикла? |
Nlk, не знаю :)
Область видимости-то не поменяется от того, что переменная будет объявлена до объявления аргументов цикла. Если циклов несколько и все юзают одну переменную, то её можно определить до создания цикла или в аргументах первого цикла, а в остальных циклах просто изменять её значение. Т.е. так:
for(var i=0;i<10;i++){};
for(i=0;i<10;i++){};
|
Nexus,
Спасибо за ваши ответы, последний раз попрошу вашего внимания. Скажите а можно реализовать выключение всех потомков схожим образом:
var x = document.querySelectorAll('.oli');
for(var i=0;i<x.length;i++)
x[i].addEventListener("click", myFunction);
function myFunction() {
this.childNodes.style.display = "none";
}
|
Цитата:
|
рони,
Спасибо, касаемо варианта с классом, по css не могу сообразить как должно выглядеть.
function myFunction() {
this.classList.add("disable");
}
.disable .submenu {display: none;}
|
Не знаю, при чем тут .submenu, но
<style>
.disable, .submenu {display: none;}
</style>
<h1 class="oli">вариант 1</h1>
<p class="sd">вариант 2</p>
<p class="oli">вариант 3</p>
<script>
var x = document.querySelectorAll('.oli');
for(var i=0;i<x.length;i++)
x[i].addEventListener("click", myFunction);
function myFunction() {
this.classList.add("disable");
}
</script>
|
Цитата:
Цитата:
|
Nlk,
<meta charset="utf-8">
<style>
.oli {
background-color: #EEE8AA;
cursor: pointer;
}
.disable > .submenu {display: none;}
</style>
<div class="oli">вариант 1 <ul class="submenu"><li>test</li></ul></div>
<div class="sd">вариант 2</div>
<div class="oli">вариант 3 <ul class="submenu"><li>test</li></ul></div>
<script>
var x = document.querySelectorAll('.oli');
for(var i=0;i<x.length;i++)
x[i].addEventListener("click", myFunction);
function myFunction() {
this.classList.add("disable");
}
</script>
|
Цитата:
Цитата:
|
Я вам всем ужасно благодарен на этом форуме! За ваше терпение и понимание.
А как мне реализовать переключение при повторном клике, как то так или использовать toggle?
function myFunction() {
if (this.classList.add("disable")) {
this.classList.remove("disable");
}
}
или
this.classList.contains('show-submenu') ? hideSubMenu(el) : showSubMenu(el);
|
function myFunction() {
this.classList.toggle("disable");
}
|
Nlk,
:-?
function myFunction() {
this.classList.toggle("disable");
}
|
Спасибо большое всё работает)
Как завершу выложу попрошу проверить. А не могли бы рассказать про данную альтернативную реализацию меню.
[].slice.call(document.querySelectorAll('.dropdown .nav-link')).forEach(function(el){
el.addEventListener('click', onClick, false);
});
Как я понимаю: [].slice - в пустой массив производится копирование call - посредством контекста (document.querySelectorAll('.dropdown .nav-link')) - из nodeList'а .forEach - который посредством метода forEach делает полноценный массив из классов. |
Nlk,
коллекции-не-массивы |
Цитата:
Цитата:
|
рони,
Спасибо, скажите а элементы классов .dropdown и .nav-link оказываются в одном массиве? |
Nlk,
document.querySelectorAll('.dropdown .nav-link')
Если вопрос по этой выборке, то "querySelectorAll" вернет коллекцию элементов с классом "nav-link", которые являются детьми для элементов с классом "dropdown". Родители при таком селекте в коллекцию не попадут. |
Nexus,
Теперь всё ясно, а я голову ломал. Огромнейшее Вам спасибо! |
Выпадающее меню работу которого вы мне сейчас объяснили https://codepen.io/ryanmorr/pen/LVzYmx
|
А можно в дальнейшем ещё вопросы в этой ветке задавать, без прямой связи с темой?
В данном отрывке кода не могу понять как метод contains используется? Ведь он призван проверять присутствие класса в элементе!?
container.addEventListener('click', function(e){
if(isShowingSidebar() && main.contains(e.target)){
e.preventDefault();
hideSidebar();
}
}, true);
|
|
Nexus,
Спасибо за ссылку, ознакомился. Но не могу понять, метод contains необходим для проверки вложенности элементов. А в данном случае используется проверка на событие, так? |
Nlk, нет.
Цитата:
|
Nexus,
извините за мою тупость, но я не понимаю что в данной строке кода происходит? Что e.target событие понятно. main.contains(e.target) |
Цитата:
В этой строке проверяется является ли элемент, на котором произошло событие дочерним по отношению к элементу main или элемент "main" и есть тот элемент, на котором это событие произошло. |
Nexus,
огромное спасибо, что разъяснили столь подробно. |
Скажите метод matches подходит для проверки класса по которому было произведено событие?
window.onclick = function(event) {
if (event.target.matches('.dropbtn')) {}
|
Цитата:
|
рони,
Спасибо за ответы, я знал что пример рабочий, просто хотел уточнить возможные нюансы. Как к примеру вы упомянули про closest, я в первые про него слышу. В остальном постараюсь понапрасну не писать. |
Скажите пожалуйста, у меня такой вопрос.
Есть модальное окно, при его всплытии работает скролл сайта. Могу ли я от него избавиться, таким путем задав body class или id, и впоследствии в момент всплытия popup-окна добавить ему данный класс. К примеру:
.popup-active. classBody {
overwlov:hidden;
}
|
Или это может вообще считается не очень хорошей практикой body задавать класс?
|
Nlk, нормальная практика.
У вас css малость кривоват.
body.popup-active{overflow:hidden;}
|
Nexus,
в данном случае если я не ошибаюсь overflow:hidden мы задаём классу .popup-active, а мне нужно overflow:hidden задать body чтобы при всплытии моего popup-окна прокрутка сайта исчезла. Или я чего -то не понимаю.. |
Nlk, нельзя добавить класс дочернему элементу, а свойство объявить его родителю, поэтому когда popup показывается тэгу body добавляете класс "popup-active".
У body с классом "popup-active" скроллбары отключаем (код я привел выше). Тут вроде бы адекватное описание селекторов: https://misha.blog/css/selektoryi.html |
| Часовой пояс GMT +3, время: 10:49. |
|