2016-07-26 221 views
0

我想创建一个自定义选择标记,例如我希望它继承所有的属性。我试过:自定义选择标记

document.registerElement('my-select', { 
    prototype: Object.create(HTMLSelectElement.prototype), 
    extends: 'select' 
}); 

document.registerElement('my-option', { 
    prototype: Object.create(HTMLOptionElement.prototype), 
    extends: 'option' 
}); 

但它似乎不起作用。我做错了什么?

回答

1

您只提供了构建自定义选择组件的抽象方法,该实现将包括创建两个原型,即select和option,最后将它与我们将在HTML页面中声明的自定义选择框挂钩。

结帐这个拨弄链接,演示https://jsfiddle.net/47gzo8kt/

的Javascript:

var CustomizedSelectOptionPrototype = Object.create(HTMLElement.prototype); 
document.registerElement('cust-select-option', { prototype: CustomizedSelectOptionPrototype}); 

var CustomizedSelectProto = Object.create(HTMLSelectElement.prototype); 
CustomizedSelectProto.createdCallback = function() { 
    if (!this.getAttribute('tabindex')) { 
     this.setAttribute('tabindex', 0); 
    } 
    this.placeholder = document.createElement('span'); 
    this.appendChild(this.placeholder); 

    var selected = this.querySelector('cust-select-option[selected]'); 
    this.placeholder.textContent = selected ? selected.textContent : (this.getAttribute('placeholder') || ''); 
}; 
document.registerElement('cust-select', { prototype: CustomizedSelectProto, extends:"select"}); 

HTML:

<label> 
    Customized Select Box: 
    <select is="cust-select" placeholder="Please select an option"> 
     <option selected value="1">English</option> 
     <option value="2">French</option> 
     <option value="3">Hindi</option> 
    </select> 
</label> 
+0

没有那不是我想要什么,我想写: <卡斯特 - 选择选项> .... .... –

+0

我想卡斯特选到表现就像 * *扩展选择框的方式 –

0

它已经一段时间,因为这个问题被问。然而我碰到它想要做同样的事情。看来v0和v1的规格现在很乱。尽管使用HTMLButtonElement的代码相同,但它使用HTMLSelectElement的方式将非法构造函数置于chrome中。我已经开始写这篇文章,并认为我会分享。它可以被清理并添加更多的select元素方法,但是可以指望其他人可以从这里采取它来根据他们的需求进行定制。

class mySelectElement extends HTMLElement { 
    static get observedAttributes() { return ['disabled']; } 
    constructor() { 
     super(); 
     let shadowRoot = this.attachShadow({ 
       mode: 'open' 
      }), 
      content = document.createElement('slot'), 
      options = null; 
     content.setAttribute('select', 'option'); 
     shadowRoot.innerHTML = `<style> 
:host([disabled]) { 
background: grey; 
pointer-events: none; 
opacity: 0.4; 
pointer-events: none; 
height: 16px; 
} 
:host:before{ 
content: ''; 
} 
:host{ 
contain: layout size style; 
overflow: auto; 
align-items:center; 
background-color:rgb(255, 255, 255); 
border: 1px solid black; 
color:rgb(0, 0, 0); 
display:inline-block; 
font: 13.3333px Arial; 
height:16px; 
width:145px; 
writing-mode:horizontal-tb; 
-webkit-appearance:menulist; 
-webkit-rtl-ordering:logical; 
} 
.hide{ 
display:none; 
} 
#options{ 
position: fixed; 
border:1px solid blue; 
}  
::slotted(option){ 
background-color:white; 
} 
::slotted(:hover){ 
background-color: #a4d8d2; 
} 
</style> 
<div id="options" class="hide"></div>`; 
     options = shadowRoot.getElementById('options'); 
     options.appendChild(content); 
     this.disabled = false; 
     this.setAttribute('tabIndex', -1); 
     this.addEventListener('click', function (e) { 
      let target = e.target; 
      if (target.nodeName == 'OPTION') { 
       this.value = target.value; 
       Array.from(target.parentElement.children).forEach(x => x.removeAttribute('selected')); 
       target.setAttribute('selected', ''); 
       shadowRoot.styleSheets[0].rules[1].style.cssText = "content: " 
        + '"' + target.textContent + '"'; 
       this.blur(); 
      } 
     }); 
     this.addEventListener('focus', function() { 
      let rect = this.getBoundingClientRect(); 
      options.style.top = rect.bottom; 
      options.style.left = rect.left; 
      options.style.width = rect.width; 
      options.classList.remove('hide'); 
     }); 
     this.addEventListener('focusout', function() { 
      options.classList.add('hide'); 
     }); 
     this.add = function (item) { 
      this.appendChild(item); 
      if (this.value == undefined) { 
       this.value = content.assignedNodes()[0].value; 
       content.assignedNodes()[0].setAttribute('selected', ''); 
       shadowRoot.styleSheets[0].rules[1].style.cssText = "content: " + 
        '"' + content.assignedNodes()[0].textContent + '"'; 
      } 
     } 
     this.item = function (i) { 
      return content.assignedNodes()[i]; 
     } 
     this.namedItem = function (val) { 
      return content.assignedNodes().find(x => x.value == val); 
     } 
     this.remove = function (i) { 
      return content.assignedNodes()[i].remove(); 
     } 
    } 
    attributeChangedCallback(attributeName, oldValue, newValue, namespace) { 
     if (attributeName == 'disabled') { 
      if (newValue = '') 
       this.disabled = true; 
      else if (newValue == null) 
       this.disabled = false; 
     } 

    } 
} 

customElements.define('my-select', mySelectElement); 
var _select = customElements.get('my-select'); 

var select = new _select; 
document.body.appendChild(select); 
for (let i = 0; i < 10; i++) { 
    let option = document.createElement('option'); 
    option.innerHTML = 'hello_' + i; 
    option.value = 'h' + i; 
    select.add(option); 
}