Thành phần web HTML không sử dụng kiểu DOM bóng
Tôi đã tạo một thành phần web vani hoặc phần tử HTML. Nó chỉ hiển thị hai liên kết.
Để đóng gói điều này, tôi sử dụng Shadow DOM. Tuy nhiên nó dường như không được gói gọn. Trong cây DOM, nó nằm trong # shadow-root là tốt.
Tại sao thành phần web sử dụng kiểu chung thay vì kiểu mà tôi đã cung cấp trong mẫu cho thành phần web của mình?
Chữ màu đỏ và tôi mong đợi nó có màu xanh lục.
class MyEl extends HTMLElement {
constructor() {
super();
this.shadow = this.attachShadow({ mode: "open" });
}
connectedCallback() {
const template = `
<style>
a {
color: green;
}
</style>
<slot></slot>`;
this.shadow.innerHTML = template;
}
}
window.customElements.define("my-el", MyEl);
a {
color: red
}
<my-el>
<a href="example.com">Item1</a>
<a href="example.com">Item2</a>
</my-el>
Trả lời
Mặc dù câu hỏi này đã có câu trả lời được chấp nhận, nhưng việc di chuyển con của một vị trí sang bóng đổ không phải là mong muốn đối với hầu hết các trường hợp sử dụng.
Những gì bạn có thể muốn làm là sử dụng ::slotted()
bộ chọn.
Chỉ cần lưu ý rằng các kiểu được áp dụng cho con của một vị trí thông qua ::slotted()
bộ chọn chỉ hoạt động như kiểu "mặc định" và vẫn có thể bị ghi đè bằng cách sử dụng các kiểu trong DOM nhẹ.
Ví dụ: hãy kiểm tra phiên bản đã chỉnh sửa này của đoạn mã của bạn:
Như bạn có thể thấy, lần này my-el
cố gắng áp dụng cả màu sắc và kiểu trang trí văn bản để neo ( <a>
) con trong bất kỳ vị trí nào của nó.
Tuy nhiên, trong dom sáng, chúng ta có một a.special
bộ chọn ghi đè màu, do đó, <a class="special">
sẽ có màu đỏ chứ không phải màu xanh lục
class MyEl extends HTMLElement {
constructor() {
super();
this.shadow = this.attachShadow({ mode: "open" });
}
connectedCallback() {
const template = `
<style>
::slotted(a) {
color: green;
text-decoration: none;
}
</style>
<slot></slot>`;
this.shadow.innerHTML = template;
}
}
window.customElements.define("my-el", MyEl);
a.special {
color: red
}
<my-el>
<a href="example.com">Item1</a>
<a class="special" href="example.com">Item2</a>
</my-el>
Giải thích đầy đủ, chi tiết có trong: :: bộ chọn CSS có rãnh cho các phần tử con lồng nhau trong vùng shadowDOM
TL; DR
Các liên kết của bạn nằm trong lightDOM và do đó được tạo kiểu bởi DOM của nó (trong mã của bạn là DOM tài liệu)
Di chuyển các nút từ lightDOM sang shadowDOM là một "giải pháp"; nhưng bạn không sử dụng khe cắm sau đó.
FYI, mã của bạn có thể được nén thành:
class MyEl extends HTMLElement {
constructor() {
super().attachShadow({ mode: "open" })
.innerHTML = `<style>a{color:green}</style><slot></slot>`;
}
}
window.customElements.define("my-el", MyEl);
Có thể tìm thấy thêm các câu trả lời liên quan đến SLOT với Tìm kiếm StackOverflow: SLOT yếu tố tùy chỉnh
quan sát dòng này, bạn phải di chuyển / sao chép các phần tử vào bóng, chẳng hạn với:
this.shadow.innerHTML = this.innerHTML + template;
Tôi đã thêm điều này để chứng minh rằng chỉ kiểu nội tuyến sẽ được áp dụng cho các phần tử dom bóng .. vì vậy các liên kết được sao chép trong SD đang sử dụng kiểu của bạn :)
vì vậy màu đỏ sẽ là GLOBAL
, màu xanh lá cây sẽ là SHADOW
yếu tố
class MyEl extends HTMLElement {
constructor() {
super();
}
connectedCallback() {
this.shadow = this.attachShadow({ mode: "open" });
const template = `
<style>
a {
color: green;
}
</style>
<slot></slot>`;
this.shadow.innerHTML = this.innerHTML + template;
}
}
window.customElements.define("my-el", MyEl);
a {
color: red
}
<my-el>
<a href="example.com">Item1</a>
<a href="example.com">Item2</a>
</my-el>