Я использую веб-компоненты и создал класс Panel.
По умолчанию, если для именованного слота не было предоставлено содержимого, родительский элемент не должен быть виден.
<div class = "panel-header">
<slot name = "header">
Header
</slot>
</div>
<div class = "panel-body">
<slot name = "body">
Body
</slot>
</div>
<div class = "panel-footer"> <!-- display:none -->
<slot name = "footer"></slot> <!-- if there's no content -->
</div>
Вот метод рендеринга моего родительского компонента:
render() {
this.innerHTML = `
<panel-component>
<span slot = "header">Member Info</span>
<span slot = "body">${this.search ? this.search : 'Please select a member'}</span>
<!-- no footer slot -->
</panel-component>
`;
}
Я бы предпочел применить этот стиль с помощью CSS, но я открыт для предложений по JavaScript.
::slotted(div:empty) {
display: none;
}
.panel-footer:empty,
.panel-footer:has(:empty) {
display: none;
}
:scope > :empty {
display: none;
}
::slotted(div[slot = "footer"]:empty) {
display: none;
}
Похоже, что существует решение CSS, но на основе приведенных ниже предложений мне удалось получить желаемый результат.
render() {
this.shadowRoot.appendChild(template.content.cloneNode(true));
const parent = this.shadowRoot.querySelector(".panel-footer");
const footer = this.shadowRoot.querySelector("#footer");
footer.assignedNodes().length > 0 ? parent.style.display = "block" : parent.style.display = "none";
}
@JaromandaX .panel-footer:has(:empty)
работает, но также скрывается при наличии контента. ::slotted(div[slot = "footer"]:empty)
вообще ничего не скрывает
О, ты прав, я что-то напутал :p
Я не понимаю, как это сделать с помощью только CSS
Вы можете добиться этого с помощью JS. Итак, сначала вам нужно добавить id
или class
к элементу, для которого вы хотите проверить, содержит ли он какой-либо контент или нет. В приведенном ниже примере я добавил идентификатор checkContent
к slot
.
После этого вам понадобится js, чтобы проверить, содержит ли checkContent
какой-либо контент или нет. Если он содержит, то panel-footer
должен отображаться или быть скрыт.
Codepen для того же самого находится здесь. Если я что-то не так понял или пропустил, поделитесь, пожалуйста.
function hideContent(){
let panelFooter = document.querySelector('.panel-footer');
let content = document.getElementById('checkContent')
if (content.innerHTML == null || content.innerHTML == ''){
panelFooter.style.display = "none";
}
else{
panelFooter.style.display = "block";
}
console.info(panelFooter.style.display)
}
hideContent()
<div class = "panel-footer">
<slot name = "footer" id = "checkContent">Remove this text and check console.</slot>
</div>
Ваша идея интересна, но в настоящее время ее невозможно реализовать только с помощью селекторов CSS.
Возможно, вы ищете селектор с именем :has-slotted, но CSS все еще развивается. На GitHub есть обсуждение этой темы; вы можете перейти по этой ссылке: https://github.com/w3c/csswg-drafts/issues/6867, чтобы проверить это.
Кажется, что и
.panel-footer:has(:empty)
, и::slotted(div[slot = "footer"]:empty)
достигают того, чего вы хотите — вы видите обратное?