将焦点设置在新添加的输入元素上后触发模糊

问题描述 投票:0回答:1

五年前,有人问了一个像我今天要问的问题,但显然没有发布可以解决问题的答案。现在我遇到了同样的问题。到目前为止,这是我所做的。 #cellHandlers = { lvCell: null, outerDiv: null, td: null, span: null, input: null, commitChanges: undefined, beginEdit: (td, cell) => { this.#cellHandlers.lvCell = cell; this.#cellHandlers.td = td; this.#cellHandlers.outerDiv = td.firstChild; this.#cellHandlers.span = td.querySelector('span'); if (this.#cellHandlers.input == null) { this.#cellHandlers.input = document.createElement('input'); this.#cellHandlers.input.type = 'text'; //this.#cellHandlers.input.setAttribute('autofocus', 'true'); } this.#cellHandlers.outerDiv.remove(); this.#cellHandlers.td.appendChild(this.#cellHandlers.input); this.#cellHandlers.td.focus(); this.#cellHandlers.input.select(); // using setTimeout is a work around. The original code was //this.#cellHandlers.hookEvents(true); //this.#cellHandlers.input.focus(); window.setTimeout(() => { this.#cellHandlers.hookEvents(true); this.#cellHandlers.input.focus(); }, 10); //this.#cellHandlers.input.focus(); }, filterKey: e => { e.stopPropagation(); const result = typeof this.#cellKeyFilter == 'function' && this.#cellKeyFilter({ cell: this.#cellHandlers.cell, key: e.key || e.data, value: this.#cellHandlers.input.value, pos: this.#cellHandlers.input.selectionStart }); if (result) return true; e.preventDefault(); return false; }, hookEvents: a => { for (let h in this.#cellHandlers) { if (h[0] != '_') continue; if (a) this.#cellHandlers.input.addEventListener(h.substr(1), this.#cellHandlers[h]) else this.#cellHandlers.input.removeEventListener(h.substr(1), this.#cellHandlers[h]) } }, endEdit: e => { if (e !== undefined) { e.stopPropagation(); } if (this.#cellHandlers.outerDiv) { this.#cellHandlers.hookEvents(false); } if (this.#cellHandlers.commitChanges) { this.#cellHandlers.commitChanges = false; if (this.#cellHandlers.span.textContent != this.#cellHandlers.input.value) { this.#cellHandlers.span.textContent = this.#cellHandlers.input.value; this.dispatchEvent(ListView.#evCellValueChanged); } } try { this.#cellHandlers.input.remove(); } catch { } this.#cellHandlers.td.appendChild(this.#cellHandlers.outerDiv); this.#cellHandlers.outerDiv = null; this.focus(); }, _blur: e => { this.#cellHandlers.endEdit(e); }, _input: e => { return this.#cellHandlers.filterKey(e); }, _keydown: e => { e.stopPropagation(); switch (e.key) { case 'Escape': this.#cellHandlers.commitChanges = false; this.#cellHandlers.endEdit(); break; case 'Tab': case 'Enter': this.#cellHandlers.input.removeEventListener('blur', this.#cellHandlers._blur); if (e.key == 'Tab') { let index = this.#cellHandlers.lvCell.columnIndex + 1; const cells = this.#cellHandlers.td.parentElement.cells; if (index == cells.length) index = 0; this.#setActiveCell(cells[index]); } this.#cellHandlers.commitChanges = true; this.#cellHandlers.endEdit(); break; } } }

#cellHandlers 是 HTMLElement 子类的类的属性。它作用/模仿 c# 的 DataGridView 的一些功能。当单击此类中的单元格并且该单元格的 editable 属性为 true 时,将调用 #cellHandlers.beginEdit,在输入元素尚未创建并添加到单元格时创建输入元素。该单元格是存储在#cellHandlers.td 中的表格单元格(td)。连接事件并将焦点设置在输入上后,blur 事件立即触发,并且该事件的处理程序调用 #cellHandlers.endEdit,这显然会结束单元格的编辑状态。为什么会出现这种行为以及如何防止它?

顺便说一句,我希望没有人建议类似 jQuery 的解决方案,尽管它可能是最后的手段。

javascript input
1个回答
0
投票

创建输入元素并将其添加到父元素后,我这样做了:

window.setTimeout(()=>input.focus(), 1);

请注意,autofocus 属性仅在新创建输入元素时起作用,而不是在将其保存为变量中的节点时起作用。所以这个工作对我来说是必要的。

当您删除元素并希望将焦点返回到其父元素时,也是如此。我用了同样的逻辑。

大多数时间尝试和错误都是有效的(在把你搞砸了太多之后)。

© www.soinside.com 2019 - 2024. All rights reserved.