【问题标题】:Why custom elements not support attributes as an object?为什么自定义元素不支持属性作为对象?
【发布时间】:2016-12-19 06:26:48
【问题描述】:

我正在尝试将自定义元素中的数据属性作为对象传递,但同时在 attachCallback 方法中接收以字符串形式获取值“[object object]”。

那么任何人都可以帮助我弄清楚如何将属性作为对象在自定义元素(Web 组件)中获取。

代码示例

<script>
class myElements extends HTMLElement {
    createdCallback() {
        this.innerHTML = `<h1>Hello</h1>`;
    }
    attachedCallback() {
        console.log(this.getAttribute('data'));
    }
}

 document.registerElement('my-element', myElements);
</script>

自定义元素标签

<script>
    var object = { key1: 111, key2: 222, key3: function(){return "hi"}, key4:[1,2,3]};

   function changeHandler() {
    page('/default', function() {
        // some logic to decide which route to redirect to
        if (admin) {
            page.redirect('/admin');
        } else {
            page.redirect('/guest');
        }
    });
}

</script>

<my-element data="object" onchange="changeHandler"></my-element>

注意:假设&lt;my-element&gt; 是一个下拉菜单,让用户可以选择一些值。

解决方案:自定义元素规范中仍然没有原生解决方案(v0v1)。

由于自定义元素不支持数据绑定,因此我们需要一个糖化层(例如,Polymer 或 SkateJS),正如@tony 在评论中提到的那样。

【问题讨论】:

  • data-* 属性值处缺少引号。在html元素的属性中存储函数的目的是什么?
  • 你可以试试这样的:stackoverflow.com/questions/11697863/…
  • @coder "主要目的是将属性中的函数作为回调处理程序传递"你有什么问题?您可以将object 定义为全局变量,并使用括号表示法来引用object
  • objectchangeHandler 只是这些属性值中的字符串,与您的 JS 代码无关。请告诉我们您用于获取[object object]的确切代码。

标签: javascript web-component custom-element


【解决方案1】:

尝试将对象转换为 JSON 字符串,

var object = { key1: 111, key2: 222};
JSON.stringify(object);

然后当你想获取值时,将其解析回对象

JSON.parse(this.getAttribute('data'));

【讨论】:

  • 感谢@Himanshu 的评论和不完整的对象格式抱歉....但是这种类型的对象 var object = { key1: 111, key2: 222, key3: function(){return "嗨"}, key4:[1,2,3]};
  • 建议的方法(字符串化和解析)不适用于内部具有函数作为值的对象。
【解决方案2】:

自定义元素不会修改标准的 HTML 元素属性行为,该行为始终为 string 类型。

因此,您应该:

  1. 从您的自定义元素发送一个change 事件,该事件将触发onchange 处理程序。

  2. 通过自定义元素方法注册您的对象/函数回调。

  3. 修改一个 state 属性,该属性将被其容器观察(使用Mutation Observer)。

如果你想使用属性,你总是可以使用eval()


调用changeHandler()的解决方案1示例:

//define custom element
class DropDown extends HTMLElement 
{
  connectedCallback ()
  {
    var span = this.querySelector( 'span' )

    //define ul list
    var ul = this.querySelector( 'ul' )

    ul.onclick = ev => {
      if ( this.value != ev.target.textContent )
      {
        this.value = ev.target.textContent
        this.setAttribute( 'value', this.value )
        span.textContent = this.value 
        this.dispatchEvent( new CustomEvent( 'change' ) )
      }
    }

    //show or hide
    this.onclick = ev => ul.classList.toggle( 'show' )
    
  }

}
customElements.define( 'drop-down', DropDown )
drop-down  {
  position: relative ;
  cursor: pointer ;
  display: inline-block ;
}
drop-down > span {
  border: 1px solid #aae ;
  padding: 2px 5px ;
}
drop-down > ul {
  position: absolute ;
  top: 4px ; left: 5px ;
  list-style: none ;
  outline: 1px solid #aae ;
  padding: 0 ;
  display: inline-block ;
  opacity: 0 ;
  transition: all 0.3s ease-out ;
  background: white ;
  visibility: hidden ;
  z-index: 10 ;
}
drop-down > ul.show {
  opacity: 1 ;
  visibility: visible ;
}
drop-down > ul > li {
  padding: 2px 5px ;
}
drop-down > ul > li:hover {
  background: lightgoldenrodyellow ;
}
<drop-down onchange="changeHandler()">
  <span>select value</span>
  <ul>
    <li>Chrome</li>
    <li>Firefox</li>
    <li>Opera</li>
    <li>Safari</li>
  </ul>
</drop-down>

<script>
  function changeHandler ()
  {
    console.log( 'changeHandler()', event.target.value )
  }
</script>

【讨论】:

    猜你喜欢
    • 2022-01-11
    相关资源
    最近更新 更多