Не удается изменить innerHTML дочернего класса для переключения «Больше / меньше читать» в javascript

#javascript #jquery #html #bulma

#javascript #jquery #HTML #bulma

Вопрос:

Я создаю ИТ-сайт и использую accordion для отображения услуг моих клиентов. Нажимаешь на аккордеон, и он расширяется или сжимается, предоставляя описание этого сервиса. Я хочу добавить текст «читать больше» / «читать меньше», который изменяется в зависимости от того, открыт аккордеон или закрыт (что делается с использованием класса is-active. Я не могу изменить innerHTML дочернего класса

Читать дальше

текст, потому что это дочерний элемент статьи «аккордеон активен».

Я просмотрел множество решений, и они, похоже, не решают проблему, с которой я сталкиваюсь, потому что мне нужно получить доступ к дочернему классу элемента, только если этот элемент имеет классы «accordion» и «is-active». Я пытался присвоить переменной тег Read More с помощью class = «readSwitch» id = «readSwitch» и изменить эти переменные html, например z.innerHTML = «Читать меньше», но z является копией y.getElementsByClass («readSwitch»), а не фактического элемента. Как мне напрямую получить доступ к классу «readSwitch» для элементов, которые содержат оба класса «accordion is-active»?

JavaScript

   function readToggle() {
      var x = document.getElementById("accordions");
      var y = x.getElementsByClassName("accordion is-active");
      var i;
      for (i = 0; i < y.length; i  ) {
        var z = y[i].getElementsByClassName("readSwitch");
        z.innerHTML = "Read Less";
        console.log(z.innerHTML);
      }

    }
  

HTML

 <section class="accordions" id="accordions">
        <article class="accordion is-active">
          <div class="accordion-header toggle" onclick="readToggle()">
            <p>
              Custom Built Computers
            </p>
            <p style="font-size:10px" class="readSwitch" 
            id="readSwitch">
              Read More
            </p>
          </div>
          <div class="accordion-body">
            <div class="accordion-content">
              blah blah blah
            </div>
          </div>
        </article>
</section>
  

Проблема в том, что z является копией y, поэтому его изменение не обновляет DOM. Однако, когда я пытаюсь напрямую получить доступ к внутреннему HTML y, используя что-то вроде y [i].getElementsByClassName («Переключатель чтения»).innerHTML = «Меньше читать»; Я получаю ошибку «TypeError: y.getElementsByClassName не является функцией. (В ‘y.getElementsByClassName(«Переключатель чтения»)’, ‘y.getElementsByClassName’ не определено) » . Существуют ли какие-либо способы напрямую изменять дочерние классы y в innerHTML, используя что-то вроде y.readSwitch.innerHTML = «Меньше читать»?

РЕДАКТИРОВАНИЕ РЕШЕНО!!! : Благодаря Джонатану Хайндлу я смог разобраться в этом. Я боролся с этой глупой вещью в течение 3 дней и не мог найти никаких решений в Интернете, поэтому я публикую свое решение Javascript для переключения читать больше читать меньше здесь для других. Это решение работает с приведенным выше HTML.

   document.onclick = function () {
      //variables for accordions with is-active
      var x = document.getElementById("accordions");
      var y = x.getElementsByClassName("accordion is-active");

      //variables for accordions with just accordion class, exclude those with "is-active"
      var noless = document.querySelectorAll('article.accordion:not(.is-active)');

      //Update all accordions with is-active to read less
      var i;
      for (i = 0; i < y.length; i  ) {
        y[i].getElementsByClassName("readSwitch")[0].innerHTML = "Read Less amp;uarr;";
      }

      //update accordions without is-active class to read more
      var w;
      for (w = 0; w < noless.length; w  ) {
        noless[w].getElementsByClassName("readSwitch")[0].innerHTML = "Read More amp;darr;";
      }
    }
  

Ответ №1:

getElementsByClassName возвращает массив элементов, поэтому, когда вы хотите сослаться на сам объект, вам нужно добавить индекс впоследствии:

 y[i].getElementsByClassName("readSwitch")[0].innerHTML
  

PS: При редактировании текста узла рекомендуется использовать .textContent = "Read LEss" в противном случае вы перезапишете все дочерние элементы указанного узла

Bsp:

 let x = document.getElementById("accordions");
let y = x.getElementsByClassName("accordion is-active");//maybe x.children depending on the structure
for (let i = 0; i < y.length; i  ) {
    let z = y[i].getElementsByClassName("readSwitch")[0];
    z.textContent= "Read Less";
    console.log(z.textContent);
  }
  

Комментарии:

1. Спасибо, что решил это! Это всегда какая-нибудь глупая мелочь вроде этой. Теперь мне просто нужно придумать способ, которым он будет обновляться до «читать больше» при сжатии аккордиона.

2. ну, вы также могли бы (вероятно, должны) обновить y [i].className=»not-active» или аналогичный, тогда вы можете просто сделать то же самое в обратном порядке (или сохранить некоторую переменную в одном из элементов для представления состояния щелчка — это быстро усложняется, хотя