#javascript #foreach
#javascript #для каждого
Вопрос:
Итак, что я пытаюсь сделать, так это отобразить несколько карточек отзывов. С помощью кнопки «Показать больше» / «показать меньше». При нажатии я хочу, чтобы текст этого конкретного отзыва показывал больше / показывал меньше. Но на данный момент моя функция заставляет все отзывы показывать больше / показывать меньше текста. Пожалуйста, помогите, я не знаю, чего мне не хватает.
const testimonialCards = document.querySelectorAll('#feedback-text'); //returns nodelist
const testimonialArray = Array.from(testimonialCards); //converts nodelist to array
const showMoreButton = document.querySelectorAll('.js-show-more');
const showMoreButtonArray = Array.from(showMoreButton);
//looping through the testimonial cards
testimonialArray.forEach(e => {
//looping through buttons array
showMoreButtonArray.forEach(t => {
//adding onclick method to the buttons
t.addEventListener('click', function() {
//conditional to check if the hidden exists, if so so, remove it and add the show all class etc.
if (e.classList.contains('excerpt-hidden')) {
e.classList.remove('excerpt-hidden');
e.classList.add('showAllContent');
showMoreButton.innerText = "Show Less";
} else {
e.classList.add('excerpt-hidden');
e.classList.remove('showAllContent');
showMoreButton.innerText = "Show More";
}
});
});
});
/*Css for show more text and show less using the height of the text container*/
.js-show-more {
border: 0;
border-radius: 0;
background-color: unset;
color: #b83426;
text-transform: uppercase;
cursor: pointer;
}
/*truncating text*/
.excerpt-hidden {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
overflow: hidden;
height: 65px;
width: 80%;
margin: 0 auto 1em;
}
.showAllContent {
height: auto;
overflow: initial;
-webkit-line-clamp: none;
}
<!--This is my testimonial card, I would have about 8 cards on pageload-->
<testimonial class="testimonial-card" flag="sa.svg">
<h4>Title</h4>
<p class="excerpt-hidden expanded-text" id="feedback-text">
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has
survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing
software like Aldus PageMaker including versions of Lorem Ipsum.
</p>
<button class="js-show-more">Show More</button>
</testimonial>
Ответ №1:
Это должно сработать:
const testimonialCards = document.querySelectorAll('#feedback-text'); //returns nodelist
const showMoreButtons = document.querySelectorAll('.js-show-more');
//looping through buttons array
showMoreButtons.forEach((t, i) => {
//adding onclick method to the buttons
t.addEventListener('click', function() {
const e = testimonialCards[i]
// conditional to check if the hidden exists, if so so,
// remove it and add the show all class etc.
if (e.classList.contains('excerpt-hidden')) {
e.classList.remove('excerpt-hidden');
e.classList.add('showAllContent');
t.innerText = "Show Less";
} else {
e.classList.add('excerpt-hidden');
e.classList.remove('showAllContent');
t.innerText = "Show More";
}
});
});
/*Css for show more text and show less using the height of the text container*/
.js-show-more {
border: 0;
border-radius: 0;
background-color: unset;
color: #b83426;
text-transform: uppercase;
cursor: pointer;
}
/*truncating text*/
.excerpt-hidden {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
overflow: hidden;
height: 65px;
width: 80%;
margin: 0 auto 1em;
}
.showAllContent {
height: auto;
overflow: initial;
-webkit-line-clamp: none;
}
<testimonial class="testimonial-card" flag="sa.svg">
<h4>Title</h4>
<p class="excerpt-hidden expanded-text" id="feedback-text">
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has
survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing
software like Aldus PageMaker including versions of Lorem Ipsum.
</p>
<button class="js-show-more">Show More</button>
</testimonial>
<testimonial class="testimonial-card" flag="sa.svg">
<h4>Title 2</h4>
<p class="excerpt-hidden expanded-text" id="feedback-text">
It has
survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing
software like Aldus PageMaker including versions of Lorem Ipsum.
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.
</p>
<button class="js-show-more">Show More</button>
</testimonial>
Ответ №2:
Проблемы:
-
Вы повторяете
showMoreButton
для каждого отзыва. Это совершенно не нужно и является причиной проблемы, с которой вы столкнулись. С каждым отзывом связана одна кнопка. Вам просто нужно перебрать отзывы, получить кнопку в текущем отзыве и добавить к ней прослушиватель событий. -
Вам не нужно конвертировать,
NodeList
возвращаемыйdocument.querySelectorAll
, в массив. Вы можете использовать.forEach()
метод сNodeList
.
Решение:
Вы могли бы добавить отдельного click
слушателя для каждой кнопки, но есть способ получше. Вы могли бы воспользоваться всплывающими событиями.
Оберните все отзывы в оболочку div
и добавьте click
событие в элемент оболочки, а не в каждую кнопку, связанную с каждым отзывом.
Когда click
событие запускается на элементе-оболочке div
, выполните следующие действия:
- Проверьте,
Event.target
есть ли кнопка. - Если это так, найдите родительский элемент нажатой кнопки, а затем выберите
#feedback-text
элемент. - Затем переключите классы
excerpt-hidden
иshowAllContent
для выбранного#feedback-text
элемента. - Наконец, измените текст нажатой кнопки.
Следующий фрагмент кода показывает пример с двумя отзывами.
const testimonialWrapper = document.querySelector('.wrapper');
testimonialWrapper.addEventListener('click', function(event) {
const target = event.target;
if (target.matches('.js-show-more')) {
const p = target.parentElement.querySelector('#feedback-text');
p.classList.toggle('excerpt-hidden');
p.classList.toggle('showAllContent');
target.textContent =
target.textContent == 'Show More' ? 'Show Less' : 'Show More';
}
});
.js-show-more {
border: 0;
border-radius: 0;
background-color: unset;
color: #b83426;
text-transform: uppercase;
cursor: pointer;
}
.excerpt-hidden {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
overflow: hidden;
height: 65px;
width: 80%;
margin: 0 auto 1em;
}
.showAllContent {
height: auto;
overflow: initial;
-webkit-line-clamp: none;
}
<div class="wrapper">
<testimonial class="testimonial-card" flag="sa.svg">
<h4>Title</h4>
<p class="excerpt-hidden expanded-text" id="feedback-text">
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has
survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop
publishing software like Aldus PageMaker including versions of Lorem Ipsum.
</p>
<button class="js-show-more">Show More</button>
</testimonial>
<testimonial class="testimonial-card" flag="sa.svg">
<h4>Title</h4>
<p class="excerpt-hidden expanded-text" id="feedback-text">
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has
survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop
publishing software like Aldus PageMaker including versions of Lorem Ipsum.
</p>
<button class="js-show-more">Show More</button>
</testimonial>
</div>