表单 – 本机形式的自定义输入元素

前端之家收集整理的这篇文章主要介绍了表单 – 本机形式的自定义输入元素前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
使用网络组件,人们想要创建和覆盖的元素之一是< input>.输入元素是坏的,因为它们根据类型很多,通常很难自定义,所以人们总是想修改它们的外观和行为是正常的.

两年前或多或少地,当我第一次听到网路组件时,我很兴奋,我想要创建的第一种元素是自定义输入元素.现在规格完成了,就像我对输入元素的需求没有解决.阴影DOM应该允许我改变他们的内部结构和外观,但输入元素被列入黑名单,不能有一个影子根源,因为它们已经有一个隐藏的.如果我想添加额外的逻辑和行为,定制,内置元素与属性应该做的技巧;我不能做影子DOM魔法,但至少我有这个,对吧?好的Safari不会实现它,聚合物不会使用它们,因为这样的原因,闻起来就像将要被废弃的标准.

所以我留下了正常的自定义元素;他们可以使用阴影DOM,并有任何我想要的逻辑,但我希望他们成为输入!他们应该在< form>内部工作,但如果我是正确的,表单元素不喜欢它们.我必须编写自己的自定义表单元素,以及复制所有原生的表单元素吗?我必须告别FormData,验证API等吗?我是否失去了能够使用没有javascript的输入的表单?

解决方法

您可以创建一个具有所需外观和行为的自定义元素.

在其中放置一个隐藏的< input>元素,其名称(将被传递到< form>)).

修改自定义元素“可见值”时,更新其值属性.

我在this answer to a similar SO question发了一个例子.

  1. class CI extends HTMLElement
  2. {
  3. constructor ()
  4. {
  5. super()
  6. var sh = this.attachShadow( { mode: 'open' } )
  7. sh.appendChild( tpl.content.cloneNode( true ) )
  8. }
  9.  
  10. connectedCallback ()
  11. {
  12. var view = this
  13. var name = this.getAttribute( 'name' )
  14.  
  15. //proxy input elemnt
  16. var input = document.createElement( 'input' )
  17. input.name = name
  18. input.value = this.getAttribute( 'value' )
  19. input.id = 'realInput'
  20. input.style = 'width:0;height:0;border:none;background:red'
  21. input.tabIndex = -1
  22. this.appendChild( input )
  23.  
  24.  
  25. //content editable
  26. var content = this.shadowRoot.querySelector( '#content' )
  27. content.textContent = this.getAttribute( 'value' )
  28. content.oninput = function ()
  29. {
  30. //console.warn( 'content editable changed to',content.textContent )
  31. view.setAttribute( 'value',content.textContent)
  32. }
  33.  
  34. //click on label
  35. var label = document.querySelector( 'label[for="' + name + '"]' )
  36. label.onclick = function () { content.focus() }
  37.  
  38. //autofill update
  39. input.addEventListener( 'change',function ()
  40. {
  41. //console.warn( 'real input changed' )
  42. view.setAttribute( 'value',this.value )
  43. content.value = this.value
  44. } )
  45.  
  46. this.connected = true
  47. }
  48.  
  49. attributeChangedCallback ( name,old,value )
  50. {
  51. //console.info( 'attribute %s changed to %s',name,value )
  52. if ( this.connected )
  53. {
  54. this.querySelector( '#realInput' ).value = value
  55. this.shadowRoot.querySelector( '#content' ).textContent = value
  56. }
  57. }
  58.  
  59. }
  60. CI.observedAttributes = [ "value" ]
  61. customElements.define( 'custom-input',CI )
  62. //Submit
  63. function submitF ()
  64. {
  65. for( var i = 0 ; i < this.length ; i++ )
  66. {
  67. var input = this[i]
  68. if ( input.name ) console.log( '%s=%s',input.name,input.value )
  69. }
  70. }
  71. S1.onclick = function () { submitF.apply(form1) }
  1. <form id=form1>
  2. <table>
  3. <tr><td><label for=name>Name</label> <td><input name=name id=name>
  4. <tr><td><label for=address>Address</label> <td><input name=address id=address>
  5. <tr><td><label for=city>City</label> <td><custom-input id=city name=city></custom-input>
  6. <tr><td><label for=zip>Zip</label> <td><input name=zip id=zip>
  7. <tr><td colspan=2><input id=S1 type=button value="Submit">
  8. </table>
  9. </form>
  10. <hr>
  11. <div>
  12. <button onclick="document.querySelector('custom-input').setAttribute('value','Paris')">city => Paris</button>
  13. </div>
  14.  
  15. <template id=tpl>
  16. <style>
  17. #content {
  18. background: dodgerblue;
  19. color: white;
  20. min-width: 50px;
  21. font-family: Courier New,Courier,monospace;
  22. font-size: 1.3em;
  23. font-weight: 600;
  24. display: inline-block;
  25. padding: 2px;
  26. }
  27. </style>
  28. <div contenteditable id=content></div>
  29. <slot></slot>
  30. </template>

猜你在找的HTML相关文章