重复元素的事件处理程序
Event handler on repeated element
我是 hyperHTML 的新手,正在试用它。这是我的问题。如何为重复的模板元素添加事件处理程序。这是我的网络组件:
import css from './component.css';
import isJson from '../utils/isJson.js';
const hyper = hyperHTML;
class IdxAdminTab extends HTMLElement {
constructor() {
super();
this.attachShadow({mode: 'open'});
}
attributeChangedCallback(name, oVal, nVal) {
if (name === 'tabs' && isJson(nVal)) {
this.tabs = JSON.parse(nVal);
this.tabs.forEach((tab) => {
tab.number = parseInt(tab.number, 10).toLocaleString();
});
this.updateView();
}
}
clearSelections() {
this.tabs.forEach((tab) => {
tab.selected = false;
});
}
connectedCallback() {
this.updateView();
}
currentlySelected() {
return this.tabs.find((tab) => tab.selected);
}
disconnectedCallback() {
}
tabSelected(evn) {
}
updateView() {
hyper(this.shadowRoot)`
<style>${css}</style>
<div id="tab-container">
${this.tabs.map(tab => `
<div class="${tab.selected ? 'selected' : ''}" id="${tab.id}" onclick="${this.selectedTab}">
<div class="name">${tab.name}</div>
<div class="number">${tab.number}</div>
</div>
`)}
</div>
`;
}
static get observedAttributes() {
return ['tabs'];
}
}
customElements.define('idx-admin-tab', IdxAdminTab);
export { IdxAdminTab };
我想在重复选项卡中添加点击处理程序并将 tabSelected 注册为处理程序。我添加的点击处理程序抛出未捕获的语法错误:
(function(event){[object HTMLElement]
})
您的地图 returns 纯字符串,因此您的点击处理程序不指向函数,而是指向函数的字符串表示形式。
${this.tabs.map(tab => `
<div class="${tab.selected ? 'selected' : ''}" id="${tab.id}" onclick="${this.selectedTab}">
<div class="name">${tab.name}</div>
<div class="number">${tab.number}</div>
</div>
`)}
使用
hyperHTML.wire(tab)`<div>...</div>`
相反。 CodePen
您的代码有两个小问题:
- 您 return 只是一个字符串,如前所述
- 您没有绑定您的处理程序
当您使用模板文字时,很容易忘记它们只是字符串。
您需要 return DOM 应始终指向同一选项卡的节点(或连线)。
我假设 tab.id
是唯一的,并且我将它们用作绑定到组件本身的标识符。
这是一个更好的版本:
class IdxAdminTab extends HTMLElement {
constructor() {
super();
this.selectedTab = this.selectedTab.bind(this);
this.render = hyper(this.attachShadow({mode: 'open'}));
this.updateView();
}
selectedTab(e) {
console.log('tab selected');
}
updateView() {
this.render`
<style>${css}</style>
<div id="tab-container">
${this.tabs.map(tab => hyper(this, `:${tab.id}`)`
<div class="${tab.selected ? 'selected' : ''}" id="${tab.id}" onclick="${this.selectedTab}">
<div class="name">${tab.name}</div>
<div class="number">${tab.number}</div>
</div>
`)}
</div>`;
}
}
如您所见,您甚至可以在将 shadowRoot 分配一次作为渲染时使用 {mode: 'closed'}
属性。
现在你有了一个完全可用的组件。
但是,hyperHTML 附带了一个名为 HyperHTMLElement 的自定义元素助手,看看它的实用程序,也许它会让您的生活更轻松。
我是 hyperHTML 的新手,正在试用它。这是我的问题。如何为重复的模板元素添加事件处理程序。这是我的网络组件:
import css from './component.css';
import isJson from '../utils/isJson.js';
const hyper = hyperHTML;
class IdxAdminTab extends HTMLElement {
constructor() {
super();
this.attachShadow({mode: 'open'});
}
attributeChangedCallback(name, oVal, nVal) {
if (name === 'tabs' && isJson(nVal)) {
this.tabs = JSON.parse(nVal);
this.tabs.forEach((tab) => {
tab.number = parseInt(tab.number, 10).toLocaleString();
});
this.updateView();
}
}
clearSelections() {
this.tabs.forEach((tab) => {
tab.selected = false;
});
}
connectedCallback() {
this.updateView();
}
currentlySelected() {
return this.tabs.find((tab) => tab.selected);
}
disconnectedCallback() {
}
tabSelected(evn) {
}
updateView() {
hyper(this.shadowRoot)`
<style>${css}</style>
<div id="tab-container">
${this.tabs.map(tab => `
<div class="${tab.selected ? 'selected' : ''}" id="${tab.id}" onclick="${this.selectedTab}">
<div class="name">${tab.name}</div>
<div class="number">${tab.number}</div>
</div>
`)}
</div>
`;
}
static get observedAttributes() {
return ['tabs'];
}
}
customElements.define('idx-admin-tab', IdxAdminTab);
export { IdxAdminTab };
我想在重复选项卡中添加点击处理程序并将 tabSelected 注册为处理程序。我添加的点击处理程序抛出未捕获的语法错误:
(function(event){[object HTMLElement]
})
您的地图 returns 纯字符串,因此您的点击处理程序不指向函数,而是指向函数的字符串表示形式。
${this.tabs.map(tab => `
<div class="${tab.selected ? 'selected' : ''}" id="${tab.id}" onclick="${this.selectedTab}">
<div class="name">${tab.name}</div>
<div class="number">${tab.number}</div>
</div>
`)}
使用
hyperHTML.wire(tab)`<div>...</div>`
相反。 CodePen
您的代码有两个小问题:
- 您 return 只是一个字符串,如前所述
- 您没有绑定您的处理程序
当您使用模板文字时,很容易忘记它们只是字符串。 您需要 return DOM 应始终指向同一选项卡的节点(或连线)。
我假设 tab.id
是唯一的,并且我将它们用作绑定到组件本身的标识符。
这是一个更好的版本:
class IdxAdminTab extends HTMLElement {
constructor() {
super();
this.selectedTab = this.selectedTab.bind(this);
this.render = hyper(this.attachShadow({mode: 'open'}));
this.updateView();
}
selectedTab(e) {
console.log('tab selected');
}
updateView() {
this.render`
<style>${css}</style>
<div id="tab-container">
${this.tabs.map(tab => hyper(this, `:${tab.id}`)`
<div class="${tab.selected ? 'selected' : ''}" id="${tab.id}" onclick="${this.selectedTab}">
<div class="name">${tab.name}</div>
<div class="number">${tab.number}</div>
</div>
`)}
</div>`;
}
}
如您所见,您甚至可以在将 shadowRoot 分配一次作为渲染时使用 {mode: 'closed'}
属性。
现在你有了一个完全可用的组件。
但是,hyperHTML 附带了一个名为 HyperHTMLElement 的自定义元素助手,看看它的实用程序,也许它会让您的生活更轻松。