Я использую этот скрипт для отображения/скрытия контента. Однако как я могу закрыть открытые элементы при их открытии? Я пробовал что-то вроде этого, но это работает неправильно:
// Get siblings
var contentSiblings = document.querySelectorAll('.content');
// close them before opening new one
if (contentSiblings) {
contentSiblings.forEach((elem) => {
if (elem.classList.contains('is-visible')) {
hide(elem);
}
});
}
// Show/hide filter content
var show = function (elem) {
elem.classList.add('is-visible');
};
// Hide an element
var hide = function (elem) {
elem.classList.remove('is-visible');
};
// Toggle element visibility
var toggle = function (elem) {
// If the element is visible, hide it
if (elem.classList.contains('is-visible')) {
hide(elem);
return;
}
// Otherwise, show it
show(elem);
};
// Listen for click events
document.addEventListener('click', function (event) {
// Make sure clicked element is our toggle
if (!event.target.classList.contains('btn')) return;
// Prevent default link behavior
event.preventDefault();
// Get the selected content
var content = document.querySelector(event.target.hash);
if (!content) return;
// Toggle the content
toggle(content);
}, false);
.content {
display: none;
opacity: 0;
transition: opacity .15s linear;
}
.content.is-visible {
display: block;
opacity: 1;
}
<a class = "btn" id = "btn-one" href = "#one">Button one</a>
<a class = "btn" id = "btn-two" href = "#two">Button two</a>
<div class = "content" id = "one">Content one</div>
<div class = "content" id = "two">Content two</div>
Вероятно, простым подходом было бы всегда скрывать все элементы «контента» перед их отображением. Например, функция show
может сначала скрыть все элементы, а затем показать указанный элемент:
// Show/hide filter content
var show = function (elem) {
// Hide all others first
document.querySelectorAll('.content').forEach(hide);
elem.classList.add('is-visible');
};
// Hide an element
var hide = function (elem) {
elem.classList.remove('is-visible');
};
// Toggle element visibility
var toggle = function (elem) {
// If the element is visible, hide it
if (elem.classList.contains('is-visible')) {
hide(elem);
return;
}
// Otherwise, show it
show(elem);
};
// Listen for click events
document.addEventListener('click', function (event) {
// Make sure clicked element is our toggle
if (!event.target.classList.contains('btn')) return;
// Prevent default link behavior
event.preventDefault();
// Get the selected content
var content = document.querySelector(event.target.hash);
if (!content) return;
// Toggle the content
toggle(content);
}, false);
.content {
display: none;
opacity: 0;
transition: opacity .15s linear;
}
.content.is-visible {
display: block;
opacity: 1;
}
<a class = "btn" id = "btn-one" href = "#one">Button one</a>
<a class = "btn" id = "btn-two" href = "#two">Button two</a>
<div class = "content" id = "one">Content one</div>
<div class = "content" id = "two">Content two</div>
Вы можете добавить функцию hideAllElements
, чтобы скрыть все видимые элементы перед отображением содержимого:
// Show/hide filter content
function show(elem) {
hideAllElements()
elem.classList.add('is-visible');
};
// Hide an element
function hide (elem) {
elem.classList.remove('is-visible');
};
// Hide all elements
function hideAllElements (elem) {
const visibleElements = document.querySelectorAll('.is-visible');
for (const element of visibleElements) {
element.classList.remove('is-visible');
}
};
// Toggle element visibility
function toggle (elem) {
// If the element is visible, hide it
if (elem.classList.contains('is-visible')) {
hide(elem);
return;
}
// Otherwise, show it
show(elem);
};
// Listen for click events
document.addEventListener('click', function (event) {
// Make sure clicked element is our toggle
if (!event.target.classList.contains('btn')) return;
// Prevent default link behavior
event.preventDefault();
// Get the selected content
const content = document.querySelector(event.target.hash);
if (!content) return;
// Toggle the content
toggle(content);
}, false);
.content {
display: none;
opacity: 0;
transition: opacity .15s linear;
}
.content.is-visible {
display: block;
opacity: 1;
}
<a class = "btn" id = "btn-one" href = "#one">Button one</a>
<a class = "btn" id = "btn-two" href = "#two">Button two</a>
<div class = "content" id = "one">Content one</div>
<div class = "content" id = "two">Content two</div>
Кстати, если вы даете своим функциям описательные имена, комментарии больше не нужны.
Именно, большое спасибо.
вы также можете сделать:
document.body.addEventListener('click', e =>
{
if (!e.target.matches('.btn')) return;
if ( document.body.className === e.target.id )
document.body.className = '';
else
document.body.className = e.target.id;
})
.content {
display: none;
opacity: 0;
transition: opacity .15s linear;
}
body.btn-one #one.content ,
body.btn-two #two.content {
display: block;
opacity: 1;
}
<a class = "btn" id = "btn-one" href = "#">Button one</a>
<a class = "btn" id = "btn-two" href = "#">Button two</a>
<div class = "content" id = "one">Content one</div>
<div class = "content" id = "two">Content two</div>
С небольшим количеством CSS; гибкий макет , комбинатор следующего уровня и :has(), вы можете показывать и скрывать элементы с помощью переключателей.
section {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
section label {
order: 1;
display: inline-block;
align-self: start;
}
section label:has(input:checked) {
background: PowderBlue;
}
section label:has(input:checked)+div {
display: block;
}
section input {
display: none;
}
section div {
order: 2;
display: none;
width: 100%;
border: solid black thin;
min-height: 5em;
}
<section>
<label><input type = "radio" name = "tab" checked>Button one</label>
<div class = "content">Content one</div>
<label><input type = "radio" name = "tab">Button two</label>
<div class = "content">Content two</div>
</section>
Спасибо за замечание, я исправил.