6

Tôi đã tạo một ví dụ đơn giản bằng cách sử dụng Thành phần web với hai phần tử tùy chỉnh (v1), trong đó một phần tử được lồng vào nhau. index.html:Phần tử lồng nhau (thành phần web) không thể lấy mẫu của nó

<!DOCTYPE html> 
<html> 
<head> 
    <meta charset="utf-8"> 
    <title>Example</title> 
    <meta name="description" content=""> 
    <meta name="viewport" content="width=device-width, initial-scale=1"> 
    <link rel="import" href="app-container.html"> 
</head> 
<body> 
    <app-container></app-container> 
</body> 
</html> 

app-container.html:

<link rel="import" href="toolbar.html"> 
<template id="app-container"> 
    <app-toolbar></app-toolbar> 
</template> 
<script> 
    customElements.define('app-container', class extends HTMLElement { 
    constructor() { 
     super(); 
     let shadowRoot = this.attachShadow({ mode: 'open' }); 
     const content = document.currentScript.ownerDocument.querySelector('#app-container').content; 
     shadowRoot.appendChild(content.cloneNode(true)); 
    } 
    }); 
</script> 

toolbar.html:

Nhưng trong toolbar.html document.currentScript cũng giống như trong ứng dụng -container.html và do đó querySelector('#app-toolbar') không thể tìm thấy mẫu có id app-toolbar. Làm thế nào để giải quyết vấn đề này?

Ví dụ được thử nghiệm trên Chrome 55 (không có chèn lấp).

Trả lời

13

document.currentScript chứa tham chiếu đến tập lệnh hiện được phân tích cú pháp và thực thi. Do đó nó không còn hiệu lực cho mục đích của bạn khi chức năng constructor() được gọi (từ tập lệnh khác).

Thay vào đó bạn shoud lưu giá trị của nó trong một biến vào đầu của kịch bản, và sử dụng biến này trong các nhà xây dựng:

<script> 
    var currentScript = document.currentScript 
    customElements.define(...) 
    ... 
</script> 

Nếu bạn có nhiều kịch bản, bạn nên sử dụng tên riêng biệt.

Cách khác, bạn có thể gói gọn giá trị phù du trong một đóng cửa:

(function(owner) { 
    customElements.define('app-container', class extends HTMLElement { 
     constructor() { 
      super(); 
      let shadowRoot = this.attachShadow({ mode: 'open' }); 
      const content = owner.querySelector('#app-container').content; 
      shadowRoot.appendChild(content.cloneNode(true)); 
     } 
    }); 
})(document.currentScript.ownerDocument); 

Ở đây, giá trị document.currentScript.ownerDocument được gán cho owner tranh luận mà vẫn được xác định một cách chính xác khi constructor() được gọi.

owner được định nghĩa cục bộ để bạn có thể sử dụng cùng một tên trong tài liệu khác.

+0

Supersharp, Rất cám ơn! Chúc mừng năm mới! –

+0

Cảm ơn, bạn cũng vậy! – Supersharp

Các vấn đề liên quan