Source:
carville-shop
Демо:
Плагины:
Подключение:
//
Разметка:
//
<ul class="tags-oems tags-oems--lessmore" id="lessmore-2">
<li>
<a
href="#"
data-popover-text="Копировать"
data-copy-text="123123"
class="js-text-popover-btn"
>443615301
</a>
</li>
<li>
<a href="#">8W0615121E</a>
</li>
<li>
<a href="#">8W0615121E</a>
</li>
<li>
<a href="#">8W0615121E</a>
</li>
<li>
<a href="#">443615301</a>
</li>
<li>
<a href="#">8W0615121E</a>
</li>
<li>
<a href="#">8W0615121E</a>
</li>
<li>
<a href="#">8W0615121E</a>
</li>
<li>
<a href="#">8W0615121E</a>
</li>
<li>
<a href="#">443615301</a>
</li>
<li>
<a href="#">8W0615121E</a>
</li>
<li>
<a href="#">8W0615121E</a>
</li>
<li>
<a href="#">8W0615121E</a>
</li>
<li>
<a href="#">8W0615121E</a>
</li>
<li>
<a href="#">443615301</a>
</li>
<li>
<a href="#">8W0615121E</a>
</li>
<li>
<button
class="btn-more js-lessmore-btn"
data-target="#lessmore-2"
>
<span>Еще 6</span>
<span>Скрыть</span>
<svg class="icon" aria-hidden="true">
<use xlink:href="#arrow-down"></use>
</svg>
</button>
</li>
</ul>
Стили:
//
.tags-oems {
display: flex;
flex-wrap: wrap;
gap: 0.8rem;
a {
transition: background-color 0.2s;
display: block;
padding: 0.8rem 1.2rem;
border-radius: 3rem;
background: #f6f6f6;
font-size: 1.2rem;
font-weight: 400;
line-height: 1.4rem; /* 116.667% */
&:hover {
background: #e8e8e8;
}
}
&--lessmore {
&:not(.opened) {
li {
&:nth-child(n + 9) {
display: none;
}
}
}
li:last-child {
display: block !important;
}
}
}
.btn-more {
display: flex;
align-items: center;
gap: 0.6rem;
padding: 0.8rem 0;
font-size: 1.2rem;
font-weight: 400;
line-height: 1.4rem; /* 116.667% */
color: #ff6e00;
span:nth-child(2) {
display: none;
}
.icon {
font-size: 1.6rem;
}
&.opened {
span:nth-child(1) {
display: none;
}
span:nth-child(2) {
display: block;
}
.icon {
transform: rotate(180deg);
}
}
}
Инициализация:
interface ILessMoreOptions {
btnOpenedClass?: string;
listOpenedClass?: string;
}
class LessMore {
private btnEl: HTMLElement;
private listEl: HTMLElement;
private options: Required<ILessMoreOptions>;
private initializedClass = "lessmore-initialized";
constructor(btnEl: HTMLAnchorElement, options: ILessMoreOptions = {}) {
if (!btnEl) {
throw new Error("LessMore: btnEl is required");
}
this.btnEl = btnEl;
this.options = {
btnOpenedClass: "opened",
listOpenedClass: "opened",
...options,
};
const listSelector = btnEl.hash || btnEl.dataset.target;
if (!listSelector) {
throw new Error("LessMore: btn has not list selector");
}
const listEl = document.querySelector<HTMLElement>(listSelector);
if (!listEl) {
throw new Error("LessMore: listEl not found");
}
this.listEl = listEl;
// Проверяем, есть ли уже созданный экземпляр
const existing = (btnEl as any)._lessmoreInstance as LessMore;
if (existing) return existing;
this.init();
// Сохраняем экземпляр в DOM
(this.btnEl as any)._lessmoreInstance = this;
}
/** Инициализация кнопки */
private init(): void {
this.btnEl.classList.add(this.initializedClass);
this.btnEl.addEventListener("click", this.handleButtonClick);
}
/** Обработчик клика */
private handleButtonClick = (event: MouseEvent): void => {
event.preventDefault();
this.toggle();
};
/** Переключить состояние */
public toggle(): void {
if (this.btnEl.classList.contains(this.options.btnOpenedClass)) {
this.close();
} else {
this.open();
}
}
/** Открыть список */
public open(): void {
this.btnEl.classList.add(this.options.btnOpenedClass);
this.listEl.classList.add(this.options.listOpenedClass);
}
/** Закрыть список */
public close(): void {
this.btnEl.classList.remove(this.options.btnOpenedClass);
this.listEl.classList.remove(this.options.listOpenedClass);
}
/** Получить экземпляр по DOM-элементу */
public static getInstance(btnEl: HTMLElement): LessMore | undefined {
return (btnEl as any)._lessmoreInstance as LessMore | undefined;
}
/** Удалить экземпляр и обработчик */
public destroy(): void {
this.btnEl.classList.remove(this.initializedClass);
this.btnEl.removeEventListener("click", this.handleButtonClick);
delete (this.btnEl as any)._lessmoreInstance;
}
}
export default LessMore;
export function initLessMore() {
document
.querySelectorAll<HTMLAnchorElement>(".js-lessmore-btn")
.forEach((el) => {
new LessMore(el, {
btnOpenedClass: "opened",
listOpenedClass: "opened",
});
});
}
0 комментариев