Hello, I have a website with entries according to the structure:
entryItem.innerHTML =
<div class="entry-title">${title}</div>
<div class="entry-body">
<div class="entry-content">
<p class="formatted-p">${content}</p>
</div>
<div class="entry-table-container-wrocor"></div>
<div class="entry-table-container-gennot"></div>
<div class="entry-tags"></div>
</div>
The entry-tags are located within the entry-body at the bottom, but there are 2 issues with the entry-tags: 1) when the entry is being expanded, the entry-tags don’t expand smoothly with the rest of the entry-body but rather jumpy; and 2) when pressing the minimize/maximize button of the page window, the entry-tags display inconsistent behavior regarding their position (for some entries the tags even disappear - especially in the first entry); the tags keep a consistent position when manually resizing the page window though
Anyone know how to A) fix this jumpy expansion of tags, and B) maintain a consistent position of tags (both when manually expanding the entry and when resizing and min-/maximizing the page window)?
This is the Javascript code (with CSS code underneath):
const newItems = document.querySelectorAll('.entry-item');
newItems.forEach(item => {
const entryBody = item.querySelector('.entry-body');
const tableWrocor = item.querySelector('.entry-table-container-wrocor');
const tableGennot = item.querySelector('.entry-table-container-gennot');
const tagsContainer = item.querySelector('.entry-tags');
item.addEventListener('click', (event) => {
const selection = window.getSelection();
if (selection && selection.toString()) return;
const isActive = item.classList.contains('active');
const containers = [entryBody, tableWrocor, tableGennot, tagsContainer].filter(Boolean);
if (isActive) {
containers.forEach(container => {
container.style.maxHeight = container.scrollHeight + "px";
});
requestAnimationFrame(() => {
containers.forEach(container => {
container.style.maxHeight = "0";
if (container.classList.contains('entry-tags')) {
container.addEventListener("transitionend", function handler(e) {
if (e.target !== container) return;
container.style.opacity = "0";
container.style.visibility = "hidden";
container.removeEventListener("transitionend", handler);
}, { once: true });
}
});
});
item.classList.remove("active");
item.classList.add("collapsed");
} else {
containers.forEach(container => {
container.style.maxHeight = "0";
});
item.classList.add("active");
item.classList.remove("collapsed");
containers.forEach(container => {
container.style.maxHeight = container.scrollHeight + "px";
container.addEventListener("transitionend", function handler(e) {
if (e.target !== container) return;
if (item.classList.contains("active")) {
container.style.maxHeight = "none"; // Remove max height restriction
}
container.removeEventListener("transitionend", handler);
}, { once: true });
if (container.classList.contains('entry-tags')) {
// Ensure tags are fully visible after expansion
container.style.opacity = "1";
container.style.visibility = "visible";
}
});
}
requestAnimationFrame(() => {
const rect = item.getBoundingClientRect();
if (rect.top < 0 || rect.bottom > window.innerHeight) {
item.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
});
if (selection) selection.removeAllRanges();
});
// Re-render tag names
const tagsData = (item.getAttribute('data-tags') || "").split(',').map(tag => tag.trim());
const tagNames = tagsData
.map(tagId => {
const option = document.querySelector(`#categories option[value="${tagId}"]`);
return option ? option.textContent.trim() : null;
})
.filter(Boolean)
.sort((a, b) => a.localeCompare(b, undefined, { sensitivity: 'base' }));
if (tagNames.length > 0 && tagsContainer) {
tagsContainer.innerHTML = 'Tag(s): ' + tagNames.join(', ');
}
});
// Ensure entry tags are properly shown when resizing
window.addEventListener("resize", () => {
// Wait briefly for the layout to fully settle
requestAnimationFrame(() => {
setTimeout(() => {
document.querySelectorAll(".entry-item.active").forEach(item => {
const entryBody = item.querySelector(".entry-body");
const tableWrocor = item.querySelector(".entry-table-container-wrocor");
const tableGennot = item.querySelector(".entry-table-container-gennot");
const tagsContainer = item.querySelector(".entry-tags");
const adjustContainerHeight = (container) => {
if (!container) return;
container.style.maxHeight = "none"; // Allow full expansion
const height = container.scrollHeight + "px";
container.style.maxHeight = height;
};
[entryBody, tableWrocor, tableGennot, tagsContainer].forEach(adjustContainerHeight);
if (tagsContainer) {
tagsContainer.style.opacity = "1";
tagsContainer.style.visibility = "visible";
}
});
}, 50); // Let the browser recalculate layout first
});
});
// Fix: Adjust .entry-tags after window is minimized and restored
document.addEventListener("visibilitychange", () => {
if (document.visibilityState === "visible") {
requestAnimationFrame(() => {
setTimeout(() => {
// Force reflow to trigger layout recalculation
document.querySelectorAll(".entry-item.active").forEach(item => {
const entryBody = item.querySelector(".entry-body");
const tagsContainer = item.querySelector(".entry-tags");
// Force reflow by accessing the offsetHeight/scrollHeight of entry-body
entryBody.offsetHeight; // Trigger reflow for the entry body
if (tagsContainer) {
// Force reflow for the tags container too
tagsContainer.offsetHeight; // Trigger reflow for the tags
// Reset maxHeight and ensure it's correctly calculated
tagsContainer.style.maxHeight = "none"; // Clear height restriction
const height = tagsContainer.scrollHeight + "px";
tagsContainer.style.maxHeight = height;
// Ensure opacity and visibility are applied after reflow
tagsContainer.style.opacity = "1";
tagsContainer.style.visibility = "visible";
}
});
}, 100); // Give the browser a short moment to restore layout
});
}
});
addStarIcon();}```
This is the CSS code:
```.entry-body {
position: relative;
border: 1px dashed red;
overflow: hidden;
max-height: 0; /* Prevent expansion by default */
height: 0;
padding: 0 10px; /* Collapse padding as well */
transition: max-height 0.4s ease; /* Smooth transition for expansion */
}
.entry-item.active .entry-body {
height: auto;
max-height: 5000px; /* Allow expansion to a larger height */
}
/* Ensure entry-content stays in flow */
.entry-item .entry-content {
user-select: none;
margin: 0px 35px 3px 35px;
padding-bottom: 6px;
}
/* Entry content text appearance */
.entry-content *:not(mark) {
font-size: 16px !important;
line-height: 1.5 !important;
font-family: Helvetica, sans-serif !important;
background-color: transparent !important;
}
.entry-item.active .entry-content {
display: block;
user-select: text;
}
.entry-item .entry-table-container-wrocor {
margin: 0px 35px 6px 35px; /* same as .entry-content */
padding-bottom: 13px;
}
.entry-item.active .entry-table-container-wrocor {
display: block;
}
.entry-item .entry-table-container-gennot {
margin: 0px 35px 6px 35px;
padding-bottom: 13px;
}
.entry-item.active .entry-table-container-gennot {
display: block;
}
.full-width-cell {
width: 100%;
display: block;
}
.entry-item .entry-tags {
position: relative;
bottom:5px;
right: 20px;
padding-left: 15px;
display: none;
font-style: italic;
font-size:13px;
text-align: right;
margin-top: 10px;
}
.entry-item.active .entry-tags {
display: block;
opacity: 1; /* Ensure full visibility */
visibility: visible; /* Ensure tags are visible */
}```