如何代理自定义元素(Web组件)

时间:2022-09-02 12:14:10

class A extends HTMLElement {
  constructor() {
    super()
    return new Proxy(this, {})
  }
}

class B extends A {
  constructor() {
    super()
  }
}

window.customElements.define('b-element', B)
<b-element></b-element>

How can i Proxy custom element?

如何代理自定义元素?

When i try it: "Uncaught InvalidStateError: custom element constructors must call super() first and must not return a different object"

当我尝试:“Uncaught InvalidStateError:自定义元素构造函数必须首先调用super(),并且不能返回不同的对象”

1 个解决方案

#1


6  

You can either Proxify a class or an instance of a Custom Element.

您可以对一个类或一个自定义元素的实例进行Proxify。

Given the following Custom Element definition:

给定以下自定义元素定义:

class A extends HTMLElement {
  constructor() {
    super()
  }
  connectedCallback() {
    this.innerHTML = 'Hello'    
  }
}
customElements.define( 'a-element', A )

Proxy for a Custom Element instance

自定义元素实例的代理

Create a Proxy from an instance reference (here: ae):

从实例引用创建代理(这里:ae):

<a-element id="ae"></a-element>
<script>
  var b1 = new Proxy( ae, {
    get ( target, value ) { return target[value] }       
  } )
  console.log( b1.innerHTML ) // => "Hello"
</script>

Proxy for a Custom Element class

自定义元素类的代理

Define the construct trap to catch the new operator:

定义构造陷阱以捕获新操作符:

<script>
  var B = new Proxy( A, {
    construct() { return new A }
  } )
  var b2 = new B
  document.body.appendChild( b2 )
  console.log( b2.innerHTML ) // => "Hello"
</script>

Get a Custom Element instance Proxy from a class Proxy

从类代理中获取自定义元素实例代理

If you want to instanciate a Custom Element and get one Proxy object directly, you can combine both solutions above.

如果您希望实例化一个自定义元素并直接获得一个代理对象,您可以将上面的两个解决方案组合在一起。

The following example shows how to get a Proxy for element <a-element> that will log in the console each property access. The construct() trap defined in the class Proxy returns itself a Proxy for the instanciated Custom Element.

下面的示例展示了如何为元素 获取代理,该代理将登录到控制台的每个属性访问。在类代理中定义的构造()陷阱返回实例自定义元素的代理。

class A extends HTMLElement {
  constructor() {
    super()
  }
  connectedCallback() {
    this.innerHTML = 'Hello'    
  }
}
customElements.define( 'a-element', A )		

var P = new Proxy( A, {
  construct () { 
    return new Proxy ( new A, {
      get ( target, value ) { 
        if ( value == 'element' ) 
          return target
        console.info( `proxy: property ${value} for <${target.localName}> is "${target[value]}"` )
        return target[value]
      }       
    } )
  }
} )
var p = new P
document.body.appendChild( p.element )
console.log( p.innerHTML )

#1


6  

You can either Proxify a class or an instance of a Custom Element.

您可以对一个类或一个自定义元素的实例进行Proxify。

Given the following Custom Element definition:

给定以下自定义元素定义:

class A extends HTMLElement {
  constructor() {
    super()
  }
  connectedCallback() {
    this.innerHTML = 'Hello'    
  }
}
customElements.define( 'a-element', A )

Proxy for a Custom Element instance

自定义元素实例的代理

Create a Proxy from an instance reference (here: ae):

从实例引用创建代理(这里:ae):

<a-element id="ae"></a-element>
<script>
  var b1 = new Proxy( ae, {
    get ( target, value ) { return target[value] }       
  } )
  console.log( b1.innerHTML ) // => "Hello"
</script>

Proxy for a Custom Element class

自定义元素类的代理

Define the construct trap to catch the new operator:

定义构造陷阱以捕获新操作符:

<script>
  var B = new Proxy( A, {
    construct() { return new A }
  } )
  var b2 = new B
  document.body.appendChild( b2 )
  console.log( b2.innerHTML ) // => "Hello"
</script>

Get a Custom Element instance Proxy from a class Proxy

从类代理中获取自定义元素实例代理

If you want to instanciate a Custom Element and get one Proxy object directly, you can combine both solutions above.

如果您希望实例化一个自定义元素并直接获得一个代理对象,您可以将上面的两个解决方案组合在一起。

The following example shows how to get a Proxy for element <a-element> that will log in the console each property access. The construct() trap defined in the class Proxy returns itself a Proxy for the instanciated Custom Element.

下面的示例展示了如何为元素 获取代理,该代理将登录到控制台的每个属性访问。在类代理中定义的构造()陷阱返回实例自定义元素的代理。

class A extends HTMLElement {
  constructor() {
    super()
  }
  connectedCallback() {
    this.innerHTML = 'Hello'    
  }
}
customElements.define( 'a-element', A )		

var P = new Proxy( A, {
  construct () { 
    return new Proxy ( new A, {
      get ( target, value ) { 
        if ( value == 'element' ) 
          return target
        console.info( `proxy: property ${value} for <${target.localName}> is "${target[value]}"` )
        return target[value]
      }       
    } )
  }
} )
var p = new P
document.body.appendChild( p.element )
console.log( p.innerHTML )