在自定义元素 Shadow DOM 中选择插槽文本

Oll*_*ams 4 javascript shadow-dom custom-element

我用普通的 html/css/js 制作了一个简单的复制粘贴组件。我试图将它变成一个 Web 组件,但无法再使复制粘贴行为起作用。

shadow DOM 内部的标记基本上是

<span contenteditable="true">
  <slot></slot>
</span>
<button>Copy</button>
Run Code Online (Sandbox Code Playgroud)

Javascript:

class CopyPaste extends HTMLElement {
  constructor() {
    super();
    let shadowRoot = this.attachShadow({mode: 'open'});
    shadowRoot.appendChild(copyPasteTemplate.content.cloneNode(true));
  }

  connectedCallback() {
    let copyButton = this.shadowRoot.querySelector('button');
    let textToCopy = this.shadowRoot.querySelector('span');

    function selectElementContents(el) {
      var range = document.createRange();
      range.selectNodeContents(el);
      var sel = window.getSelection();
      sel.removeAllRanges();
      sel.addRange(range);
    }

    function copyText() {
      selectElementContents(textToCopy);
      document.execCommand('copy');
    }

    copyButton.addEventListener('click', copyText);
    textToCopy.addEventListener('click', copyText);
  }
}

window.customElements.define('copy-paste', CopyPaste);
Run Code Online (Sandbox Code Playgroud)

Sup*_*arp 7

在您的示例中,textToCopy变量指的是<slot>元素,内部没有文本。

如果你想从<copy-paste>元素的轻量DOM中获取分布式节点,你应该使用元素的assignedNodes()方法<slot>

let textToCopy = this.shadowRoot.querySelector('slot').assignedNodes()[0];
Run Code Online (Sandbox Code Playgroud)

PS:请注意,该contenteditable属性可能无法按您在给定示例中的预期工作。

  • 考虑使用“{flatten: true}”,这样当“&lt;slot&gt;”从父级插槽填充时仍然有效:“this.shadowRoot.querySelector('slot').assignedNodes({flatten: true})[0] ;`(这是在上面答案链接的文档中) (3认同)