【问题标题】:How to wrap an input field in a custom element?如何将输入字段包装在自定义元素中?
【发布时间】:2019-02-05 10:12:51
【问题描述】:

我正在尝试将输入字段包装在自定义元素中。

自定义元素 DOM 如下所示:

<custom-element>
  <div class="fancy-wrapper">
     <input value="4">
  </div>
<custom-element>

虽然元素应该像这样工作:

<custom-input id="test"></custom-input>

<script>
let test = document.getElementById('test')
console.log(test.value); //  should return 4 (value of inner input)

test.onkeydown = function(e){
    console.log(e.target.value); // should the new value of the inner input
};
</script>

有什么方法可以将&lt;custom-input&gt; 属性重定向到其中的&lt;input&gt; 属性,而无需手动连接所有内容?

【问题讨论】:

    标签: javascript html custom-element


    【解决方案1】:

    不,这与拥有一个 DIV 和另一个子 DIV 没有什么不同

    您必须自己在 CustomElement 和内容之间建立连接。

    一种方法是在您的自定义元素上定义一个获取/设置函数来获取子输入的值

    您当然可以循环任何子元素并使用 definePropertyProxies 在 CustomElement 上分配,而不是手动声明 Get/Set

    下面的示例创建了 2 个 INPUT 字段和一个 this.input 数组:

        <number-and-range>
           <input type="number"> // this.input[0]
           <input type="range">  // this.input[1]
        </number-and-range>
    

    并将 (GET/SET) &lt;number-and.range&gt;.value 连接到 this.input[0]

    customElements.define('number-and-range', class extends HTMLElement {
      get value() {
        return this.input[0].value;
      }
    
      set value(val) {
        //input validation should go here
        this.input[0].value = val;
        console.clear();
        console.log('new value:',val);
      }
      connectedCallback() {
        this.input = ['number', 'range'] //create [0] and [1] values in array
          .map((type, idx) => Object.assign(
            this.appendChild(document.createElement('input')), {
              type,
              min: 20,
              max: 50,
              oninput: _ => this.value = this.input[~~!idx].value = this.input[idx].value //toggle [0] and [1]
            }));
        this.value = 42;//default value
      }
    });
    
    let el=document.querySelector('number-and-range');
    console.log(el.value);
    el.value=99;
    <body>
    <h3>Custom Element : Connected INPUT and Range slider</h3>
    Please enter a number between 20 and 50, or use the range slider
    <p>
    <number-and-range></number-and-range>
    </p>
    </body>

    【讨论】:

      【解决方案2】:

      如果我理解您的问题,您想将custom-element 的所有属性复制到input 标记。

      你能做的是,

      //get all attributes of custom element
      var el = document.getElementById ('test');
      
      // get all attributes
      var attrs = el.getAttributeNames(); // returns an array
      
      // loop over attrs array and append the attribute and value in the input,
      // I am assuming, you will not add copy id attribute here.
      
      var input = el.getElementsByTagName ('input')[0];
      for (var index = 0; index < attrs.length; index++) {
        if (attrs[index] !== 'id') {
      
          // set attribute of input with attribute name from the array,
          // and get the value from from input.
      
          input.setAttribute (attrs[index], el.getAttribute (attrs[index]));
        }
      }
      

      这是一个想法,你可以做其他事情。

      【讨论】:

        【解决方案3】:

        HTML:

        <custom-element id="test">
          <div><input value="43" /></div>
        </custom-element> 
        

        JavaScript:

        class CustomElement extends HTMLElement {
          constructor() {
            super();
            const currentDocument = document.currentScript.ownerDocument;
            this.template = currentDocument.querySelector('input');
          }
          get value() {
            return this.template.getAttribute('value');
          }
          set onkeydown(cb) {
            return this.template.addEventListener('keydown', cb);
          }
        }
        
        window.customElements.define('custom-element', CustomElement);
        
        let test = document.getElementById('test');
        console.log(test.value);
        test.onkeydown = function(e) {
          console.log(e.target.value);
        };
        

        可以看看demo

        【讨论】:

        • 我知道如何创建自定义元素,问题是如何在输入元素周围创建一个包装器,而不会失去对它的直接访问。
        • 问题不清楚,抱歉。根据问题@Daveman 重构
        【解决方案4】:

        可以追加到自定义元素标签的innerHTML

        var string="<input type='text' ";
        document.getElementById('test').onclick = function(e){
        var attr=[...document.querySelector('#test').attributes].map(attr => attr.nodeName);
        attr.forEach((e)=>{
        var val=document.getElementById('test').getAttribute(e);
        string+=e+"="+val + " ";
        })
        document.getElementById("test").innerHTML+=string + '//>' ;
        console.log(document.getElementById("test").outerHTML)
        };
        &lt;custom-input id="test"&gt;dd&lt;/custom-input&gt;

        【讨论】:

        • 我编辑了这个问题,让它更清楚我想要做什么。我的问题不是关于将元素分配给自定义元素,我基本上想要一个自定义 HTMLInputElement 但其他元素围绕真实输入。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-08-18
        • 2018-07-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-04
        • 2016-04-16
        • 1970-01-01
        相关资源
        最近更新 更多