如何将 link 作为插槽嵌入到自定义组件中?
How to embed a link in a custom component as a slot?
我正在尝试创建一个包含一些动画的简单组件。我为 link 的文本设置了名称属性。我为 link 的目的地设置了一个插槽,但模板不允许将 link 设置为插槽。我不确定接下来要尝试什么。
当我将鼠标悬停在 link 上时,它只显示 <slot name=
而不是实际的 URL。
const template = document.createElement('template');
template.innerHTML = `
<style>
.txt-link a {
color: #005fec;
font-weight: 700;
font-size: 18px;
text-decoration: none;
position: relative;
}
.txt-link a:hover {
text-decoration: none;
cursor: pointer;
}
.txt-link a::before {
content: "";
position: absolute;
bottom: -5px;
left: 0;
width: 0;
height: 1px;
background-color: #005fec;
visibility: hidden;
transition: all 0.3s ease-in-out 0s;
}
.txt-link a:hover::before {
visibility: visible;
width: 100%;
}
.txt-link.arrow-link img {
height: 15px;
position: relative;
top: 2px;
}
</style>
<div class="txt-link arrow-link">
<a href="<slot name="destination" />"></a>
<img alt="arrow right icon" class="learn-more-arrow" src="https://www.pikpng.com/pngl/m/73-734729_arrow-blue-right-transparent-blue-arrow-right-clipart.png" loading="lazy">
</div>
`;
class CustomAnimLink extends HTMLElement {
constructor() {
super();
this.showInfo = true;
this.attachShadow({ mode: 'open' });
this.shadowRoot.appendChild(template.content.cloneNode(true));
this.shadowRoot.querySelector('a').innerText = this.getAttribute('name');
}
}
window.customElements.define('custom-anim-link', CustomAnimLink);
<custom-anim-link name="Learn more">
<div slot="destination">https://www.yahoo.com</div>
</custom-anim-link>
插槽不能做到这一点。插槽用于将 HTMLElement
放置在插槽的位置,不能用于除此之外的任何其他内容。
而是将 URL 作为属性传递。这似乎适合数据类型。 Web Components 有一些很好的生命周期来帮助你。
我添加了 static get observedAttributes()
以指示应遵守某些属性。这样做将使您能够在其中一个属性中的值发生更改时执行某些操作,例如更新 Shadow DOM.
中锚点上的 URL
只要观察到的属性值发生变化,就会调用 attributeChangedCallback
,您可以在其中确定值发生变化时应该发生什么。
observedAttributes
和 attributeChangedCallback
都是 Web 组件生命周期挂钩的一部分。
const template = document.createElement('template');
template.innerHTML = `
<style>
.txt-link a {
color: #005fec;
font-weight: 700;
font-size: 18px;
text-decoration: none;
position: relative;
}
.txt-link a:hover {
text-decoration: none;
cursor: pointer;
}
.txt-link a::before {
content: "";
position: absolute;
bottom: -5px;
left: 0;
width: 0;
height: 1px;
background-color: #005fec;
visibility: hidden;
transition: all 0.3s ease-in-out 0s;
}
.txt-link a:hover::before {
visibility: visible;
width: 100%;
}
.txt-link.arrow-link img {
height: 15px;
position: relative;
top: 2px;
}
</style>
<div class="txt-link arrow-link">
<a href=""><slot></slot></a>
<img alt="arrow right icon" class="learn-more-arrow" src="https://www.pikpng.com/pngl/m/73-734729_arrow-blue-right-transparent-blue-arrow-right-clipart.png" loading="lazy">
</div>
`;
class CustomAnimLink extends HTMLElement {
static get observedAttributes() {
return ['name', 'destination'];
}
constructor() {
super();
this.showInfo = true;
this.attachShadow({
mode: 'open'
});
this.shadowRoot.appendChild(template.content.cloneNode(true));
}
get anchor() {
return this.shadowRoot.querySelector('a');
}
get name() {
return this.getAttribute('name');
}
set name(value) {
if ('string' === typeof value) {
this.setAttribute('name', value);
}
}
get destination() {
return this.getAttribute('destination');
}
set destination(value) {
if ('string' === typeof value) {
this.setAttribute('destination', value);
}
}
attributeChangedCallback(attrName, oldValue, newValue) {
switch (attrName) {
case 'destination':
this.anchor.href = newValue;
break;
case 'name':
this.anchor.textContent = newValue;
break;
}
}
}
window.customElements.define('custom-anim-link', CustomAnimLink);
<custom-anim-link name="Learn more" destination="https://www.yahoo.com"></custom-anim-link>
或者,您可以在插槽的位置传递 <a>
标记。然后获取分配给 destination
插槽的所有元素,并根据 name
属性的值设置 textContent
属性。我们在上一个示例中添加的 destination
属性也是如此。
const template = document.createElement('template');
template.innerHTML = `
<style>
.txt-link a {
color: #005fec;
font-weight: 700;
font-size: 18px;
text-decoration: none;
position: relative;
}
.txt-link a:hover {
text-decoration: none;
cursor: pointer;
}
.txt-link a::before {
content: "";
position: absolute;
bottom: -5px;
left: 0;
width: 0;
height: 1px;
background-color: #005fec;
visibility: hidden;
transition: all 0.3s ease-in-out 0s;
}
.txt-link a:hover::before {
visibility: visible;
width: 100%;
}
.txt-link.arrow-link img {
height: 15px;
position: relative;
top: 2px;
}
</style>
<div class="txt-link arrow-link">
<slot name="destination"></slot>
<img alt="arrow right icon" class="learn-more-arrow" src="https://www.pikpng.com/pngl/m/73-734729_arrow-blue-right-transparent-blue-arrow-right-clipart.png" loading="lazy">
</div>
`;
class CustomAnimLink extends HTMLElement {
static get observedAttributes() {
return ['name', 'destination'];
}
constructor() {
super();
this.showInfo = true;
this.attachShadow({
mode: 'open'
});
this.shadowRoot.appendChild(template.content.cloneNode(true));
}
get destinations() {
const slot = this.shadowRoot.querySelector('slot');
const assignedElements = slot.assignedElements();
return assignedElements;
}
get name() {
return this.getAttribute('name');
}
set name(value) {
if ('string' === typeof value) {
this.setAttribute('name', value);
}
}
get destination() {
return this.getAttribute('destination');
}
set destination(value) {
if ('string' === typeof value) {
this.setAttribute('destination', value);
}
}
attributeChangedCallback(attrName, oldValue, newValue) {
switch(attrName) {
case 'name':
this.destinations.forEach(destination => {
destination.textContent = newValue;
});
break;
case 'destination':
this.destinations.forEach(destination => {
destination.href = newValue;
});
break;
}
}
}
window.customElements.define('custom-anim-link', CustomAnimLink);
<custom-anim-link name="Learn more" destination="https://www.yahoo.com">
<a slot="destination"></a>
</custom-anim-link>
或者作为最后的简单手段,只需将 <a>
作为您的自定义元素的子项完整传递。
<custom-anim-link>
<a href="https://www.yahoo.com">Learn more</a>
</custom-anim-link>
我正在尝试创建一个包含一些动画的简单组件。我为 link 的文本设置了名称属性。我为 link 的目的地设置了一个插槽,但模板不允许将 link 设置为插槽。我不确定接下来要尝试什么。
当我将鼠标悬停在 link 上时,它只显示 <slot name=
而不是实际的 URL。
const template = document.createElement('template');
template.innerHTML = `
<style>
.txt-link a {
color: #005fec;
font-weight: 700;
font-size: 18px;
text-decoration: none;
position: relative;
}
.txt-link a:hover {
text-decoration: none;
cursor: pointer;
}
.txt-link a::before {
content: "";
position: absolute;
bottom: -5px;
left: 0;
width: 0;
height: 1px;
background-color: #005fec;
visibility: hidden;
transition: all 0.3s ease-in-out 0s;
}
.txt-link a:hover::before {
visibility: visible;
width: 100%;
}
.txt-link.arrow-link img {
height: 15px;
position: relative;
top: 2px;
}
</style>
<div class="txt-link arrow-link">
<a href="<slot name="destination" />"></a>
<img alt="arrow right icon" class="learn-more-arrow" src="https://www.pikpng.com/pngl/m/73-734729_arrow-blue-right-transparent-blue-arrow-right-clipart.png" loading="lazy">
</div>
`;
class CustomAnimLink extends HTMLElement {
constructor() {
super();
this.showInfo = true;
this.attachShadow({ mode: 'open' });
this.shadowRoot.appendChild(template.content.cloneNode(true));
this.shadowRoot.querySelector('a').innerText = this.getAttribute('name');
}
}
window.customElements.define('custom-anim-link', CustomAnimLink);
<custom-anim-link name="Learn more">
<div slot="destination">https://www.yahoo.com</div>
</custom-anim-link>
插槽不能做到这一点。插槽用于将 HTMLElement
放置在插槽的位置,不能用于除此之外的任何其他内容。
而是将 URL 作为属性传递。这似乎适合数据类型。 Web Components 有一些很好的生命周期来帮助你。
我添加了 static get observedAttributes()
以指示应遵守某些属性。这样做将使您能够在其中一个属性中的值发生更改时执行某些操作,例如更新 Shadow DOM.
只要观察到的属性值发生变化,就会调用 attributeChangedCallback
,您可以在其中确定值发生变化时应该发生什么。
observedAttributes
和 attributeChangedCallback
都是 Web 组件生命周期挂钩的一部分。
const template = document.createElement('template');
template.innerHTML = `
<style>
.txt-link a {
color: #005fec;
font-weight: 700;
font-size: 18px;
text-decoration: none;
position: relative;
}
.txt-link a:hover {
text-decoration: none;
cursor: pointer;
}
.txt-link a::before {
content: "";
position: absolute;
bottom: -5px;
left: 0;
width: 0;
height: 1px;
background-color: #005fec;
visibility: hidden;
transition: all 0.3s ease-in-out 0s;
}
.txt-link a:hover::before {
visibility: visible;
width: 100%;
}
.txt-link.arrow-link img {
height: 15px;
position: relative;
top: 2px;
}
</style>
<div class="txt-link arrow-link">
<a href=""><slot></slot></a>
<img alt="arrow right icon" class="learn-more-arrow" src="https://www.pikpng.com/pngl/m/73-734729_arrow-blue-right-transparent-blue-arrow-right-clipart.png" loading="lazy">
</div>
`;
class CustomAnimLink extends HTMLElement {
static get observedAttributes() {
return ['name', 'destination'];
}
constructor() {
super();
this.showInfo = true;
this.attachShadow({
mode: 'open'
});
this.shadowRoot.appendChild(template.content.cloneNode(true));
}
get anchor() {
return this.shadowRoot.querySelector('a');
}
get name() {
return this.getAttribute('name');
}
set name(value) {
if ('string' === typeof value) {
this.setAttribute('name', value);
}
}
get destination() {
return this.getAttribute('destination');
}
set destination(value) {
if ('string' === typeof value) {
this.setAttribute('destination', value);
}
}
attributeChangedCallback(attrName, oldValue, newValue) {
switch (attrName) {
case 'destination':
this.anchor.href = newValue;
break;
case 'name':
this.anchor.textContent = newValue;
break;
}
}
}
window.customElements.define('custom-anim-link', CustomAnimLink);
<custom-anim-link name="Learn more" destination="https://www.yahoo.com"></custom-anim-link>
或者,您可以在插槽的位置传递 <a>
标记。然后获取分配给 destination
插槽的所有元素,并根据 name
属性的值设置 textContent
属性。我们在上一个示例中添加的 destination
属性也是如此。
const template = document.createElement('template');
template.innerHTML = `
<style>
.txt-link a {
color: #005fec;
font-weight: 700;
font-size: 18px;
text-decoration: none;
position: relative;
}
.txt-link a:hover {
text-decoration: none;
cursor: pointer;
}
.txt-link a::before {
content: "";
position: absolute;
bottom: -5px;
left: 0;
width: 0;
height: 1px;
background-color: #005fec;
visibility: hidden;
transition: all 0.3s ease-in-out 0s;
}
.txt-link a:hover::before {
visibility: visible;
width: 100%;
}
.txt-link.arrow-link img {
height: 15px;
position: relative;
top: 2px;
}
</style>
<div class="txt-link arrow-link">
<slot name="destination"></slot>
<img alt="arrow right icon" class="learn-more-arrow" src="https://www.pikpng.com/pngl/m/73-734729_arrow-blue-right-transparent-blue-arrow-right-clipart.png" loading="lazy">
</div>
`;
class CustomAnimLink extends HTMLElement {
static get observedAttributes() {
return ['name', 'destination'];
}
constructor() {
super();
this.showInfo = true;
this.attachShadow({
mode: 'open'
});
this.shadowRoot.appendChild(template.content.cloneNode(true));
}
get destinations() {
const slot = this.shadowRoot.querySelector('slot');
const assignedElements = slot.assignedElements();
return assignedElements;
}
get name() {
return this.getAttribute('name');
}
set name(value) {
if ('string' === typeof value) {
this.setAttribute('name', value);
}
}
get destination() {
return this.getAttribute('destination');
}
set destination(value) {
if ('string' === typeof value) {
this.setAttribute('destination', value);
}
}
attributeChangedCallback(attrName, oldValue, newValue) {
switch(attrName) {
case 'name':
this.destinations.forEach(destination => {
destination.textContent = newValue;
});
break;
case 'destination':
this.destinations.forEach(destination => {
destination.href = newValue;
});
break;
}
}
}
window.customElements.define('custom-anim-link', CustomAnimLink);
<custom-anim-link name="Learn more" destination="https://www.yahoo.com">
<a slot="destination"></a>
</custom-anim-link>
或者作为最后的简单手段,只需将 <a>
作为您的自定义元素的子项完整传递。
<custom-anim-link>
<a href="https://www.yahoo.com">Learn more</a>
</custom-anim-link>