Komponen web HTML tidak menggunakan gaya shadow DOM

Aug 15 2020

Saya telah membuat komponen web vanilla atau elemen HTML. Ini hanya menampilkan dua tautan.

Untuk merangkumnya, saya menggunakan shadow DOM. Namun tampaknya tidak dikemas. Di pohon DOM itu ada di dalam # shadow-root yang bagus.

Mengapa komponen web menggunakan gaya global daripada gaya yang saya berikan di template untuk komponen web saya?

Teksnya berwarna merah dan saya berharap warnanya hijau.

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>

Jawaban

1 AlanDávalos Aug 17 2020 at 15:12

Meskipun pertanyaan ini sudah memiliki jawaban yang diterima, memindahkan turunan slot ke shadowRoot tidak diinginkan untuk sebagian besar kasus penggunaan.

Yang mungkin ingin Anda lakukan adalah menggunakan ::slotted()selektor.

Perlu diingat bahwa gaya yang diterapkan ke turunan slot melalui ::slotted()pemilih hanya berfungsi sebagai gaya "default" dan masih dapat diganti dengan menggunakan gaya di light DOM.

Misalnya, periksa versi cuplikan Anda yang diedit ini:

Seperti yang Anda lihat, kali ini my-elmencoba menerapkan warna dan gaya dekorasi teks ke anak jangkar ( <a>) di salah satu slotnya.

Namun, dalam dom cahaya, kami memiliki a.specialpemilih yang menimpa warna, jadi warnanya <a class="special">merah, bukan hijau

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>

1 Danny'365CSI'Engelman Aug 15 2020 at 23:44

Penjelasan lengkap dan mendetail ada di: :: selektor CSS berlubang untuk turunan bersarang di slot shadowDOM

TL; DR

Tautan Anda ada di lightDOM dan dengan demikian ditata oleh DOM-nya (dalam kode Anda DOM dokumen)
Memindahkan node dari lightDOM ke shadowDOM adalah salah satu "solusi"; tetapi Anda tidak menggunakan slot.

FYI, kode Anda dapat dipadatkan menjadi:

class MyEl extends HTMLElement {
  constructor() {
    super().attachShadow({ mode: "open" })
           .innerHTML = `<style>a{color:green}</style><slot></slot>`;

  }
}

window.customElements.define("my-el", MyEl);

Lebih banyak jawaban terkait SLOT dapat ditemukan dengan Pencarian StackOverflow: SLOT Elemen Kustom

KresimirPendic Aug 15 2020 at 19:57

Perhatikan baris ini, Anda harus memindahkan / menyalin elemen ke bayangan misalnya dengan:

this.shadow.innerHTML = this.innerHTML + template;

Saya telah menambahkan ini untuk menunjukkan bahwa hanya gaya sebaris yang akan diterapkan ke elemen dom bayangan .. jadi tautan yang disalin di SD menggunakan gaya Anda :)

jadi merah akan menjadi GLOBAL, hijau akan menjadi SHADOWelemen

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>