Я хочу настроить таргетинг на дочерний элемент следующего родственного брата без использования класса или идентификатора

Вот HTML-код (который появляется в нескольких местах, но к каждому виду следует относиться по-разному):

<div class = "foot-nav-heading">Click me!</div>
    <div class = "textwidget">
       <ul class = "quick-link accordion-content">
          <li>Test</li>
       </ul>
</div>

Вот код javascript:

var accordions = document.getElementsByClassName("foot-nav-heading");
  for (var i = 0; i < accordions.length; i++) {
     accordions[i].onclick = function() {
       this.classList.toggle('is-open');

   var content = this.nextElementSibling;
   if (content.style.maxHeight) {
   // accordion is currently open, so close it
 content.style.maxHeight = null;
   } else {
  // accordion is currently closed, so open it
 content.style.maxHeight = content.scrollHeight + "px";
   }
 }
}

Я хочу настроить таргетинг на «ul» в элементе «div.textwidget». я пробовал

var content = this.next.(".text-widget").find(".accordion-content")

Но это не работает.

Заранее спасибо!

this.querySelector('.accordion-content');не уверен, что это сработает, но попробуй;)
john Smith 18.12.2018 18:28
document.querySelector('div.textwidget > ul.quick-link.accordion-content');
j08691 18.12.2018 18:28

Обратите внимание, что приведенный ниже код появляется несколько раз в разных местах: <div class = "foot-nav-heading"> Нажми меня! </div> <div class = "textwidget"> <ul class = "quick-link accordion- content "> <li> Тест </li> </ul> </div>

Edward Bella 18.12.2018 18:34
document.querySelectorAll ...
j08691 18.12.2018 18:39

@ j08691 Что я заменю на "document.querySelector ('div.textwidget> ul.quick-link.accordion-content');"? Не так хорошо с Javascript. Спасибо

Edward Bella 18.12.2018 18:47
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
5
59
2

Ответы 2

Ваш код работает! Проблема не в брате, проблема в том, что вы не можете установить высоту css равной null

var accordions = document.getElementsByClassName("foot-nav-heading");
  for (var i = 0; i < accordions.length; i++) {
     accordions[i].onclick = function() {
       this.classList.toggle('is-open');
   var content = this.nextElementSibling;

   if (content.style.maxHeight != "0px") {
   // accordion is currently open, so close it
 content.style.maxHeight = "0px";
   } else {
  // accordion is currently closed, so open it
 content.style.maxHeight = "200px";
   }
 }
}
<div class = "foot-nav-heading">Click me!</div>
    <div class = "textwidget">
       <ul class = "quick-link accordion-content">
          <li>Test</li>
       </ul>
</div>

Here is the javascript code:

<div class = "foot-nav-heading">Click me!</div>
    <div class = "textwidget">
       <ul class = "quick-link accordion-content">
          <li>Test</li>
       </ul>
</div>

Here is the javascript code:

РЕДАКТИРОВАТЬ:
То, что вы пробовали со своим кодом, - это получить nextSibling. Но у вас могут быть дополнительные текстовые узлы с возвратом каретки. Попробуйте этот фрагмент:

document.querySelectorAll(".textwidget")[0].childNodes.forEach(function(el){
  console.info(el.nodeName,el.nodeType);
});
<div class = "foot-nav-heading">Click me!</div>
    <div class = "textwidget">
    <ul class = "quick-link accordion-content">
          <li>Test</li>
       </ul>
</div>

Поэтому попытка нацеливания напрямую была бы рискованной (в вашем примере вы можете получить то, что хотите, с content.childNodes[1], но это опасно, если вы не знаете, как пишется html. Это может быть content.childNodes[0] без возврата каретки). Следовательно, лучший вариант - проанализировать дочерние узлы и установить переменную или вставить элементы в массив, когда они выполняют условие. в твоем случае :

var ul;
content.forEach(function(el){
  if (el.nodeName === 'UL') ul = el;
}

или создайте массив из списка узлов для фильтрации желаемого узла:

var ul = Array.from(document.querySelectorAll(".textwidget")[0].childNodes).filter(function(el) {if (el.nodeName == 'UL') return el});

// or use es6 features
// var ul = [...document.querySelectorAll(".textwidget")[0].childNodes].filter(e => e.nodeName == 'UL');

console.info(ul[0]);
<div class = "foot-nav-heading">Click me!</div>
    <div class = "textwidget">
       <ul class = "quick-link accordion-content">
          <li>Test</li>
       </ul>
</div>

Но он отлично работает там, где я его клонировал. Единственная разница в том, что <ul> заключен в <div>, поэтому мне нужно настроить таргетинг на <ul> внутри <div>

Edward Bella 18.12.2018 18:50

Делегирование событий

  • Оберните все аккордеоны в бирку (main#main)
  • Зарегистрируйте событие клика в этом родительском теге.
  • Теперь любой щелчок по родительскому тегу обнаруживается вложенными в него тегами.
  • Используя e.target, вы можете точно определить, какой тег был нажат.
  • Этот метод может поддерживать неограниченное количество тегов, используя один EventListener

Проблема XY

Относительно цели ОП:

"I want to target the child element in the next sibling parent without using class or ID."

Принимая во внимание фактический макет, каждая «кнопка» может быть нацелена на nextElementSibling, добавить / удалить класс и по-прежнему иметь возможность воздействовать на дочерний элемент nextElementSibling с помощью селектора CSS. Короче говоря, таргетинг на тег, вложенный в родительский элемент, является потраченным впустую, и который, в свою очередь, упрощает доступ к его потомкам через CSS.

Макет

<button>CLICK</button>

<section class='accordion'>
  <ul class='list'>
    <li>ITEM</li>
  </ul>
</section>

CSS

/* By default this hides .list */
.accordion {
  max-height: 0;
  opacity: 0;
  font-size: 0;
  transition: all 0.3s;
  border: 3px outset #666;
}

/* This class is added/removed when <button> is clicked */
/* .open is nextElementSibling and anytime .open is added, it's child .list 
   benefits from it as well
 */
.open,
.open .list {
  height: auto;
  max-height: 1000px;
  opacity: 1;
  font-size: 16px;
  transition: all 0.3s;
  border: 3px outset #666;
}


Демо

Детали прокомментированы в демо

// Reference the parent tag (main#main)
var main = document.getElementById('main');

/*
Register <main> to the click event...
toggleText() is the callback function
*/
main.addEventListener('click', toggleText);

// Pass the Event Object (e)
function toggleText(e) {
  // Reference e.target -- clicked tag (header.head) 
  var tgt = e.target;
  /*
  Reference the next adjacent sibling of e.target (article.text)
  */
  var actTxt = tgt.nextElementSibling;
  // Collect all article.text into a NodeList
  var txts = document.querySelectorAll('.text');
  // if clicked tag has class .head...
  if (tgt.classList.contains('head')) {
    /*
    On each loop...
    if the current article.text is NOT e.target's .text sibling...
    ...remove class .open.
    Toggle .open class on e.target's .text sibling.
    */
    for (let i = 0; i < txts.length; i++) {
      if (txts[i] !== actTxt) {
        txts[i].classList.remove('open');
      }
    }
    actTxt.classList.toggle('open');
  }
}
.head {
  cursor: pointer;
  border: 3px outset #666;
  text-align:center;
  padding: 3px 5px;
}

.text {
  max-height: 0;
  opacity: 0;
  font-size: 0;
  transition: all 0.3s;
  border: 3px outset #666;
}

.open,
.open .menu {
  height: auto;
  max-height: 1000px;
  opacity: 1;
  font-size: 16px;
  transition: all 0.3s;
  border: 3px outset #666;
}
<main id='main'>

  <header class = "head">MENU</header>
  <article class = "text">
    <ul class = "menu">
      <li>ITEM 1</li>
      <li>ITEM 2</li>
      <li>ITEM 3</li>
    </ul>
  </article>

  <header class = "head">MENU</header>
  <article class = "text">
    <ul class = "menu">
      <li>ITEM 1</li>
      <li>ITEM 2</li>
      <li>ITEM 3</li>
    </ul>
  </article>

  <header class = "head">MENU</header>
  <article class = "text">
    <ul class = "menu">
      <li>ITEM 1</li>
      <li>ITEM 2</li>
      <li>ITEM 3</li>
    </ul>
  </article>

</main>

Другие вопросы по теме