Аккордеон в Zero-блоке

Карточки с раскрывающимся текстом — так это называется в Тильде. Ну, а для всех остальных — это аккордеон.

Данная модификация работает для следующих блоков:
  • TX16N: Текст в раскрывающихся карточках
  • TX16N2: Текст в раскрывающихся карточках на цветном фоне
  • SV501: Текст в раскрывающихся карточках

Посмотрите пример, чтобы понять, как работает модификация.

Инструкция:
  1. Добавьте один из блоков с аккордеоном (TX16N / TX16N2 / SV501) на страницу.
  2. Уберите заголовок и описание из шапки блока, если используете SV501.
  3. Уберите отступы сверху и снизу у блока, а также фон, если он задан (у вас применится фон Zero-блока).
  4. Создайте Зеро-блок, добавьте в него HTML-элемент, а внутри напишите: <div id="zero-accordion"></div>. ID zero-accordion должен совпадать с таковым в третьем поле формы внизу.
  5. Впишите в настройки ниже ID блоков.
  6. Скопируйте полученный код и вставьте его в блок T123. Сам блок разместите под вашими элементами (Zero-блоком и аккордеоном) или в самом низу страницы.
Если у вас несколько аккордеонов на странице, то у них должны быть разные ID& Например, для первого вы пишете в HTML-элементе Zero-блока <div id="zero-accordion-1"></div>, а в следующем уже <div id="zero-accordion-2"></div>. Для каждого аккордеона нужен будет новый скрипт. Для получения нового «правильного» скрипта для второго и более аккордеонов, вам необходимо каждый раз в третьем поле менять ID на новый (можете просто дописывать новое число).

UPD:Модификация теперь работает с автоскейлом.
<!-- Аккордеон в Zero-блоке | https://necodim.ru/tilda/accordion-in-zero -->

<script>!function(){const findLowestElement=selector=>{const elements=document.querySelectorAll(selector);let lowestElement=null,maxBottom=-1/0;return elements.forEach(el=>{const rect=el.getBoundingClientRect(),bottom=rect.top+rect.height;bottom>maxBottom&&(maxBottom=bottom,lowestElement=el)}),lowestElement},findElementWithClassEnding=(ending,parent=null)=>{const allElements=parent?parent.querySelectorAll("*"):document.querySelectorAll("*"),elements=new Array;for(let element of allElements)Array.from(element.classList).some(className=>className.endsWith(ending))&&elements.push(element);const result=elements.length?elements:null;return result},getElementHeight=element=>{if(element){const height=element.offsetHeight;return height}return!1},getBottom=element=>{const elementHeight=element.offsetHeight,elementTopPosition=element.closest(".tn-elem").offsetTop,bottom=Math.round(elementTopPosition+elementHeight);return bottom},getRealDistanceBetweenBottoms=element=>{const zeroArtboardBaseHeight=Math.round(parseInt(zeroWithAccordionArtboard.getAttribute("data-artboard-height"),10)),bottom=getBottom(element),distance=Math.round(zeroArtboardBaseHeight-bottom);return distance},setZeroProperty=(prop,value)=>{const zeroFilter=zeroWithAccordionArtboard.querySelector(".t396__filter"),zeroCarrier=zeroWithAccordionArtboard.querySelector(".t396__carrier");zeroWithAccordionArtboard.style.setProperty(prop,value,"important"),zeroFilter.style.setProperty(prop,value,"important"),zeroCarrier.style.setProperty(prop,value,"important")},setZeroHeight=height=>{const px=height+"px";setZeroProperty("height",px),setZeroProperty("min-height",px),zeroWithAccordionArtboard.setAttribute("data-artboard-height",height),zeroWithAccordionArtboard.setAttribute("data-artboard-proxy-min-height",height),zeroWithAccordionArtboard.setAttribute("data-artboard-proxy-max-height",height)},zeroID="#rec123456789",accordionID="#rec234567890",zeroWithAccordionArtboard=document.querySelector(` .t396__artboard`);zeroWithAccordionArtboard.addEventListener("artBoardRendered",()=>{setZeroProperty("transition","all .2s ease-in-out");const accordion=document.getElementById("zero-accordion"),accordionHeight=getElementHeight(document.querySelector(accordionID)),htmlElement=accordion.closest(".tn-elem"),htmlElementBaseHeight=parseInt(htmlElement.style.height.replace(/\D/g,""),10),zeroArtboardBaseHeight=Math.round(parseInt(zeroWithAccordionArtboard.getAttribute("data-artboard-height"),10)),zeroSummarizeHeight=zeroArtboardBaseHeight-htmlElementBaseHeight+accordionHeight,zoom="window"===zeroWithAccordionArtboard.getAttribute("data-artboard-upscale")?window.tn_scale_factor:1,zeroArtboardZoomHeight=Math.round(zeroSummarizeHeight*zoom);zeroWithAccordionArtboard.setAttribute("data-artboard-height",zeroArtboardZoomHeight),zeroWithAccordionArtboard.setAttribute("data-artboard-proxy-min-height",zeroArtboardZoomHeight),zeroWithAccordionArtboard.setAttribute("data-artboard-proxy-max-height",zeroArtboardZoomHeight),htmlElement.style.height=Math.ceil(accordion.getBoundingClientRect().height)+"px",setZeroHeight(zeroArtboardZoomHeight),accordion.appendChild(document.querySelector(accordionID)),accordion.querySelectorAll(".t-col").forEach(col=>(col.style.marginLeft="0",col.style.marginRight="0"));const accordionHiddenElements=findElementWithClassEnding("__content",accordion),accordionBaseHeight=accordion.offsetHeight;let accordionHiddenHeight=0,accordionMaxHeight=accordionBaseHeight;accordionHiddenElements.forEach(el=>{el.style.display="block",elStyle=window.getComputedStyle(el,null);var paddingBottom=Number(elStyle.paddingBottom.replace("px","")),height=el.scrollHeight+paddingBottom;el.style.display="",accordionHiddenHeight+=height}),accordionMaxHeight+=accordionHiddenHeight;const lowestDiv=findLowestElement(` .tn-atom`);let zeroArtboardMaxHeight,differenceBottom;if(isAccordionLastDiv=lowestDiv===accordion.closest(".tn-atom"),isAccordionLastDiv)zeroArtboardMaxHeight=Math.round((zeroSummarizeHeight+accordionHiddenHeight)*zoom),differenceBottom=getRealDistanceBetweenBottoms(accordion);else{const lowestDivHeight=lowestDiv.offsetHeight,difference=Math.round(Math.abs(lowestDiv.getBoundingClientRect().top-accordion.getBoundingClientRect().top));differenceBottom=getRealDistanceBetweenBottoms(lowestDiv),zeroArtboardMaxHeight=Math.round((zeroSummarizeHeight+accordionMaxHeight-lowestDivHeight+difference)*zoom)}accordion.querySelectorAll("button").forEach(button=>{button.addEventListener("click",e=>{const interval=setInterval(()=>{const needToGrow=isAccordionLastDiv?getBottom(accordion)<zeroArtboardMaxHeight:getBottom(accordion)>getBottom(lowestDiv),height=(accordion.offsetHeight+accordion.closest(".tn-elem").offsetTop+differenceBottom)*zoom;setZeroHeight(needToGrow?height:zeroArtboardZoomHeight)},16);setTimeout(()=>{clearInterval(interval)},400)})})})}();</script>
Пример работы модификации
Этот аккордеон находится внутри Zero-блока
F.A.Q.
Made on
Tilda