使用 slot 时如何使用 javascript 找到父元素宽度

How to find the parent element width using javascript when we are using slot

我有一个自定义元素,其中一个 div 包含插槽。

在那个插槽中,我有 JS 脚本,我想在其中获取插槽父级的宽度 div。

我知道单词很容易混淆 :)。

here is the sample code link

<!doctype html>
<body>
<script>
customElements.define('user-card', class extends HTMLElement {
  connectedCallback() {
    this.attachShadow({mode: 'open'});
    this.shadowRoot.innerHTML = `
      <style>
        .name {
          font-size: 24px;
          width:200px;
          background-color: yellow
        }
      </style>
      <div class="name">Name:
        <slot name="username"></slot>
      </div>
      <div class="dob">Birthday:
        <slot name="birthday"></slot>
      </div>
    `;
    this.shadowRoot.styles = `

    `
  }
});
</script>

<user-card>
  <span slot="username">
    <script>
      function abc(event) {
        console.log('Expected: ', this.document.getElementsByTagName('user-card')[0].shadowRoot.querySelectorAll('div.name')[0].offsetWidth)
        console.log('Result: ',event.target.parentElement.offsetWidth);
      }

    </script>
    <div onclick="abc(event)">
      Ritesh Rajput
      </div>

  </span>
  <span slot="birthday">01.01.2001</span>
</user-card>
</body>

理想情况下两者应该 return 相同的值

console.log('Expected: ', this.document.getElementsByTagName('user-card')[0].shadowRoot.querySelectorAll('div.name')[0].offsetWidth)
console.log('Result: ',event.target.parentElement.offsetWidth);

在第二个日志中,元素 event.target.parentElement<span slot="username"><span>inline 并且宽度为 0.

如果您想读取其宽度,您必须将 CSS 显示 属性 设置为 inline-block

您可以在首页定义:

<head>
  <style>
    span[slot=username] {
      display: inline-block;
      width: 100%; 
    }
  </style>
</head>

或者在 Shadow DOM 中通过 ::slotted() CSS 伪元素:

<style>
  ::slotted(span[slot=username]) {
      display: inline-block;
      width: 100%;         
  }
</style>

customElements.define('user-card', class extends HTMLElement {
  connectedCallback() {
    this.attachShadow({mode: 'open'})
        .innerHTML = `
      <style>
        div.name {
          font-size: 24px;
          width: 200px;
          background-color: yellow;
          display: inline-block;
        }
        ::slotted(span[slot="username"]) {
          display: inline-block; 
          width: 100%;
        }
      </style>
      <div class="name">Name :
        <slot name="username"></slot>
      </div>
      <div class="dob">Birthday:
        <slot name="birthday"></slot>
      </div>
    `
  }
})

function abc(event) {
  console.log('Expected: ', this.document.getElementsByTagName('user-card')[0].shadowRoot.querySelector('.name').offsetWidth)
  console.log('Result: ', event.target.parentElement.offsetWidth)
}
<user-card>
  <span slot="username">
    <div onclick="abc(event)">Ritesh Rajput</div>
  </span>
  <span slot="birthday">01.01.2001</span>
</user-card>