|
Выборка элементов 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, время: 18:27. |
|