我想创建一个自定义选择标记,例如我希望它继承所有属性。我试过了:
document.registerElement('my-select', {
prototype: Object.create(HTMLSelectElement.prototype),
extends: 'select'
});
document.registerElement('my-option', {
prototype: Object.create(HTMLOptionElement.prototype),
extends: 'option'
});
但它似乎不起作用。我做错了什么?
答案 0 :(得分:1)
您只提供了构建自定义选择组件的抽象方法。实现将包括创建两个原型,即select和option,最后使用我们将在HTML页面中声明的自定义选择框将其挂起。< / p>
查看演示文稿的小提琴链接: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>
答案 1 :(得分:0)
自问这个问题以来已经有一段时间了。但是我遇到它想要做同样的事情。现在看来v0和v1规格一团糟。尽管对HTMLButtonElement使用相同的代码,但它在chrome中抛出非法构造函数,与使用HTMLSelectElement相同。我已经开始写这个并认为我会分享。它可以被清理,并且添加了更多的选择元素方法,但是其他人可以从这里获取它以根据他们的需要进行调整。
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);
}